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.Errors; 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 errors in result map. */ 052 public static final String WORKFLOW_ERRORS_KEY = "workflowErrors"; 053 054 /** Constant for storing the workflow warnings in result map. */ 055 public static final String WORKFLOW_WARNS_KEY = "workflowWarnings"; 056 057 /** Service manager available to subclasses. */ 058 protected ServiceManager _manager; 059 /** Logger available to subclasses. */ 060 protected Logger _logger; 061 062 @Override 063 public void enableLogging(Logger logger) 064 { 065 _logger = logger; 066 } 067 068 @Override 069 public void service(ServiceManager manager) throws ServiceException 070 { 071 _manager = manager; 072 } 073 074 /** 075 * Retrieve the user responsible of the call. 076 * @param transientVars the parameters from the call. 077 * @return the user responsible of the call. 078 * @throws WorkflowException if the user is not present. 079 */ 080 public UserIdentity getUser(Map transientVars) throws WorkflowException 081 { 082 WorkflowContext workflowContext = (WorkflowContext) transientVars.get("context"); 083 084 if (workflowContext == null) 085 { 086 throw new WorkflowException("Unable to get the workflow context"); 087 } 088 089 return UserIdentity.stringToUserIdentity(workflowContext.getCaller()); 090 } 091 092 /** 093 * Retrieve the workflow parameters map, or an empty map if there is no parameters 094 * @param transientVars the parameters from the call. 095 * @return the workflow parameters map 096 * @throws WorkflowException if the object model or the request is not present. 097 */ 098 public Map<String, Object> getContextParameters(Map transientVars) throws WorkflowException 099 { 100 return Optional.ofNullable(transientVars.get(CONTEXT_PARAMETERS_KEY)) 101 .filter(Map.class::isInstance) 102 .map(Map.class::cast) 103 .orElseGet(() -> new HashMap<>()); 104 } 105 106 /** 107 * Retrieve the list condition failures 108 * @param transientVars the parameters from the call. 109 * @return the list of failed condition 110 * @throws WorkflowException If an error occurred 111 */ 112 @SuppressWarnings("unchecked") 113 public List<String> getConditionFailures (Map transientVars) throws WorkflowException 114 { 115 return (List<String>) transientVars.get(FAIL_CONDITIONS_KEY); 116 } 117 118 /** 119 * Retrieve the map to write return values 120 * @param transientVars the parameters from the call. 121 * @return the map to render. 122 * @throws WorkflowException if the result map is not found. 123 */ 124 @SuppressWarnings("unchecked") 125 public Map<String, Object> getResultsMap(Map transientVars) throws WorkflowException 126 { 127 Map<String, Object> resultMap = (Map<String, Object>) transientVars.get(RESULT_MAP_KEY); 128 129 if (resultMap == null) 130 { 131 throw new WorkflowException("Unable to retrieve result map"); 132 } 133 134 // Found in transient variables map 135 return resultMap; 136 } 137 138 /** 139 * Add a global workflow error such as fail condition 140 * @param transientVars the parameters from the call. 141 * @param errorLabel The error label 142 * @throws WorkflowException if the result map is not found. 143 */ 144 @SuppressWarnings("cast") 145 public void addWorkflowError (Map transientVars, I18nizableText errorLabel) throws WorkflowException 146 { 147 Map<String, Object> resultMap = (Map<String, Object>) getResultsMap(transientVars); 148 if (!resultMap.containsKey(AbstractWorkflowComponent.WORKFLOW_ERRORS_KEY)) 149 { 150 resultMap.put(AbstractWorkflowComponent.WORKFLOW_ERRORS_KEY, new Errors()); 151 } 152 153 Errors errors = (Errors) resultMap.get(AbstractWorkflowComponent.WORKFLOW_ERRORS_KEY); 154 errors.addError(errorLabel); 155 } 156 157 /** 158 * Add a global workflow errors that will be traited as warnings 159 * @param transientVars the parameters from the call. 160 * @param warnLabel The warning label 161 * @throws WorkflowException if the result map is not found. 162 */ 163 @SuppressWarnings("cast") 164 public void addWorkflowWarning (Map transientVars, I18nizableText warnLabel) throws WorkflowException 165 { 166 Map<String, Object> resultMap = (Map<String, Object>) getResultsMap(transientVars); 167 if (!resultMap.containsKey(AbstractWorkflowComponent.WORKFLOW_WARNS_KEY)) 168 { 169 resultMap.put(AbstractWorkflowComponent.WORKFLOW_WARNS_KEY, new Errors()); 170 } 171 172 Errors errors = (Errors) resultMap.get(AbstractWorkflowComponent.WORKFLOW_WARNS_KEY); 173 errors.addError(warnLabel); 174 } 175}