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