001/*
002 *  Copyright 2017 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.bpm.process;
017
018import java.util.ArrayList;
019import java.util.List;
020import java.util.Map;
021
022import org.apache.avalon.framework.parameters.Parameters;
023import org.apache.avalon.framework.service.ServiceException;
024import org.apache.avalon.framework.service.ServiceManager;
025import org.apache.cocoon.acting.ServiceableAction;
026import org.apache.cocoon.environment.ObjectModelHelper;
027import org.apache.cocoon.environment.Redirector;
028import org.apache.cocoon.environment.Request;
029import org.apache.cocoon.environment.SourceResolver;
030import org.apache.cocoon.servlet.multipart.Part;
031import org.apache.cocoon.servlet.multipart.PartOnDisk;
032import org.apache.cocoon.servlet.multipart.RejectedPart;
033import org.apache.commons.lang3.StringUtils;
034
035import org.ametys.plugins.bpm.BPMWorkflowManager;
036import org.ametys.plugins.bpm.jcr.JCRWorkflowProcess;
037import org.ametys.plugins.repository.AmetysObjectResolver;
038import org.ametys.plugins.repository.provider.RequestAttributeWorkspaceSelector;
039
040import com.google.common.collect.ImmutableList;
041import com.opensymphony.workflow.WorkflowException;
042
043/**
044 * Action for creating or editing a process
045 */
046public class CreateProcessAction extends ServiceableAction
047{
048    private static final String PARAM_PROCESS_ID = "processId";
049    private static final String PARAM_WORKFLOW = "workflow";
050    private static final String PARAM_TITLE = "title";
051    private static final String PARAM_DESCRIPTION = "description";
052    private static final String PARAM_ATTACHMENTS = "attachments";
053    private static final String PARAM_ATTACHMENTS_UNTOUCHED = "attachments-untouched";
054
055    private BPMWorkflowManager _bpmWorkflowManager;
056    private AmetysObjectResolver _resolver;
057    
058    @Override
059    public void service(ServiceManager smanager) throws ServiceException
060    {
061        super.service(smanager);
062        _bpmWorkflowManager = (BPMWorkflowManager) smanager.lookup(BPMWorkflowManager.ROLE);
063        _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE);
064    }
065
066    @SuppressWarnings("unchecked")
067    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception
068    {
069        Request request = ObjectModelHelper.getRequest(objectModel);
070
071        String processId = request.getParameter(PARAM_PROCESS_ID);
072        String workflowId = request.getParameter(PARAM_WORKFLOW);
073        String title = request.getParameter(PARAM_TITLE);
074        String description = request.getParameter(PARAM_DESCRIPTION);
075        String site = request.getParameter("site");
076        String lang = request.getParameter("lang");
077        Object attachmentsObject = request.get(PARAM_ATTACHMENTS);
078        Object attachmentsUntouchedObject = request.get(PARAM_ATTACHMENTS_UNTOUCHED);
079        List<String> attachmentsUntouched = null; 
080        if (attachmentsUntouchedObject instanceof List)
081        {
082            attachmentsUntouched = (List<String>) attachmentsUntouchedObject;
083        }
084        else if (attachmentsUntouchedObject instanceof String)
085        {
086            attachmentsUntouched = ImmutableList.of((String) attachmentsUntouchedObject);
087        }
088
089        List<PartOnDisk> uploadedAttachments = new ArrayList<>();
090        if (attachmentsObject != null)
091        {
092            List<Part> attachments = attachmentsObject instanceof List ? (List<Part>) attachmentsObject : ImmutableList.of((Part) attachmentsObject);
093            for (Part attachment : attachments)
094            {
095                if (attachment == null || attachment instanceof RejectedPart)
096                {
097                    throw new IllegalArgumentException("Rejected attachment files when creating or editing a process");
098                }
099                uploadedAttachments.add((PartOnDisk) attachment);
100            }
101        }
102        
103        String currentWorkspace = RequestAttributeWorkspaceSelector.getForcedWorkspace(request);
104        try
105        {
106            RequestAttributeWorkspaceSelector.setForcedWorkspace(request, "default");
107            
108            if (StringUtils.isNotEmpty(processId))
109            {
110                _editProcess(processId, title, description, attachmentsUntouched, uploadedAttachments);
111            }
112            else
113            {
114                processId = _createProcess(workflowId, title, description, site, uploadedAttachments);
115            }
116        }
117        finally
118        {
119            RequestAttributeWorkspaceSelector.setForcedWorkspace(request, currentWorkspace);
120        }
121        
122        JCRWorkflowProcess process = _resolver.resolveById(processId);
123        redirector.globalRedirect(false, _bpmWorkflowManager.getProcessPageUrl(process, site, lang, true));
124        
125        return EMPTY_MAP;
126    }
127
128    private String _createProcess(String workflowId, String title, String description, String site, List<PartOnDisk> uploadedAttachments)
129            throws IllegalAccessException, WorkflowException
130    {
131        if (StringUtils.isEmpty(workflowId) || StringUtils.isEmpty(title))
132        {
133            throw new IllegalArgumentException("Missing mandatory arguments for creating a new process");
134        }
135
136        JCRWorkflowProcess process = _bpmWorkflowManager.createProcess(workflowId, title, site, description, uploadedAttachments);
137        return process.getId();
138    }
139
140    private void _editProcess(String processId, String title, String description, List<String> attachmentsUntouchedObject, List<PartOnDisk> uploadedAttachments) throws WorkflowException
141    {
142        if (StringUtils.isEmpty(title))
143        {
144            throw new IllegalArgumentException("Missing mandatory arguments for editing the process '" + processId + "'");
145        }
146        
147        _bpmWorkflowManager.editProcess(processId, title, description, uploadedAttachments, attachmentsUntouchedObject);
148    }
149
150
151}