001/* 002 * (C) Copyright 2015 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 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-2.1.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 <tdelprat@nuxeo.com> 016 */ 017package org.nuxeo.automation.scripting.internals.operation; 018 019import java.util.ArrayList; 020import java.util.List; 021import java.util.Map; 022 023import javax.script.ScriptException; 024 025import jdk.nashorn.api.scripting.ScriptObjectMirror; 026import jdk.nashorn.internal.objects.NativeArray; 027 028import org.nuxeo.automation.scripting.api.AutomationScriptingService; 029import org.nuxeo.automation.scripting.internals.MarshalingHelper; 030import org.nuxeo.ecm.automation.OperationContext; 031import org.nuxeo.ecm.automation.OperationException; 032import org.nuxeo.ecm.automation.core.scripting.DocumentWrapper; 033import org.nuxeo.ecm.automation.core.util.BlobList; 034import org.nuxeo.ecm.core.api.Blob; 035import org.nuxeo.ecm.core.api.DocumentModel; 036import org.nuxeo.ecm.core.api.DocumentModelList; 037import org.nuxeo.ecm.core.api.impl.DocumentModelListImpl; 038import org.nuxeo.runtime.api.Framework; 039 040/** 041 * @since 7.2 042 */ 043public class ScriptingOperationImpl { 044 045 protected final OperationContext ctx; 046 047 protected final Map<String, Object> args; 048 049 protected final String source; 050 051 public ScriptingOperationImpl(String source, OperationContext ctx, Map<String, Object> args) throws ScriptException { 052 this.ctx = ctx; 053 this.args = args; 054 this.source = source; 055 } 056 057 public Object run(Object input) throws Exception { 058 try { 059 AutomationScriptingService scriptingService = Framework.getService(AutomationScriptingService.class); 060 scriptingService.setOperationContext(ctx); 061 ScriptingOperationInterface itf = scriptingService.getInterface(ScriptingOperationInterface.class, source, 062 ctx.getCoreSession()); 063 input = wrapArgsAndInput(input, args); 064 return unwrapResult(itf.run(input, args)); 065 } catch (ScriptException e) { 066 throw new OperationException(e); 067 } 068 } 069 070 protected Object wrapArgsAndInput(Object input, Map<String, Object> args) { 071 for (String entryId : args.keySet()) { 072 Object entry = args.get(entryId); 073 if (entry instanceof DocumentModel) { 074 args.put(entryId, new DocumentWrapper(ctx.getCoreSession(), (DocumentModel) entry)); 075 } 076 if (entry instanceof DocumentModelList) { 077 List<DocumentWrapper> docs = new ArrayList<>(); 078 for (DocumentModel doc : (DocumentModelList) entry) { 079 docs.add(new DocumentWrapper(ctx.getCoreSession(), doc)); 080 } 081 args.put(entryId, docs); 082 } 083 } 084 if (input instanceof DocumentModel) { 085 return new DocumentWrapper(ctx.getCoreSession(), (DocumentModel) input); 086 } else if (input instanceof DocumentModelList) { 087 List<DocumentWrapper> docs = new ArrayList<>(); 088 for (DocumentModel doc : (DocumentModelList) input) { 089 docs.add(new DocumentWrapper(ctx.getCoreSession(), doc)); 090 } 091 return docs; 092 } 093 return input; 094 } 095 096 protected Object unwrapResult(Object res) { 097 // Unwrap Context 098 for (String entryId : ctx.keySet()) { 099 Object entry = ctx.get(entryId); 100 if (entry instanceof DocumentWrapper) { 101 ctx.put(entryId, ((DocumentWrapper) entry).getDoc()); 102 } else if (ctx.get(entryId) instanceof List<?>) { 103 DocumentModelList docs = new DocumentModelListImpl(); 104 List<?> l = (List<?>) entry; 105 for (Object item : l) { 106 if (ctx.get(entryId) instanceof DocumentWrapper) { 107 docs.add(((DocumentWrapper) item).getDoc()); 108 } 109 } 110 if (docs.size() == l.size() && docs.size() > 0) { 111 ctx.put(entryId, ((DocumentWrapper) entry).getDoc()); 112 } 113 } 114 } 115 // Unwrap Result 116 if (res == null) { 117 return null; 118 } 119 if (res instanceof ScriptObjectMirror) { 120 Object unwrapped = MarshalingHelper.unwrap( 121 (ScriptObjectMirror) res); 122 if (unwrapped instanceof List<?>) { 123 DocumentModelList docs = new DocumentModelListImpl(); 124 List<?> l = (List<?>) unwrapped; 125 for (Object item : l) { 126 if (item instanceof DocumentWrapper) { 127 docs.add(((DocumentWrapper) item).getDoc()); 128 } 129 } 130 if (docs.size() == l.size() && docs.size() > 0) { 131 return docs; 132 } 133 } else if (unwrapped instanceof DocumentWrapper) { 134 return ((DocumentWrapper) unwrapped).getDoc(); 135 } 136 return unwrapped; 137 } else if (res instanceof NativeArray) { 138 Object[] resList = ((NativeArray) res).asObjectArray(); 139 DocumentModelList documentModelList = new DocumentModelListImpl(); 140 BlobList blobList = new BlobList(); 141 for (Object entry : resList) { 142 if (entry instanceof DocumentModel) { 143 documentModelList.add((DocumentModel) entry); 144 } else if (entry instanceof Blob) { 145 blobList.add((Blob) entry); 146 } else if (entry instanceof DocumentWrapper) { 147 documentModelList.add(((DocumentWrapper) entry).getDoc()); 148 } 149 } 150 return documentModelList.isEmpty() ? blobList : documentModelList; 151 } else if (res instanceof DocumentWrapper) { 152 return ((DocumentWrapper) res).getDoc(); 153 } else if (res instanceof List<?>) { 154 DocumentModelList docs = new DocumentModelListImpl(); 155 List<?> l = (List<?>) res; 156 for (Object item : l) { 157 if (item instanceof DocumentWrapper) { 158 docs.add(((DocumentWrapper) item).getDoc()); 159 } 160 } 161 if (docs.size() == l.size() && docs.size() > 0) { 162 return docs; 163 } 164 } 165 return res; 166 } 167 168}