001/* 002 * Copyright 2012 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.odf.workflow; 017 018import java.util.Arrays; 019import java.util.Date; 020import java.util.HashMap; 021import java.util.Map; 022 023import javax.jcr.RepositoryException; 024 025import org.apache.avalon.framework.service.ServiceException; 026import org.apache.avalon.framework.service.ServiceManager; 027 028import org.ametys.cms.ObservationConstants; 029import org.ametys.cms.repository.Content; 030import org.ametys.cms.repository.ModifiableWorkflowAwareContent; 031import org.ametys.cms.repository.WorkflowAwareContent; 032import org.ametys.cms.workflow.AbstractContentFunction; 033import org.ametys.cms.workflow.ContentWorkflowHelper; 034import org.ametys.core.observation.Event; 035import org.ametys.odf.ODFHelper; 036import org.ametys.plugins.repository.AmetysObjectResolver; 037import org.ametys.plugins.repository.AmetysRepositoryException; 038import org.ametys.plugins.repository.version.VersionableAmetysObject; 039 040import com.opensymphony.module.propertyset.PropertySet; 041import com.opensymphony.workflow.WorkflowException; 042 043/** 044 * OSWorkflow function for validating a ODF content. 045 * If argument "recursively" is used, the referenced contents will be validated too. 046 */ 047public class ValidateODFContentFunction extends AbstractContentFunction 048{ 049 /** Label for the validated version of contents. */ 050 public static final String VALID_LABEL = "Live"; 051 052 /** The action id of global validation */ 053 public static final int VALIDATE_ACTION_ID = 4; 054 055 /** The validate step id */ 056 public static final int VALIDATED_STEP_ID = 3; 057 058 /** The Ametys object resolver */ 059 protected AmetysObjectResolver _resolver; 060 /** The workflow helper for contents */ 061 protected ContentWorkflowHelper _contentWorkflowHelper; 062 /** The ODF helper */ 063 protected ODFHelper _odfHelper; 064 /** The ODF workflow helper */ 065 protected ODFWorkflowHelper _odfWorkflowHelper; 066 067 @Override 068 public void service(ServiceManager smanager) throws ServiceException 069 { 070 super.service(smanager); 071 _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE); 072 _odfHelper = (ODFHelper) smanager.lookup(ODFHelper.ROLE); 073 _odfWorkflowHelper = (ODFWorkflowHelper) smanager.lookup(ODFWorkflowHelper.ROLE); 074 _contentWorkflowHelper = (ContentWorkflowHelper) smanager.lookup(ContentWorkflowHelper.ROLE); 075 } 076 077 @Override 078 public void execute(Map transientVars, Map args, PropertySet ps) throws WorkflowException 079 { 080 _logger.info("Performing content validation"); 081 082 WorkflowAwareContent content = getContent(transientVars); 083 084 if (!(content instanceof ModifiableWorkflowAwareContent)) 085 { 086 throw new IllegalArgumentException("The provided content " + content.getId() + " is not a ModifiableWorkflowAwareContent."); 087 } 088 089 ModifiableWorkflowAwareContent modifiableContent = (ModifiableWorkflowAwareContent) content; 090 091 try 092 { 093 _validateContent(modifiableContent); 094 095 // Set the current step ID. 096 _setCurrentStepIdAndNotify(modifiableContent, transientVars); 097 // Create a new version. 098 _createVersion(modifiableContent); 099 // Add the valid label on the newly created version. 100 _addLabel(modifiableContent, VALID_LABEL); 101 } 102 catch (RepositoryException e) 103 { 104 throw new WorkflowException("Unable to link the workflow to the content", e); 105 } 106 catch (AmetysRepositoryException e) 107 { 108 throw new WorkflowException("Unable to validate the content", e); 109 } 110 111 _notifyObservers(transientVars, content); 112 } 113 114 /** 115 * Notify observers of content validation 116 * @param transientVars The transient variables 117 * @param content The created content 118 * @throws AmetysRepositoryException If an error occurred with the repository 119 * @throws WorkflowException If an error occurred with the workflow 120 */ 121 protected void _notifyObservers (Map transientVars, Content content) throws AmetysRepositoryException, WorkflowException 122 { 123 Map<String, Object> eventParams = new HashMap<>(); 124 eventParams.put(ObservationConstants.ARGS_CONTENT, content); 125 eventParams.put(ObservationConstants.ARGS_CONTENT_ID, content.getId()); 126 _observationManager.notify(new Event(ObservationConstants.EVENT_CONTENT_VALIDATED, getUser(transientVars), eventParams)); 127 } 128 129 /** 130 * Validates the content. 131 * @param content the content. 132 * @throws WorkflowException if an error occurs. 133 * @throws RepositoryException if an error occurs. 134 */ 135 protected void _validateContent(ModifiableWorkflowAwareContent content) throws WorkflowException, RepositoryException 136 { 137 if (!(content instanceof VersionableAmetysObject)) 138 { 139 throw new WorkflowException("Invalid content implementation: " + content); 140 } 141 142 Date validationDate = new Date(); 143 boolean isValid = Arrays.asList(((VersionableAmetysObject) content).getAllLabels()).contains(VALID_LABEL); 144 if (!isValid) 145 { 146 content.setLastMajorValidationDate(validationDate); 147 } 148 149 content.setLastValidationDate(validationDate); 150 if (content.getFirstValidationDate() == null) 151 { 152 content.setFirstValidationDate(validationDate); 153 } 154 155 // Remove the proposal date. 156 content.setProposalDate(null); 157 158 content.saveChanges(); 159 } 160}