001/*
002 * (C) Copyright 2012 Nuxeo SA (http://nuxeo.com/) and others.
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 *
016 * Contributors:
017 *     mcedica
018 */
019package org.nuxeo.ecm.platform.routing.core.api.operation;
020
021import java.io.Serializable;
022import java.util.ArrayList;
023import java.util.HashMap;
024import java.util.List;
025import java.util.Map;
026
027import org.apache.commons.logging.Log;
028import org.apache.commons.logging.LogFactory;
029import org.nuxeo.ecm.automation.OperationContext;
030import org.nuxeo.ecm.automation.core.Constants;
031import org.nuxeo.ecm.automation.core.annotations.Context;
032import org.nuxeo.ecm.automation.core.annotations.Operation;
033import org.nuxeo.ecm.automation.core.annotations.OperationMethod;
034import org.nuxeo.ecm.automation.core.annotations.Param;
035import org.nuxeo.ecm.automation.core.util.DataModelProperties;
036import org.nuxeo.ecm.automation.core.util.Properties;
037import org.nuxeo.ecm.core.api.CoreSession;
038import org.nuxeo.ecm.core.api.DocumentModel;
039import org.nuxeo.ecm.core.api.DocumentModelList;
040import org.nuxeo.ecm.core.api.NuxeoException;
041import org.nuxeo.ecm.platform.routing.api.DocumentRoutingConstants;
042import org.nuxeo.ecm.platform.routing.api.DocumentRoutingService;
043
044/**
045 * Starts the workflow with the given model id on the input documents. Returns back the input documents. The id of the
046 * created workflow instance is available under the \"WorkflowId\" context variable.
047 *
048 * @since 5.6
049 */
050@Operation(id = StartWorkflowOperation.ID, category = Constants.CAT_WORKFLOW, label = "Start workflow", requires = Constants.WORKFLOW_CONTEXT, description = "Starts the workflow with the given model id on the input documents. Returns back the input documents."
051        + "The id of the created workflow instance is available under the \"workflowInstanceId\" context variable."
052        + "@Since 5.7.2 you can set multiple variables on the workflow (before 5.8 only scalar types are supported). The variables are specified as <i>key=value</i> pairs separated by a new line."
053        + "To specify multi-line values you can use a \\ character followed by a new line. <p>Example:<pre>description=foo bar</pre>For updating a date, you will need to expose the value as ISO 8601 format, "
054        + "for instance : <p>Example:<pre>title=The Document Title<br>issued=@{org.nuxeo.ecm.core.schema.utils.DateParser.formatW3CDateTime(CurrentDate.date)}</pre><p>"
055        + " @since 5.9.3 and 5.8.0-HF10 you can also set variables of complex types, by submiting a JSON representation: "
056        + "<p><pre>assignees = [\"John Doe\", \"John Test\"]</pre></p>")
057public class StartWorkflowOperation {
058
059    public static final String ID = "Context.StartWorkflow";
060
061    private static Log log = LogFactory.getLog(StartWorkflowOperation.class);
062
063    @Context
064    protected CoreSession session;
065
066    @Context
067    protected OperationContext ctx;
068
069    @Param(name = "id", required = true)
070    protected String id;
071
072    @Param(name = "start", required = false, values = "true")
073    protected Boolean start = true;
074
075    // @since 5.7.2
076    @Param(name = "variables", required = false)
077    protected Properties variables;
078
079    @Context
080    protected DocumentRoutingService documentRoutingService;
081
082    @OperationMethod
083    public DocumentModelList run(DocumentModelList docs) {
084        List<String> ids = new ArrayList<>();
085        for (DocumentModel doc : docs) {
086            ids.add(doc.getId());
087        }
088        startNewInstance(ids);
089        return docs;
090    }
091
092    @OperationMethod
093    public DocumentModel run(DocumentModel doc) {
094        List<String> ids = new ArrayList<>();
095        ids.add(doc.getId());
096        startNewInstance(ids);
097        return doc;
098    }
099
100    protected void startNewInstance(List<String> ids) {
101        if (!documentRoutingService.canCreateInstance(session, ids, id)) {
102            throw new NuxeoException(
103                    String.format("Cannot start the workflow model %s for the input documents %s", id, ids));
104        }
105        Map<String, Serializable> vars = null;
106        if (variables != null) {
107            if (variables instanceof DataModelProperties) {
108                vars = ((DataModelProperties) variables).getMap();
109                vars.put(DocumentRoutingConstants._MAP_VAR_FORMAT_JSON, false);
110            } else {
111                vars = new HashMap<>(variables);
112                vars.put(DocumentRoutingConstants._MAP_VAR_FORMAT_JSON, true);
113            }
114        }
115        String workflowId = documentRoutingService.createNewInstance(id, ids, vars, session, Boolean.TRUE.equals(start));
116        ctx.put("WorkflowId", workflowId);
117        // to be consistent with all the other workflow variablesin the context
118        // @since 5.7.2
119        ctx.put("workflowInstanceId", workflowId);
120    }
121}