001/*
002 * Copyright (c) 2006-2014 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *     bstefanescu
011 *     Vladimir Pasquier <vpasquier@nuxeo.com>
012 */
013package org.nuxeo.ecm.automation.core.operations.execution;
014
015import org.nuxeo.ecm.automation.AutomationService;
016import org.nuxeo.ecm.automation.OperationContext;
017import org.nuxeo.ecm.automation.OperationException;
018import org.nuxeo.ecm.automation.core.Constants;
019import org.nuxeo.ecm.automation.core.annotations.Context;
020import org.nuxeo.ecm.automation.core.annotations.Operation;
021import org.nuxeo.ecm.automation.core.annotations.OperationMethod;
022import org.nuxeo.ecm.automation.core.annotations.Param;
023import org.nuxeo.ecm.automation.core.util.BlobList;
024import org.nuxeo.ecm.automation.core.util.Properties;
025import org.nuxeo.ecm.core.api.Blob;
026import org.nuxeo.ecm.core.api.CoreSession;
027import org.nuxeo.ecm.core.api.DocumentModel;
028
029import java.util.HashMap;
030import java.util.Map;
031
032/**
033 * Run an embedded operation chain that returns a Blob using the current input.
034 *
035 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
036 */
037@Operation(id = RunFileChain.ID, category = Constants.CAT_SUBCHAIN_EXECUTION, label = "Run File Chain", description = "Run an operation chain which is returning a file in the current context. The input for the chain to run is a file or a list of files. Return the output of the chain as a file or a list of files. The 'parameters' injected are accessible in the subcontext ChainParameters. For instance, @{ChainParameters['parameterKey']}.", aliases = { "Context.RunFileOperation" })
038public class RunFileChain {
039
040    public static final String ID = "RunFileOperation";
041
042    @Context
043    protected OperationContext ctx;
044
045    @Context
046    protected AutomationService service;
047
048    @Context
049    protected CoreSession session;
050
051    @Param(name = "id")
052    protected String chainId;
053
054    @Param(name = "isolate", required = false, values = "false")
055    protected boolean isolate = false;
056
057    @Param(name = "parameters", description = "Accessible in the subcontext ChainParameters. For instance, @{ChainParameters['parameterKey']}.", required = false)
058    protected Properties chainParameters;
059
060    /**
061     * @since 6.0 Define if the chain in parameter should be executed in new transaction.
062     */
063    @Param(name = "newTx", required = false, values = "false", description = "Define if the chain in parameter should be executed in new transaction.")
064    protected boolean newTx = false;
065
066    /**
067     * @since 6.0 Define transaction timeout (default to 60 sec).
068     */
069    @Param(name = "timeout", required = false, description = "Define transaction timeout (default to 60 sec).")
070    protected Integer timeout = 60;
071
072    /**
073     * @since 6.0 Define if transaction should rollback or not (default to true).
074     */
075    @Param(name = "rollbackGlobalOnError", required = false, values = "true", description = "Define if transaction should rollback or not (default to true)")
076    protected boolean rollbackGlobalOnError = true;
077
078    @OperationMethod
079    public Blob run(Blob blob) throws OperationException {
080        // Handle isolation option
081        Map<String, Object> vars = isolate ? new HashMap<>(ctx.getVars()) : ctx.getVars();
082        OperationContext subctx = ctx.getSubContext(isolate, blob);
083
084        // Running chain/operation
085        Blob result = null;
086        if (newTx) {
087            result = (Blob) service.runInNewTx(subctx, chainId, chainParameters, timeout, rollbackGlobalOnError);
088        } else {
089            result = (Blob) service.run(subctx, chainId, (Map) chainParameters);
090        }
091
092        // reconnect documents in the context
093        if (!isolate) {
094            for (String varName : vars.keySet()) {
095                if (!ctx.getVars().containsKey(varName)) {
096                    ctx.put(varName, vars.get(varName));
097                } else {
098                    Object value = vars.get(varName);
099                    if (session != null && value != null && value instanceof DocumentModel) {
100                        ctx.getVars().put(varName, session.getDocument(((DocumentModel) value).getRef()));
101                    } else {
102                        ctx.getVars().put(varName, value);
103                    }
104                }
105            }
106        }
107        return result;
108    }
109
110    @OperationMethod
111    public BlobList run(BlobList blobs) throws OperationException {
112        BlobList result = new BlobList(blobs.size());
113        for (Blob blob : blobs) {
114            result.add(run(blob));
115        }
116        return result;
117    }
118
119}