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.io.IOException; 019import java.util.ArrayList; 020import java.util.List; 021import java.util.Map; 022import java.util.Set; 023 024import org.apache.avalon.framework.service.ServiceException; 025import org.apache.avalon.framework.service.ServiceManager; 026import org.apache.cocoon.ProcessingException; 027import org.apache.cocoon.environment.ObjectModelHelper; 028import org.apache.cocoon.generation.ServiceableGenerator; 029import org.apache.cocoon.xml.AttributesImpl; 030import org.apache.cocoon.xml.XMLUtils; 031import org.apache.commons.lang.ArrayUtils; 032import org.apache.commons.lang.StringUtils; 033import org.xml.sax.SAXException; 034 035import org.ametys.cms.lock.LockContentManager; 036import org.ametys.cms.repository.Content; 037import org.ametys.cms.repository.ModifiableContent; 038import org.ametys.cms.repository.WorkflowAwareContent; 039import org.ametys.cms.workflow.ContentWorkflowHelper; 040import org.ametys.core.right.RightManager; 041import org.ametys.core.user.CurrentUserProvider; 042import org.ametys.core.user.UserIdentity; 043import org.ametys.core.util.DateUtils; 044import org.ametys.plugins.repository.AmetysObjectResolver; 045import org.ametys.plugins.repository.UnknownAmetysObjectException; 046import org.ametys.plugins.repository.lock.LockAwareAmetysObject; 047import org.ametys.plugins.workflow.support.WorkflowProvider; 048import org.ametys.plugins.workflow.support.WorkflowProvider.AmetysObjectWorkflow; 049 050import com.opensymphony.workflow.spi.Step; 051 052/** 053 * SAX the contents information 054 */ 055public class ContentInformationGenerator extends ServiceableGenerator 056{ 057 /** Ametys object resovler. */ 058 protected AmetysObjectResolver _resolver; 059 /** The rights manager */ 060 protected RightManager _rightManager; 061 /** The user provider */ 062 protected CurrentUserProvider _userProvider; 063 /** The workflow provider */ 064 protected WorkflowProvider _workflowProvider; 065 /** The lock manager. */ 066 protected LockContentManager _lockManager; 067 /** The content workflow helper */ 068 protected ContentWorkflowHelper _contentWorkflowHelper; 069 /** The content helper */ 070 protected ContentHelper _contentHelper; 071 072 @Override 073 public void service(ServiceManager serviceManager) throws ServiceException 074 { 075 super.service(serviceManager); 076 _resolver = (AmetysObjectResolver) serviceManager.lookup(AmetysObjectResolver.ROLE); 077 _userProvider = (CurrentUserProvider) serviceManager.lookup(CurrentUserProvider.ROLE); 078 _rightManager = (RightManager) serviceManager.lookup(RightManager.ROLE); 079 _workflowProvider = (WorkflowProvider) serviceManager.lookup(WorkflowProvider.ROLE); 080 _lockManager = (LockContentManager) serviceManager.lookup(LockContentManager.ROLE); 081 _contentWorkflowHelper = (ContentWorkflowHelper) serviceManager.lookup(ContentWorkflowHelper.ROLE); 082 _contentHelper = (ContentHelper) serviceManager.lookup(ContentHelper.ROLE); 083 } 084 085 @SuppressWarnings("unchecked") 086 @Override 087 public void generate() throws IOException, SAXException, ProcessingException 088 { 089 Map<String, Object> jsParameters = (Map<String, Object>) objectModel.get(ObjectModelHelper.PARENT_CONTEXT); 090 List<String> ids = null; 091 Object idParam = jsParameters.get("id"); 092 if (idParam instanceof String) 093 { 094 ids = new ArrayList<>(); 095 ids.add((String) idParam); 096 } 097 else 098 { 099 ids = (List<String>) idParam; 100 } 101 102 contentHandler.startDocument(); 103 XMLUtils.startElement(contentHandler, "contents"); 104 105 for (String contentID : ids) 106 { 107 AttributesImpl attrs = new AttributesImpl(); 108 109 try 110 { 111 Content content = _resolver.resolveById(contentID); 112 113 attrs.addCDATAAttribute("id", content.getId()); 114 attrs.addCDATAAttribute("title", _contentHelper.getTitle(content)); 115 attrs.addCDATAAttribute("name", content.getName()); 116 attrs.addCDATAAttribute("path", content.getPath()); 117 attrs.addCDATAAttribute("type", StringUtils.join(content.getTypes(), ',')); 118 if (content.getLanguage() != null) 119 { 120 attrs.addCDATAAttribute("lang", content.getLanguage()); 121 } 122 attrs.addCDATAAttribute("creator", content.getCreator().getLogin()); 123 attrs.addCDATAAttribute("lastContributor", content.getLastContributor().getLogin()); 124 attrs.addCDATAAttribute("creationDate", DateUtils.zonedDateTimeToString(content.getCreationDate())); 125 attrs.addCDATAAttribute("lastModified", DateUtils.zonedDateTimeToString(content.getLastModified())); 126 127 if (content instanceof WorkflowAwareContent) 128 { 129 WorkflowAwareContent waContent = (WorkflowAwareContent) content; 130 AmetysObjectWorkflow workflow = _workflowProvider.getAmetysObjectWorkflow(waContent); 131 132 attrs.addCDATAAttribute("workflowName", workflow.getWorkflowName(waContent.getWorkflowId())); 133 attrs.addCDATAAttribute("workflowStep", this.__joinSteps(workflow.getCurrentSteps(waContent.getWorkflowId()))); 134 135 int[] availableActions = _contentWorkflowHelper.getAvailableActions(waContent); 136 String workflowAvailableAction = StringUtils.join(ArrayUtils.toObject(availableActions), ", "); 137 attrs.addCDATAAttribute("workflowAvailableActions", workflowAvailableAction); 138 } 139 140 if (content instanceof ModifiableContent) 141 { 142 attrs.addCDATAAttribute("isModifiable", "true"); 143 } 144 145 if (content instanceof LockAwareAmetysObject) 146 { 147 LockAwareAmetysObject lockAwareContent = (LockAwareAmetysObject) content; 148 if (lockAwareContent.isLocked()) 149 { 150 attrs.addCDATAAttribute("locked", String.valueOf(lockAwareContent.isLocked())); 151 attrs.addCDATAAttribute("canUnlock", String.valueOf(_lockManager.canUnlock(lockAwareContent))); 152 } 153 } 154 155 saxAdditionalAtttributes (content, attrs); 156 157 XMLUtils.startElement(contentHandler, "content", attrs); 158 159 saxUserRights(content); 160 saxAdditionalInformation(content); 161 XMLUtils.endElement(contentHandler, "content"); 162 } 163 catch (UnknownAmetysObjectException e) 164 { 165 getLogger().warn("Content of id '" + contentID + "' does not exist.", e); 166 167 attrs.addCDATAAttribute("id", contentID); 168 XMLUtils.createElement(contentHandler, "content-not-found", attrs); 169 } 170 171 } 172 173 XMLUtils.endElement(contentHandler, "contents"); 174 contentHandler.endDocument(); 175 } 176 177 private String __joinSteps(List<Step> steps) 178 { 179 StringBuffer a = new StringBuffer(); 180 181 for (Step s : steps) 182 { 183 if (a.length() > 0) 184 { 185 a.append(", "); 186 } 187 a.append(s.getStepId()); 188 } 189 190 return a.toString(); 191 } 192 193 194 /** 195 * SAX the user rights on content 196 * @param content The content to check rights 197 * @throws SAXException if an error occurred while SAXing 198 */ 199 protected void saxUserRights (Content content) throws SAXException 200 { 201 UserIdentity user = _userProvider.getUser(); 202 Set<String> rights = _rightManager.getUserRights(user, content); 203 204 XMLUtils.startElement(contentHandler, "user-rights"); 205 206 for (String rightID : rights) 207 { 208 AttributesImpl rightAttr = new AttributesImpl(); 209 rightAttr.addCDATAAttribute("id", rightID); 210 XMLUtils.createElement(contentHandler, "right", rightAttr); 211 } 212 XMLUtils.endElement(contentHandler, "user-rights"); 213 } 214 215 /** 216 * SAX the additional attributes 217 * @param content The content 218 * @param attrs The attributes 219 * @throws SAXException if an error occurred while SAXing 220 */ 221 protected void saxAdditionalAtttributes (Content content, AttributesImpl attrs) throws SAXException 222 { 223 // Nothing 224 } 225 226 /** 227 * SAX additional information on content 228 * @param content The content 229 * @throws SAXException if an error occurred while SAXing 230 */ 231 protected void saxAdditionalInformation (Content content) throws SAXException 232 { 233 // Nothing 234 } 235}