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 *    Mariana Cedica
011 *    Florent Guillaume
012 */
013package org.nuxeo.ecm.automation.core.operations.execution;
014
015import java.util.HashMap;
016import java.util.Map;
017
018import org.apache.commons.logging.Log;
019import org.apache.commons.logging.LogFactory;
020import org.nuxeo.ecm.automation.AutomationService;
021import org.nuxeo.ecm.automation.OperationContext;
022import org.nuxeo.ecm.automation.OperationException;
023import org.nuxeo.ecm.automation.core.Constants;
024import org.nuxeo.ecm.automation.core.annotations.Context;
025import org.nuxeo.ecm.automation.core.annotations.Operation;
026import org.nuxeo.ecm.automation.core.annotations.OperationMethod;
027import org.nuxeo.ecm.automation.core.annotations.Param;
028import org.nuxeo.ecm.automation.core.util.Properties;
029import org.nuxeo.ecm.core.api.CoreSession;
030import org.nuxeo.ecm.core.api.DocumentModel;
031import org.nuxeo.runtime.transaction.TransactionHelper;
032
033/**
034 * @deprecated since 6.0. Use instead {@link RunDocumentChain} with ID 'Context.RunDocumentOperation'. Operation to run
035 *             an operation chain in a separate transaction. The existing transaction is committed before running the
036 *             new transaction.
037 * @since 5.6
038 */
039@Deprecated
040@Operation(id = RunInNewTransaction.ID, category = Constants.CAT_SUBCHAIN_EXECUTION, label = "Run Document Chain in new Tx", description = "Run an operation chain in a separate tx. The 'parameters' injected are accessible in the subcontext ChainParameters. For instance, @{ChainParameters['parameterKey']}.", deprecatedSince = "6.0")
041public class RunInNewTransaction {
042
043    public static final String ID = "Context.RunDocumentOperationInNewTx";
044
045    private static final Log log = LogFactory.getLog(RunInNewTransaction.class);
046
047    @Context
048    protected OperationContext ctx;
049
050    @Context
051    protected AutomationService service;
052
053    @Context
054    protected CoreSession session;
055
056    @Param(name = "id")
057    protected String chainId;
058
059    @Param(name = "isolate", required = false, values = "false")
060    protected boolean isolate = false;
061
062    @Param(name = "rollbackGlobalOnError", required = false, values = "false")
063    protected boolean rollbackGlobalOnError = false;
064
065    @Param(name = "parameters", description = "Accessible in the subcontext ChainParameters. For instance, @{ChainParameters['parameterKey']}.", required = false)
066    protected Properties chainParameters;
067
068    @Param(name = "timeout", required = false)
069    protected Integer timeout = Integer.valueOf(60);
070
071    @OperationMethod
072    public void run() throws OperationException {
073        // if the current transaction was already marked for rollback, do nothing
074        if (TransactionHelper.isTransactionMarkedRollback()) {
075            return;
076        }
077        // commit the current transaction
078        TransactionHelper.commitOrRollbackTransaction();
079
080        Map<String, Object> vars = isolate ? new HashMap<String, Object>(ctx.getVars()) : ctx.getVars();
081
082        int to = timeout == null ? 0 : timeout.intValue();
083
084        TransactionHelper.startTransaction(to);
085        boolean ok = false;
086        try {
087            OperationContext subctx = new OperationContext(session, vars);
088            subctx.setInput(ctx.getInput());
089            service.run(subctx, chainId, (Map) chainParameters);
090            ok = true;
091        } catch (OperationException e) {
092            if (rollbackGlobalOnError) {
093                throw e;
094            } else {
095                // just log, no rethrow
096                log.error("Error while executing operation " + chainId, e);
097            }
098        } finally {
099            if (!ok) {
100                // will be logged by Automation framework
101                TransactionHelper.setTransactionRollbackOnly();
102            }
103            TransactionHelper.commitOrRollbackTransaction();
104            // caller expects a transaction to be started
105            TransactionHelper.startTransaction();
106        }
107
108        // reconnect documents in the context
109        if (!isolate) {
110            for (String varName : vars.keySet()) {
111                if (!ctx.getVars().containsKey(varName)) {
112                    ctx.put(varName, vars.get(varName));
113                } else {
114                    Object value = vars.get(varName);
115                    if (session != null && value != null && value instanceof DocumentModel) {
116                        ctx.getVars().put(varName, session.getDocument(((DocumentModel) value).getRef()));
117                    } else {
118                        ctx.getVars().put(varName, value);
119                    }
120                }
121            }
122        }
123    }
124
125}