001/* 002 * (C) Copyright 2006-2014 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 * Thierry Delprat 018 * Florent Guillaume 019 */ 020 021package org.nuxeo.ecm.automation.core.operations.execution; 022 023import java.util.Arrays; 024import java.util.Collection; 025import java.util.HashMap; 026import java.util.Map; 027 028import org.apache.commons.logging.Log; 029import org.apache.commons.logging.LogFactory; 030import org.nuxeo.ecm.automation.AutomationService; 031import org.nuxeo.ecm.automation.OperationContext; 032import org.nuxeo.ecm.automation.OperationException; 033import org.nuxeo.ecm.automation.core.Constants; 034import org.nuxeo.ecm.automation.core.annotations.Context; 035import org.nuxeo.ecm.automation.core.annotations.Operation; 036import org.nuxeo.ecm.automation.core.annotations.OperationMethod; 037import org.nuxeo.ecm.automation.core.annotations.Param; 038import org.nuxeo.ecm.core.api.CoreSession; 039import org.nuxeo.ecm.core.api.DocumentModel; 040import org.nuxeo.ecm.core.api.NuxeoException; 041import org.nuxeo.runtime.transaction.TransactionHelper; 042 043/** 044 * @deprecated since 6.0. Use instead {@link RunOperationOnList} with ID 'Context.RunOperationOnList'. Run an embedded 045 * operation chain inside separated transactions using the current input. The output is undefined (Void) 046 * @since 5.7.2 047 */ 048@Deprecated 049@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" }) 050public class RunOperationOnListInNewTransaction { 051 052 protected static Log log = LogFactory.getLog(RunOperationOnListInNewTransaction.class); 053 054 public static final String ID = "RunOperationOnListInNewTx"; 055 056 @Context 057 protected OperationContext ctx; 058 059 @Context 060 protected AutomationService service; 061 062 @Context 063 protected CoreSession session; 064 065 @Param(name = "id") 066 protected String chainId; 067 068 @Param(name = "list") 069 protected String listName; 070 071 @Param(name = "itemName", required = false, values = "item") 072 protected String itemName = "item"; 073 074 @Param(name = "isolate", required = false, values = "true") 075 protected boolean isolate = true; 076 077 @OperationMethod 078 public void run() throws OperationException { 079 Map<String, Object> vars = isolate ? new HashMap<String, Object>(ctx.getVars()) : ctx.getVars(); 080 081 Collection<?> list = null; 082 if (ctx.get(listName) instanceof Object[]) { 083 list = Arrays.asList((Object[]) ctx.get(listName)); 084 } else if (ctx.get(listName) instanceof Collection<?>) { 085 list = (Collection<?>) ctx.get(listName); 086 } else { 087 throw new UnsupportedOperationException(ctx.get(listName).getClass() + " is not a Collection"); 088 } 089 090 // commit the current transaction 091 TransactionHelper.commitOrRollbackTransaction(); 092 093 // execute on list in separate transactions 094 for (Object value : list) { 095 try { 096 TransactionHelper.runInNewTransaction(() -> { 097 try (OperationContext subctx = ctx.getSubContext(isolate, ctx.getInput())) { 098 subctx.push(itemName, value); 099 try { 100 service.run(subctx, chainId); 101 } finally { 102 subctx.pop(itemName); 103 } 104 } catch (OperationException e) { 105 throw new NuxeoException(e); 106 } 107 }); 108 } catch (NuxeoException e) { 109 if (e.getCause() instanceof OperationException) { 110 throw (OperationException) e.getCause(); 111 } 112 throw e; 113 } 114 } 115 116 TransactionHelper.startTransaction(); 117 118 // reconnect documents in the context 119 if (!isolate) { 120 for (String varName : vars.keySet()) { 121 if (!ctx.getVars().containsKey(varName)) { 122 ctx.put(varName, vars.get(varName)); 123 } else { 124 Object value = vars.get(varName); 125 if (session != null && value != null && value instanceof DocumentModel) { 126 ctx.getVars().put(varName, session.getDocument(((DocumentModel) value).getRef())); 127 } else { 128 ctx.getVars().put(varName, value); 129 } 130 } 131 } 132 } 133 } 134 135}