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.forms.content.workflow;
017
018import java.util.HashMap;
019import java.util.Map;
020
021import org.apache.avalon.framework.parameters.Parameters;
022import org.apache.avalon.framework.service.ServiceException;
023import org.apache.avalon.framework.service.ServiceManager;
024import org.apache.cocoon.environment.ObjectModelHelper;
025import org.apache.cocoon.environment.Redirector;
026import org.apache.cocoon.environment.Request;
027import org.apache.commons.collections.MapUtils;
028
029import org.ametys.cms.repository.Content;
030import org.ametys.cms.workflow.AbstractContentWorkflowComponent;
031import org.ametys.core.cocoon.ActionResultGenerator;
032import org.ametys.core.user.CurrentUserProvider;
033import org.ametys.core.user.User;
034import org.ametys.core.user.UserIdentity;
035import org.ametys.core.user.UserManager;
036import org.ametys.core.util.JSONUtils;
037import org.ametys.plugins.forms.content.Form;
038import org.ametys.plugins.forms.content.data.UserEntry;
039import org.ametys.plugins.forms.content.jcr.FormPropertiesManager;
040import org.ametys.plugins.forms.content.table.FormTableManager;
041import org.ametys.plugins.forms.workflow.SendMailFunction;
042import org.ametys.plugins.workflow.AbstractWorkflowComponent;
043import org.ametys.plugins.workflow.cocoon.WorkflowAction;
044import org.ametys.plugins.workflow.store.JdbcWorkflowStore;
045
046import com.opensymphony.workflow.InvalidInputException;
047import com.opensymphony.workflow.Workflow;
048import com.opensymphony.workflow.WorkflowException;
049
050/**
051 * Action for executing a transition on a form entry workflow.<p>
052 * The following parameters are supported:
053 * <dl>
054 *  <dt>actionId
055 *  <dd>the id of the action to fire
056 * </dl>
057 */
058public class FormEntriesWorkflowAction extends WorkflowAction
059{
060    /** Component gathering utility methods to work with the forms JCR representations */
061    private FormPropertiesManager _formPropertiesManager;
062    
063    /** Helper to manipulation the forms SQL tables */
064    private FormTableManager _formTableManager;
065    
066    /** Helper to retrieve the current user */
067    private CurrentUserProvider _currentUserProvider;
068    
069    /** The users manager */
070    private UserManager _userManager;
071    
072    /** Utility component for the handling of object represented in JSON */
073    private JSONUtils _jsonUtils;
074    
075    @Override
076    public void service(ServiceManager serviceManager) throws ServiceException
077    {
078        super.service(serviceManager);
079        _formPropertiesManager = (FormPropertiesManager) serviceManager.lookup(FormPropertiesManager.ROLE);
080        _formTableManager = (FormTableManager) serviceManager.lookup(FormTableManager.ROLE);
081        _currentUserProvider = (CurrentUserProvider) serviceManager.lookup(CurrentUserProvider.ROLE);
082        _userManager = (UserManager) serviceManager.lookup(UserManager.ROLE);
083        _jsonUtils = (JSONUtils) serviceManager.lookup(JSONUtils.ROLE);
084    }
085    
086    @Override
087    protected Map _act(Redirector redirector, Map objectModel, String source, Parameters parameters, int actionId, Map inputs) throws InvalidInputException, WorkflowException
088    {
089        Workflow workflow = _workflowProvider.getExternalWorkflow(JdbcWorkflowStore.ROLE);
090        workflow.doAction(_getWorkflowId(objectModel, source, parameters), actionId, inputs);
091        return _getActionResult(redirector, objectModel, source, parameters);
092    }
093    
094    @Override
095    protected long _getWorkflowId(Map objectModel, String source, Parameters parameters)
096    {
097        try
098        {
099            String entryId = parameters.getParameter("entryId");
100            String formId = parameters.getParameter("formId");
101            
102            Form form = _formPropertiesManager.getForm(formId);           
103            UserEntry submission = _formTableManager.getSubmission(form, new HashMap<>(), Integer.valueOf(entryId));
104        
105            if (submission == null)
106            {
107                throw new RuntimeException("Unable to retrieve the workflow id for the entry '" + entryId + "' of the form '" + formId + "'.");
108            }
109            else
110            {
111                return submission.getWorkflowId();
112            }
113        }
114        catch (Exception e)
115        {
116            throw new RuntimeException("Missing parameter workflowId", e);
117        }
118    }
119    
120    @Override
121    protected Map<String, Object> _getInputs(Redirector redirector, Map objectModel, String source, Parameters parameters) throws Exception
122    {
123        Map<String, Object> inputs = super._getInputs(redirector, objectModel, source, parameters);
124        
125        String formId = parameters.getParameter("formId");
126        Content formContent = _formPropertiesManager.getFormContent(formId);
127        // Provide the content key
128        inputs.put(AbstractContentWorkflowComponent.CONTENT_KEY, formContent);
129        
130        // Provide a map for providing data to the generator
131        Request request = ObjectModelHelper.getRequest(objectModel);
132        Map<String, Object> result = new HashMap<>();
133        request.setAttribute(ActionResultGenerator.MAP_REQUEST_ATTR, result);
134        inputs.put(AbstractWorkflowComponent.RESULT_MAP_KEY, result);
135        
136        // Set the workflow comment into the inputs.
137        String comment = request.getParameter("comment");
138        inputs.put("comment", comment);
139        
140        // Set the values for the information request function if a mail is to be sent
141        String sendMailAsJSON = request.getParameter("sendMailInfo");
142        Map<String, Object> sendMailInfo = _jsonUtils.convertJsonToMap(sendMailAsJSON); 
143        if (MapUtils.isNotEmpty(sendMailInfo))
144        {
145            // Retrieve the current user name and email
146            UserIdentity userIdentity = _currentUserProvider.getUser();
147            User user = _userManager.getUser(userIdentity.getPopulationId(), userIdentity.getLogin());
148            
149            inputs.put(SendMailFunction.SENDER, user.getEmail());
150            inputs.put(SendMailFunction.RECIPIENT, sendMailInfo.get("recipient"));
151            inputs.put(SendMailFunction.SUBJECT, sendMailInfo.get("subject"));
152            inputs.put(SendMailFunction.BODY, sendMailInfo.get("body"));
153        }
154        else
155        {
156            inputs.put(SendMailFunction.SEND_MAIL, "false");
157        }
158        
159        
160        return inputs;
161    }
162}