001/* 002 * Copyright 2015 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.workflow; 017 018import java.util.ArrayList; 019import java.util.HashMap; 020import java.util.HashSet; 021import java.util.List; 022import java.util.Map; 023import java.util.Set; 024 025import javax.jcr.Node; 026import javax.jcr.RepositoryException; 027import javax.jcr.Session; 028 029import org.apache.avalon.framework.parameters.Parameters; 030import org.apache.avalon.framework.service.ServiceException; 031import org.apache.avalon.framework.service.ServiceManager; 032import org.apache.cocoon.ProcessingException; 033import org.apache.cocoon.environment.ObjectModelHelper; 034import org.apache.cocoon.environment.Redirector; 035import org.apache.cocoon.environment.Request; 036import org.apache.cocoon.environment.SourceResolver; 037 038import org.ametys.cms.content.ContentHelper; 039import org.ametys.cms.repository.Content; 040import org.ametys.cms.repository.WorkflowAwareContent; 041import org.ametys.cms.workflow.history.ElementWithWorkflow; 042import org.ametys.cms.workflow.history.HistoryStep; 043import org.ametys.cms.workflow.history.VersionInformation; 044import org.ametys.cms.workflow.history.WorkflowHistory; 045import org.ametys.cms.workflow.history.WorkflowHistoryHelper; 046import org.ametys.core.cocoon.JSonReader; 047import org.ametys.core.right.RightManager; 048import org.ametys.core.right.RightManager.RightResult; 049import org.ametys.plugins.repository.version.VersionAwareAmetysObject; 050import org.ametys.plugins.workflow.store.AbstractJackrabbitWorkflowStore; 051import org.ametys.plugins.workflow.support.WorkflowProvider; 052import org.ametys.plugins.workflow.support.WorkflowProvider.AmetysObjectWorkflow; 053 054/** 055 * This action returns the workflow history of a content 056 * 057 */ 058public class ContentHistoryAction extends ContentVersionHistoryAction 059{ 060 /** The workflow provider */ 061 protected WorkflowProvider _workflowProvider; 062 063 /** The content helper */ 064 protected ContentHelper _contentHelper; 065 066 /** The workflow history helper */ 067 protected WorkflowHistoryHelper _workflowHistoryHelper; 068 069 /** The right manager */ 070 protected RightManager _rightManager; 071 072 @Override 073 public void service(ServiceManager serviceManager) throws ServiceException 074 { 075 super.service(serviceManager); 076 _workflowProvider = (WorkflowProvider) serviceManager.lookup(WorkflowProvider.ROLE); 077 _contentHelper = (ContentHelper) serviceManager.lookup(ContentHelper.ROLE); 078 _workflowHistoryHelper = (WorkflowHistoryHelper) serviceManager.lookup(WorkflowHistoryHelper.ROLE); 079 _rightManager = (RightManager) serviceManager.lookup(RightManager.ROLE); 080 } 081 082 @Override 083 public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception 084 { 085 Request request = ObjectModelHelper.getRequest(objectModel); 086 087 String id = request.getParameter("contentId"); 088 Content content = _resolver.resolveById(id); 089 090 Map<String, Object> result = new HashMap<>(); 091 if (_rightManager.currentUserHasRight("CMS_Rights_Content_History", content) == RightResult.RIGHT_ALLOW) 092 { 093 List<Map<String, Object>> workflowSteps = new ArrayList<>(); 094 095 Set<String> validatedVersions = new HashSet<>(); 096 097 try 098 { 099 if (content instanceof WorkflowAwareContent && content instanceof VersionAwareAmetysObject) 100 { 101 WorkflowAwareContent workflowAwareContent = (WorkflowAwareContent) content; 102 103 AmetysObjectWorkflow workflow = _workflowProvider.getAmetysObjectWorkflow(workflowAwareContent); 104 long workflowId = workflowAwareContent.getWorkflowId(); 105 int initialActionId = (int) _getInitialActionId(workflow, workflowAwareContent); 106 107 List<VersionInformation> versionsInformation = _resolveVersionInformations((VersionAwareAmetysObject) content); 108 ElementWithWorkflow element = new ElementWithWorkflow( 109 _contentHelper.getTitle(content), 110 workflowAwareContent.getCreationDate(), 111 workflowAwareContent.getCreator(), 112 versionsInformation 113 ); 114 115 WorkflowHistory workflowHistory = _workflowHistoryHelper.getWorkflowHistory(element, workflowId, workflow, initialActionId); 116 for (HistoryStep step : workflowHistory.getSteps()) 117 { 118 workflowSteps.add(_workflowHistoryHelper.historyStep2Json(step)); 119 } 120 validatedVersions = workflowHistory.getValidatedVersions(); 121 } 122 } 123 catch (RepositoryException e) 124 { 125 throw new ProcessingException("Unable to access version history", e); 126 } 127 128 for (Map<String, Object> stepInfo : workflowSteps) 129 { 130 @SuppressWarnings("unchecked") 131 List<Map<String, Object>> versions = (List<Map<String, Object>>) stepInfo.get("versions"); 132 133 for (Map<String, Object> version : versions) 134 { 135 String versionName = (String) version.get("name"); 136 if (validatedVersions.contains(versionName)) 137 { 138 version.put("valid", true); 139 } 140 } 141 } 142 143 result.put("workflow", workflowSteps); 144 } 145 else 146 { 147 result.put("hasRight", false); 148 } 149 request.setAttribute(JSonReader.OBJECT_TO_READ, result); 150 return EMPTY_MAP; 151 } 152 153 private long _getInitialActionId(AmetysObjectWorkflow workflow, WorkflowAwareContent waContent) 154 { 155 try 156 { 157 Session session = waContent.getNode().getSession(); 158 AbstractJackrabbitWorkflowStore workflowStore = (AbstractJackrabbitWorkflowStore) workflow.getConfiguration().getWorkflowStore(); 159 Node workflowEntryNode = workflowStore.getEntryNode(session, waContent.getWorkflowId()); 160 return workflowEntryNode.getProperty("ametys-internal:initialActionId").getLong(); 161 } 162 catch (Exception e) 163 { 164 getLogger().error("Unable to retrieves initial action id for workflow aware content : " + waContent.getId(), e); 165 return 0; 166 } 167 } 168}