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.cms.content; 017 018import java.util.ArrayList; 019import java.util.Iterator; 020import java.util.List; 021 022import javax.jcr.RepositoryException; 023 024import org.apache.avalon.framework.component.Component; 025import org.apache.avalon.framework.service.ServiceException; 026import org.apache.avalon.framework.service.ServiceManager; 027import org.apache.avalon.framework.service.Serviceable; 028import org.apache.avalon.framework.thread.ThreadSafe; 029import org.apache.cocoon.xml.AttributesImpl; 030import org.apache.cocoon.xml.XMLUtils; 031import org.apache.commons.lang.StringUtils; 032import org.xml.sax.ContentHandler; 033import org.xml.sax.SAXException; 034 035import org.ametys.cms.contenttype.ContentType; 036import org.ametys.cms.contenttype.ContentTypeExtensionPoint; 037import org.ametys.cms.languages.Language; 038import org.ametys.cms.languages.LanguagesManager; 039import org.ametys.cms.repository.Content; 040import org.ametys.cms.repository.WorkflowAwareContent; 041import org.ametys.cms.repository.comment.CommentableContent; 042import org.ametys.core.user.UserIdentity; 043import org.ametys.core.util.DateUtils; 044import org.ametys.core.util.I18nUtils; 045import org.ametys.plugins.core.user.UserHelper; 046import org.ametys.plugins.workflow.support.WorkflowProvider; 047import org.ametys.plugins.workflow.support.WorkflowProvider.AmetysObjectWorkflow; 048import org.ametys.runtime.i18n.I18nizableText; 049 050import com.opensymphony.workflow.loader.StepDescriptor; 051import com.opensymphony.workflow.loader.WorkflowDescriptor; 052import com.opensymphony.workflow.spi.Step; 053 054/** 055 * Component helper for saxing content's properties 056 * 057 */ 058public class SAXContentHelper implements Component, ThreadSafe, Serviceable 059{ 060 /** The avalon ROLE */ 061 public static final String ROLE = SAXContentHelper.class.getName(); 062 063 private UserHelper _userHelper; 064 private WorkflowProvider _workflowProvider; 065 private LanguagesManager _languagesManager; 066 private ContentTypeExtensionPoint _contentTypeExtensionPoint; 067 private I18nUtils _i18nUtils; 068 069 public void service(ServiceManager smanager) throws ServiceException 070 { 071 _contentTypeExtensionPoint = (ContentTypeExtensionPoint) smanager.lookup(ContentTypeExtensionPoint.ROLE); 072 _languagesManager = (LanguagesManager) smanager.lookup(LanguagesManager.ROLE); 073 _workflowProvider = (WorkflowProvider) smanager.lookup(WorkflowProvider.ROLE); 074 _userHelper = (UserHelper) smanager.lookup(UserHelper.ROLE); 075 _i18nUtils = (I18nUtils) smanager.lookup(I18nUtils.ROLE); 076 } 077 078 /** 079 * SAX the content's content types 080 * @param contentHandler The content handler where to sax 081 * @param content the content The content concerned 082 * @throws SAXException if an error occurred while saxing 083 */ 084 public void saxContentTypes (ContentHandler contentHandler, Content content) throws SAXException 085 { 086 List<String> labels = new ArrayList<>(); 087 088 for (String cTypeId : content.getTypes()) 089 { 090 ContentType cType = _contentTypeExtensionPoint.getExtension(cTypeId); 091 labels.add(_i18nUtils.translate(cType.getLabel(), content.getLanguage())); 092 } 093 XMLUtils.createElement(contentHandler, "contentType", StringUtils.join(labels, ", ")); 094 } 095 096 /** 097 * SAX the content's mixins 098 * @param contentHandler The content handler where to sax 099 * @param content the content The content concerned 100 * @throws SAXException if an error occurred while saxing 101 */ 102 public void saxMixinTypes (ContentHandler contentHandler, Content content) throws SAXException 103 { 104 List<String> labels = new ArrayList<>(); 105 106 for (String cTypeId : content.getMixinTypes()) 107 { 108 ContentType cType = _contentTypeExtensionPoint.getExtension(cTypeId); 109 labels.add(_i18nUtils.translate(cType.getLabel(), content.getLanguage())); 110 } 111 XMLUtils.createElement(contentHandler, "mixin", StringUtils.join(labels, ", ")); 112 } 113 114 /** 115 * SAX the content's mixins and content types 116 * @param contentHandler The content handler where to sax 117 * @param content the content The content concerned 118 * @throws SAXException if an error occurred while saxing 119 */ 120 public void saxContentTypesAndMixins (ContentHandler contentHandler, Content content) throws SAXException 121 { 122 List<String> labels = new ArrayList<>(); 123 124 for (String cTypeId : content.getTypes()) 125 { 126 ContentType cType = _contentTypeExtensionPoint.getExtension(cTypeId); 127 labels.add(_i18nUtils.translate(cType.getLabel(), content.getLanguage())); 128 } 129 130 for (String cTypeId : content.getMixinTypes()) 131 { 132 ContentType cType = _contentTypeExtensionPoint.getExtension(cTypeId); 133 labels.add(_i18nUtils.translate(cType.getLabel(), content.getLanguage())); 134 } 135 136 XMLUtils.createElement(contentHandler, "contentTypeOrMixin", StringUtils.join(labels, ", ")); 137 } 138 139 /** 140 * SAX the creator 141 * @param contentHandler The content handler where to sax 142 * @param content the content The content concerned 143 * @throws SAXException if an error occurred while saxing 144 */ 145 public void saxCreator (ContentHandler contentHandler, Content content) throws SAXException 146 { 147 UserIdentity user = content.getCreator(); 148 XMLUtils.createElement(contentHandler, "creator", user.getLogin()); 149 150 String fullName = _userHelper.getUserFullName(user); 151 if (fullName != null) 152 { 153 XMLUtils.createElement(contentHandler, "creatorDisplay", fullName); 154 } 155 } 156 157 /** 158 * SAX the contributor 159 * @param contentHandler The content handler where to sax 160 * @param content the content The content concerned 161 * @throws SAXException if an error occurred while saxing 162 */ 163 public void saxContributor (ContentHandler contentHandler, Content content) throws SAXException 164 { 165 UserIdentity user = content.getLastContributor(); 166 XMLUtils.createElement(contentHandler, "contributor", user.getLogin()); 167 168 String fullName = _userHelper.getUserFullName(user); 169 if (fullName != null) 170 { 171 XMLUtils.createElement(contentHandler, "contributorDisplay", fullName); 172 } 173 } 174 175 /** 176 * SAX the last modified date 177 * @param contentHandler The content handler where to sax 178 * @param content the content The content concerned 179 * @throws SAXException if an error occurred while saxing 180 */ 181 public void saxLastModified (ContentHandler contentHandler, Content content) throws SAXException 182 { 183 XMLUtils.createElement(contentHandler, "lastModified", DateUtils.zonedDateTimeToString(content.getLastModified())); 184 } 185 186 /** 187 * SAX the date of creation 188 * @param contentHandler The content handler where to sax 189 * @param content the content The content concerned 190 * @throws SAXException if an error occurred while saxing 191 */ 192 public void saxCreationDate (ContentHandler contentHandler, Content content) throws SAXException 193 { 194 XMLUtils.createElement(contentHandler, "creationDate", DateUtils.zonedDateTimeToString(content.getCreationDate())); 195 } 196 197 /** 198 * SAX the content's comments 199 * @param contentHandler The content handler where to sax 200 * @param content the content The content concerned 201 * @throws SAXException if an error occurred while saxing 202 */ 203 public void saxComments (ContentHandler contentHandler, Content content) throws SAXException 204 { 205 if (content instanceof CommentableContent) 206 { 207 boolean hasComment = ((CommentableContent) content).getComments(true, true).size() != 0; 208 XMLUtils.createElement(contentHandler, "comments", String.valueOf(hasComment)); 209 } 210 } 211 212 /** 213 * SAX the content language 214 * @param contentHandler The content handler where to sax 215 * @param content the content The content concerned 216 * @throws SAXException if an error occurred while saxing 217 */ 218 public void saxContentLanguage (ContentHandler contentHandler, Content content) throws SAXException 219 { 220 String contentLanguage = content.getLanguage(); 221 if (contentLanguage != null) 222 { 223 Language language = _languagesManager.getAvailableLanguages().get(contentLanguage); 224 if (language != null) 225 { 226 XMLUtils.createElement(contentHandler, "contentLanguageIcon", language.getSmallIcon()); 227 } 228 229 XMLUtils.createElement(contentHandler, "contentLanguage", contentLanguage); 230 } 231 } 232 233 /** 234 * SAX workflow current step of a {@link Content} 235 * @param contentHandler The content handler where to sax 236 * @param content the content The content concerned 237 * @throws SAXException if an error occurs while SAXing 238 * @throws RepositoryException if an error occurs while retrieving current step 239 */ 240 public void saxContentCurrentState(ContentHandler contentHandler, Content content) throws SAXException, RepositoryException 241 { 242 if (content instanceof WorkflowAwareContent) 243 { 244 WorkflowAwareContent waContent = (WorkflowAwareContent) content; 245 int currentStepId = 0; 246 247 AmetysObjectWorkflow workflow = _workflowProvider.getAmetysObjectWorkflow(waContent); 248 long workflowId = waContent.getWorkflowId(); 249 250 Iterator iterator = workflow.getCurrentSteps(workflowId).iterator(); 251 252 while (iterator.hasNext()) 253 { 254 Step step = (Step) iterator.next(); 255 currentStepId = step.getStepId(); 256 } 257 258 String workflowName = workflow.getWorkflowName(workflowId); 259 WorkflowDescriptor workflowDescriptor = workflow.getWorkflowDescriptor(workflowName); 260 StepDescriptor stepDescriptor = workflowDescriptor.getStep(currentStepId); 261 262 if (stepDescriptor != null) 263 { 264 I18nizableText workflowStepName = new I18nizableText("application", stepDescriptor.getName()); 265 266 AttributesImpl attr = new AttributesImpl(); 267 attr.addAttribute("", "id", "id", "CDATA", String.valueOf(currentStepId)); 268 269 XMLUtils.startElement(contentHandler, "workflowStep", attr); 270 workflowStepName.toSAX(contentHandler); 271 XMLUtils.endElement(contentHandler, "workflowStep"); 272 273 String[] icons = new String[]{"-small", "-medium", "-large"}; 274 for (String icon : icons) 275 { 276 if ("application".equals(workflowStepName.getCatalogue())) 277 { 278 XMLUtils.createElement(contentHandler, "workflow-icon" + icon, "/plugins/cms/resources_workflow/" + workflowStepName.getKey() + icon + ".png"); 279 } 280 else 281 { 282 String pluginName = workflowStepName.getCatalogue().substring("plugin.".length()); 283 XMLUtils.createElement(contentHandler, "workflow-icon" + icon, "/plugins/" + pluginName + "/resources/img/workflow/" + workflowStepName.getKey() + icon + ".png"); 284 } 285 } 286 } 287 } 288 } 289}