001/* 002 * Copyright 2016 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.plugins.contentio.synchronize.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.ametys.cms.ObservationConstants; 026import org.ametys.cms.repository.Content; 027import org.ametys.cms.repository.ModifiableWorkflowAwareContent; 028import org.ametys.cms.repository.WorkflowAwareContent; 029import org.ametys.cms.workflow.AbstractContentFunction; 030import org.ametys.core.observation.Event; 031import org.ametys.plugins.repository.AmetysRepositoryException; 032import org.ametys.plugins.repository.version.VersionableAmetysObject; 033 034import com.opensymphony.module.propertyset.PropertySet; 035import com.opensymphony.workflow.WorkflowException; 036 037/** 038 * OSWorkflow function for validating a synchronizable content. 039 */ 040public class ValidateSynchronizedContentFunction extends AbstractContentFunction 041{ 042 /** Label for the validated version of contents. */ 043 public static final String VALID_LABEL = "Live"; 044 045 /** Transvient variable for validating content silently. */ 046 public static final String SILENTLY = ValidateSynchronizedContentFunction.class.getName() + "$silently"; 047 048 @Override 049 public void execute(Map transientVars, Map args, PropertySet ps) throws WorkflowException 050 { 051 _logger.info("Performing content validation"); 052 053 WorkflowAwareContent content = getContent(transientVars); 054 055 if (!(content instanceof ModifiableWorkflowAwareContent)) 056 { 057 throw new IllegalArgumentException("The provided content " + content.getId() + " is not a ModifiableWorkflowAwareContent."); 058 } 059 060 ModifiableWorkflowAwareContent modifiableContent = (ModifiableWorkflowAwareContent) content; 061 062 try 063 { 064 // Set the validation metadata. 065 _validateContent(modifiableContent); 066 067 if (transientVars.get(SILENTLY) != null) 068 { 069 // Set the current step ID. 070 _setCurrentStepIdAndNotify(modifiableContent, transientVars); 071 } 072 else 073 { 074 // Set the current step ID. 075 _setCurrentStepId(modifiableContent, transientVars); 076 } 077 078 // Add the live label on the newly created version. 079 _addLabel(modifiableContent, VALID_LABEL); 080 } 081 catch (RepositoryException e) 082 { 083 throw new WorkflowException("Unable to link the workflow to the content", e); 084 } 085 catch (AmetysRepositoryException e) 086 { 087 throw new WorkflowException("Unable to validate the content", e); 088 } 089 090 _notifyObservers(transientVars, modifiableContent); 091 } 092 093 /** 094 * Notify observers of content validation 095 * @param transientVars The transient variables 096 * @param content The created content 097 * @throws AmetysRepositoryException If an error occurred with the repository 098 * @throws WorkflowException If an error occurred with the workflow 099 */ 100 protected void _notifyObservers (Map transientVars, Content content) throws AmetysRepositoryException, WorkflowException 101 { 102 Map<String, Object> eventParams = new HashMap<>(); 103 eventParams.put(ObservationConstants.ARGS_CONTENT, content); 104 eventParams.put(ObservationConstants.ARGS_CONTENT_ID, content.getId()); 105 _observationManager.notify(new Event(ObservationConstants.EVENT_CONTENT_VALIDATED, getUser(transientVars), eventParams)); 106 } 107 108 /** 109 * Validates the content: set the validation metadata. 110 * @param content the content. 111 * @throws WorkflowException if an error occurs. 112 * @throws RepositoryException if an error occurs. 113 */ 114 protected void _validateContent(ModifiableWorkflowAwareContent content) throws WorkflowException, RepositoryException 115 { 116 if (!(content instanceof VersionableAmetysObject)) 117 { 118 throw new WorkflowException("Invalid content implementation: " + content); 119 } 120 121 Date validationDate = new Date(); 122 boolean isValid = Arrays.asList(((VersionableAmetysObject) content).getAllLabels()).contains(VALID_LABEL); 123 if (!isValid) 124 { 125 content.setLastMajorValidationDate(validationDate); 126 } 127 128 content.setLastValidationDate(validationDate); 129 if (content.getFirstValidationDate() == null) 130 { 131 content.setFirstValidationDate(validationDate); 132 } 133 134 // Remove the proposal date. 135 content.setProposalDate(null); 136 137 content.saveChanges(); 138 } 139}