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.plugins.workflow; 017 018import java.util.HashMap; 019import java.util.List; 020import java.util.Map; 021import java.util.Optional; 022 023import org.apache.avalon.framework.logger.LogEnabled; 024import org.apache.avalon.framework.logger.Logger; 025import org.apache.avalon.framework.service.ServiceException; 026import org.apache.avalon.framework.service.ServiceManager; 027import org.apache.avalon.framework.service.Serviceable; 028 029import org.ametys.core.user.UserIdentity; 030import org.ametys.runtime.i18n.I18nizableText; 031import org.ametys.runtime.parameter.ValidationResult; 032 033import com.opensymphony.workflow.WorkflowContext; 034import com.opensymphony.workflow.WorkflowException; 035 036/** 037 * Abstract class for easily retrieving environment components 038 * in a condition or a function. 039 */ 040public abstract class AbstractWorkflowComponent implements LogEnabled, Serviceable 041{ 042 /** Constant for storing the content into the transient variables map. */ 043 public static final String CONTEXT_PARAMETERS_KEY = AbstractWorkflowComponent.class.getName() + "$Parameters"; 044 045 /** Constant for storing the result map into the transient variables map. */ 046 public static final String RESULT_MAP_KEY = AbstractWorkflowComponent.class.getName() + ";resultMap"; 047 048 /** Constant for storing the content into the transient variables map. */ 049 public static final String FAIL_CONDITIONS_KEY = AbstractWorkflowComponent.class.getName() + "$failConditions"; 050 051 /** Constant for storing the workflow validation in result map. */ 052 public static final String WORKFLOW_VALIDATION_KEY = "workflowValidation"; 053 054 /** Service manager available to subclasses. */ 055 protected ServiceManager _manager; 056 /** Logger available to subclasses. */ 057 protected Logger _logger; 058 059 @Override 060 public void enableLogging(Logger logger) 061 { 062 _logger = logger; 063 } 064 065 @Override 066 public void service(ServiceManager manager) throws ServiceException 067 { 068 _manager = manager; 069 } 070 071 /** 072 * Retrieve the user responsible of the call. 073 * @param transientVars the parameters from the call. 074 * @return the user responsible of the call. 075 * @throws WorkflowException if the user is not present. 076 */ 077 public UserIdentity getUser(Map transientVars) throws WorkflowException 078 { 079 WorkflowContext workflowContext = (WorkflowContext) transientVars.get("context"); 080 081 if (workflowContext == null) 082 { 083 throw new WorkflowException("Unable to get the workflow context"); 084 } 085 086 return UserIdentity.stringToUserIdentity(workflowContext.getCaller()); 087 } 088 089 /** 090 * Retrieve the workflow parameters map, or an empty map if there is no parameters 091 * @param transientVars the parameters from the call. 092 * @return the workflow parameters map 093 */ 094 public Map<String, Object> getContextParameters(Map transientVars) 095 { 096 return Optional.ofNullable(transientVars.get(CONTEXT_PARAMETERS_KEY)) 097 .filter(Map.class::isInstance) 098 .map(Map.class::cast) 099 .orElseGet(() -> new HashMap<>()); 100 } 101 102 /** 103 * Retrieve the list condition failure 104 * @param transientVars the parameters from the call. 105 * @return the list of failed condition 106 */ 107 @SuppressWarnings("unchecked") 108 public List<ConditionFailure> getConditionFailures (Map transientVars) 109 { 110 return (List<ConditionFailure>) transientVars.get(FAIL_CONDITIONS_KEY); 111 } 112 113 /** 114 * Retrieve the map to write return values 115 * @param transientVars the parameters from the call. 116 * @return the map to render. 117 * @throws WorkflowException if the result map is not found. 118 */ 119 @SuppressWarnings("unchecked") 120 public Map<String, Object> getResultsMap(Map transientVars) throws WorkflowException 121 { 122 Map<String, Object> resultMap = (Map<String, Object>) transientVars.get(RESULT_MAP_KEY); 123 124 if (resultMap == null) 125 { 126 throw new WorkflowException("Unable to retrieve result map"); 127 } 128 129 // Found in transient variables map 130 return resultMap; 131 } 132 133 /** 134 * Add a global workflow error such as fail condition 135 * @param transientVars the parameters from the call. 136 * @param errorLabel The error label 137 * @throws WorkflowException if the result map is not found. 138 */ 139 public void addWorkflowError (Map transientVars, I18nizableText errorLabel) throws WorkflowException 140 { 141 Map<String, Object> resultMap = getResultsMap(transientVars); 142 143 ValidationResult validationResult = (ValidationResult) resultMap.computeIfAbsent(WORKFLOW_VALIDATION_KEY, __ -> new ValidationResult()); 144 validationResult.addError(errorLabel); 145 } 146 147 /** 148 * Add a global workflow errors that will be traited as warnings 149 * @param transientVars the parameters from the call. 150 * @param warnLabel The warning label 151 * @throws WorkflowException if the result map is not found. 152 */ 153 public void addWorkflowWarning (Map transientVars, I18nizableText warnLabel) throws WorkflowException 154 { 155 Map<String, Object> resultMap = getResultsMap(transientVars); 156 157 ValidationResult validationResult = (ValidationResult) resultMap.computeIfAbsent(WORKFLOW_VALIDATION_KEY, __ -> new ValidationResult()); 158 validationResult.addWarning(warnLabel); 159 } 160 161 /** 162 * Record representing a condition failure 163 * @param text the failure text 164 * @param type the type of failure 165 */ 166 public record ConditionFailure(String text, String type) { /** */ } 167}