001/* 002 * Copyright 2010 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.web.repository.page.generators; 017 018import java.io.IOException; 019 020import org.apache.avalon.framework.parameters.ParameterException; 021import org.apache.avalon.framework.service.ServiceException; 022import org.apache.avalon.framework.service.ServiceManager; 023import org.apache.cocoon.ProcessingException; 024import org.apache.cocoon.environment.ObjectModelHelper; 025import org.apache.cocoon.environment.Request; 026import org.apache.cocoon.generation.ServiceableGenerator; 027import org.apache.cocoon.xml.AttributesImpl; 028import org.apache.cocoon.xml.XMLUtils; 029import org.apache.commons.lang.StringUtils; 030import org.xml.sax.SAXException; 031 032import org.ametys.core.user.User; 033import org.ametys.core.user.UserIdentity; 034import org.ametys.core.user.UserManager; 035import org.ametys.core.util.DateUtils; 036import org.ametys.core.util.I18nUtils; 037import org.ametys.plugins.explorer.ExplorerNode; 038import org.ametys.plugins.explorer.dublincore.DublinCoreMetadataProvider; 039import org.ametys.plugins.explorer.resources.Resource; 040import org.ametys.plugins.repository.AmetysObject; 041import org.ametys.plugins.repository.AmetysObjectIterable; 042import org.ametys.plugins.repository.AmetysObjectResolver; 043import org.ametys.plugins.repository.TraversableAmetysObject; 044import org.ametys.plugins.repository.jcr.DublinCoreHelper; 045import org.ametys.runtime.i18n.I18nizableText; 046import org.ametys.web.repository.page.Page; 047 048/** 049 * Generates the page attachments.<br> 050 * The generated XML looks like :<br> 051 * <Attachments page="XX"><br> 052 * <Folder><br> 053 * <Folder/><br> 054 * <File/><br> 055 * ...<br> 056 * </Folder><br> 057 * </Attachments> 058 */ 059public class PageAttachmentsGenerator extends ServiceableGenerator 060{ 061 /** The user manager */ 062 protected UserManager _userManager; 063 064 /** The ametys object resolver */ 065 protected AmetysObjectResolver _resolver; 066 /** The DublinCore metadata provider */ 067 private DublinCoreMetadataProvider _dcProvider; 068 069 private int _depth; 070 071 private I18nUtils _i18nUtils; 072 073 @Override 074 public void service(ServiceManager sManager) throws ServiceException 075 { 076 super.service(sManager); 077 _userManager = (UserManager) sManager.lookup(UserManager.ROLE); 078 _resolver = (AmetysObjectResolver) sManager.lookup(AmetysObjectResolver.ROLE); 079 _dcProvider = (DublinCoreMetadataProvider) sManager.lookup(DublinCoreMetadataProvider.ROLE); 080 _i18nUtils = (I18nUtils) sManager.lookup(I18nUtils.ROLE); 081 } 082 083 @Override 084 public void generate() throws IOException, SAXException, ProcessingException 085 { 086 _depth = -1; // Sax all 087 try 088 { 089 _depth = parameters.getParameterAsInteger("depth"); 090 } 091 catch (ParameterException e) 092 { 093 // Nothing 094 } 095 096 Page page = null; 097 TraversableAmetysObject attachments = null; 098 Request request = ObjectModelHelper.getRequest(objectModel); 099 100 String id = request.getParameter("id"); 101 if (!StringUtils.isEmpty(id)) 102 { 103 AmetysObject object = _resolver.resolveById(id); 104 105 if (object instanceof Page) 106 { 107 page = (Page) object; 108 attachments = page.getRootAttachments(); 109 } 110 else 111 { 112 attachments = (TraversableAmetysObject) object; 113 } 114 } 115 else 116 { 117 page = (Page) request.getAttribute(Page.class.getName()); 118 attachments = page.getRootAttachments(); 119 } 120 121 contentHandler.startDocument(); 122 123 AttributesImpl attr = new AttributesImpl(); 124 attr.addAttribute("", "id", "id", "CDATA", attachments.getId()); 125 if (!(attachments.getParent() instanceof Page)) 126 { 127 attr.addAttribute("", "parentId", "parentId", "CDATA", attachments.getParent().getId()); 128 } 129 130 XMLUtils.startElement(contentHandler, "Attachments", attr); 131 132 saxPage (page); 133 134 AmetysObjectIterable<AmetysObject> children = attachments.getChildren(); 135 136 for (AmetysObject child : children) 137 { 138 if (child instanceof ExplorerNode) 139 { 140 saxFolder((ExplorerNode) child, 0); 141 } 142 else if (child instanceof Resource) 143 { 144 saxFile((Resource) child); 145 } 146 } 147 148 XMLUtils.endElement(contentHandler, "Attachments"); 149 contentHandler.endDocument(); 150 } 151 152 /** 153 * SAX the page 154 * @param page the page. Can be null. 155 * @throws SAXException If an error occurred while SAXing 156 */ 157 protected void saxPage (Page page) throws SAXException 158 { 159 if (page != null) 160 { 161 AttributesImpl attr = new AttributesImpl(); 162 attr.addCDATAAttribute("path", page.getPathInSitemap()); 163 attr.addCDATAAttribute("lang", page.getSitemapName()); 164 attr.addCDATAAttribute("site", page.getSiteName()); 165 attr.addCDATAAttribute("title", page.getTitle()); 166 167 XMLUtils.createElement(contentHandler, "page", attr); 168 } 169 } 170 171 /** 172 * SAX a {@link ExplorerNode} 173 * 174 * @param node The node to SAX 175 * @param depth The depth 176 * @throws SAXException If an error occurred while SAXing 177 */ 178 protected void saxFolder(ExplorerNode node, int depth) throws SAXException 179 { 180 if (depth == _depth && _depth != -1) 181 { 182 // Stop saxing, the depth is reached 183 return; 184 } 185 186 AttributesImpl childAtts = new AttributesImpl(); 187 childAtts.addCDATAAttribute("id", node.getId()); 188 childAtts.addCDATAAttribute("name", node.getName()); 189 childAtts.addCDATAAttribute("icon", node.getIconCls()); 190 191 XMLUtils.startElement(contentHandler, "Folder", childAtts); 192 193 AmetysObjectIterable<AmetysObject> children = ((TraversableAmetysObject) node).getChildren(); 194 for (AmetysObject child : children) 195 { 196 if (child instanceof ExplorerNode) 197 { 198 int newDepth = depth != -1 ? (depth + 1) : -1; 199 saxFolder((ExplorerNode) child, newDepth); 200 } 201 else if (child instanceof Resource) 202 { 203 saxFile((Resource) child); 204 } 205 } 206 207 XMLUtils.endElement(contentHandler, "Folder"); 208 } 209 210 /** 211 * Sax a {@link Resource} 212 * 213 * @param resource The node to sax 214 * @throws SAXException If an erreor occurred while saxing 215 */ 216 protected void saxFile(Resource resource) throws SAXException 217 { 218 UserIdentity userIdentity = resource.getCreator(); 219 User user = _userManager.getUser(userIdentity.getPopulationId(), userIdentity.getLogin()); 220 String name = user == null ? userIdentity.getLogin() : user.getFullName(); 221 222 AttributesImpl childAtts = new AttributesImpl(); 223 childAtts.addCDATAAttribute("id", resource.getId()); 224 childAtts.addCDATAAttribute("path", resource.getResourcePath()); 225 childAtts.addCDATAAttribute("name", resource.getName()); 226 childAtts.addCDATAAttribute("mimetype", resource.getMimeType()); 227 childAtts.addCDATAAttribute("lastModified", DateUtils.dateToString(resource.getLastModified())); 228 childAtts.addCDATAAttribute("author", name); 229 childAtts.addCDATAAttribute("keywords", String.valueOf(resource.getKeywordsAsString())); 230 231 getDCAttributes(childAtts, resource); 232 233 XMLUtils.startElement(contentHandler, "File", childAtts); 234 _saxSize(resource.getLength()); 235 _saxIcon(resource.getName()); 236 XMLUtils.endElement(contentHandler, "File"); 237 } 238 239 /** 240 * SAX the DublinCore metadata 241 * @param attrs The attributes 242 * @param resource The resource 243 */ 244 protected void getDCAttributes (AttributesImpl attrs, Resource resource) 245 { 246 Request request = ObjectModelHelper.getRequest(objectModel); 247 Page page = (Page) request.getAttribute(Page.class.getName()); 248 String language = null; 249 if (page != null) 250 { 251 language = page.getSitemapName(); 252 } 253 254 _saxNonEmptyAttributes (attrs, DublinCoreHelper.METADATA_DC_TITLE, resource.getDCTitle(), language); 255 _saxNonEmptyAttributes (attrs, DublinCoreHelper.METADATA_DC_CONTRIBUTOR, resource.getDCContributor(), language); 256 _saxNonEmptyAttributes (attrs, DublinCoreHelper.METADATA_DC_CREATOR, resource.getDCCreator(), language); 257 _saxNonEmptyAttributes (attrs, DublinCoreHelper.METADATA_DC_DESCRIPTION, resource.getDCDescription(), language); 258 _saxNonEmptyAttributes (attrs, DublinCoreHelper.METADATA_DC_SUBJECT, StringUtils.join(resource.getDCSubject(), ", "), language); 259 260 _saxNonEmptyAttributes (attrs, DublinCoreHelper.METADATA_DC_PUBLISHER, resource.getDCPublisher(), language); 261 _saxNonEmptyAttributes (attrs, DublinCoreHelper.METADATA_DC_LANGUAGE, resource.getDCLanguage(), language); 262 _saxNonEmptyAttributes (attrs, DublinCoreHelper.METADATA_DC_COVERAGE, resource.getDCCoverage(), language); 263 _saxNonEmptyAttributes (attrs, DublinCoreHelper.METADATA_DC_RELATION, resource.getDCRelation(), language); 264 _saxNonEmptyAttributes (attrs, DublinCoreHelper.METADATA_DC_RIGHTS, resource.getDCRights(), language); 265 _saxNonEmptyAttributes (attrs, DublinCoreHelper.METADATA_DC_SOURCE, resource.getDCSource(), language); 266 _saxNonEmptyAttributes (attrs, DublinCoreHelper.METADATA_DC_FORMAT, resource.getDCFormat(), language); 267 _saxNonEmptyAttributes (attrs, DublinCoreHelper.METADATA_DC_DATE, DateUtils.dateToString(resource.getDCDate()), language); 268 _saxNonEmptyAttributes (attrs, DublinCoreHelper.METADATA_DC_IDENTIFIER, resource.getDCIdentifier(), language); 269 _saxNonEmptyAttributes (attrs, DublinCoreHelper.METADATA_DC_TYPE, resource.getDCType(), language); 270 } 271 272 private void _saxNonEmptyAttributes (AttributesImpl attrs, String metadataName, String value, String language) 273 { 274 if (StringUtils.isNotEmpty(value)) 275 { 276 if (_dcProvider.isEnumerated(metadataName)) 277 { 278 I18nizableText entry = _dcProvider.getEntry(metadataName, value); 279 attrs.addCDATAAttribute(metadataName, entry != null ? _i18nUtils.translate(entry, language) : value); 280 } 281 else 282 { 283 attrs.addCDATAAttribute(metadataName, value); 284 } 285 } 286 } 287 288 private void _saxIcon(String filename) throws SAXException 289 { 290 int index = filename.indexOf("."); 291 String extension = filename.substring(index + 1); 292 293 XMLUtils.createElement(contentHandler, "icon", "plugins/explorer/icon-medium/" + extension + ".png"); 294 } 295 296 private void _saxSize(long size) throws SAXException 297 { 298 org.ametys.core.util.StringUtils.toReadableDataSize(size).toSAX(contentHandler, "size"); 299 } 300}