001/* 002 * (C) Copyright 2006-2014 Nuxeo SAS (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * Thierry Delprat 016 * Florent Guillaume 017 */ 018 019package org.nuxeo.ecm.automation.core.operations.execution; 020 021import java.util.Arrays; 022import java.util.Collection; 023import java.util.HashMap; 024import java.util.Map; 025 026import org.apache.commons.logging.Log; 027import org.apache.commons.logging.LogFactory; 028import org.nuxeo.ecm.automation.AutomationService; 029import org.nuxeo.ecm.automation.OperationContext; 030import org.nuxeo.ecm.automation.OperationException; 031import org.nuxeo.ecm.automation.core.Constants; 032import org.nuxeo.ecm.automation.core.annotations.Context; 033import org.nuxeo.ecm.automation.core.annotations.Operation; 034import org.nuxeo.ecm.automation.core.annotations.OperationMethod; 035import org.nuxeo.ecm.automation.core.annotations.Param; 036import org.nuxeo.ecm.core.api.CoreSession; 037import org.nuxeo.ecm.core.api.DocumentModel; 038import org.nuxeo.runtime.transaction.TransactionHelper; 039 040/** 041 * @deprecated since 6.0. Use instead {@link RunOperationOnList} with ID 'Context.RunOperationOnList'. Run an embedded 042 * operation chain inside separated transactions using the current input. The output is undefined (Void) 043 * @since 5.7.2 044 */ 045@Deprecated 046@Operation(id = RunOperationOnListInNewTransaction.ID, category = Constants.CAT_SUBCHAIN_EXECUTION, label = "Run For Each in new TX", description = "Run an operation/chain in a new Transaction for each element from the list defined by the 'list' parameter. The 'list' parameter is pointing to a context variable that represents the list which will be iterated. The 'itemName' parameter represents the name of the context variable which will point to the current element in the list at each iteration. You can use the 'isolate' parameter to specify whether or not the evalution context is the same as the parent context or a copy of it. If the 'isolate' parameter is 'true' then a copy of the current context is used and so that modifications in this context will not affect the parent context. Any input is accepted. The input is returned back as output when operation terminates.", deprecatedSince = "6.0", aliases = { "Context.RunOperationOnListInNewTx" }) 047public class RunOperationOnListInNewTransaction { 048 049 protected static Log log = LogFactory.getLog(RunOperationOnListInNewTransaction.class); 050 051 public static final String ID = "RunOperationOnListInNewTx"; 052 053 @Context 054 protected OperationContext ctx; 055 056 @Context 057 protected AutomationService service; 058 059 @Context 060 protected CoreSession session; 061 062 @Param(name = "id") 063 protected String chainId; 064 065 @Param(name = "list") 066 protected String listName; 067 068 @Param(name = "itemName", required = false, values = "item") 069 protected String itemName = "item"; 070 071 @Param(name = "isolate", required = false, values = "true") 072 protected boolean isolate = true; 073 074 @OperationMethod 075 public void run() throws OperationException { 076 Map<String, Object> vars = isolate ? new HashMap<String, Object>(ctx.getVars()) : ctx.getVars(); 077 078 Collection<?> list = null; 079 if (ctx.get(listName) instanceof Object[]) { 080 list = Arrays.asList((Object[]) ctx.get(listName)); 081 } else if (ctx.get(listName) instanceof Collection<?>) { 082 list = (Collection<?>) ctx.get(listName); 083 } else { 084 throw new UnsupportedOperationException(ctx.get(listName).getClass() + " is not a Collection"); 085 } 086 087 // commit the current transaction 088 TransactionHelper.commitOrRollbackTransaction(); 089 090 // execute on list in separate transactions 091 for (Object value : list) { 092 TransactionHelper.startTransaction(); 093 boolean completedAbruptly = true; 094 try { 095 OperationContext subctx = new OperationContext(session, vars); 096 subctx.setInput(ctx.getInput()); 097 subctx.put(itemName, value); 098 service.run(subctx, chainId, null); 099 completedAbruptly = false; 100 } finally { 101 if (completedAbruptly) { 102 TransactionHelper.setTransactionRollbackOnly(); 103 } 104 TransactionHelper.commitOrRollbackTransaction(); 105 } 106 } 107 108 TransactionHelper.startTransaction(); 109 110 // reconnect documents in the context 111 if (!isolate) { 112 for (String varName : vars.keySet()) { 113 if (!ctx.getVars().containsKey(varName)) { 114 ctx.put(varName, vars.get(varName)); 115 } else { 116 Object value = vars.get(varName); 117 if (session != null && value != null && value instanceof DocumentModel) { 118 ctx.getVars().put(varName, session.getDocument(((DocumentModel) value).getRef())); 119 } else { 120 ctx.getVars().put(varName, value); 121 } 122 } 123 } 124 } 125 } 126 127}