You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by ad...@apache.org on 2012/03/06 03:16:30 UTC

svn commit: r1297323 - in /ofbiz/trunk/framework: base/src/org/ofbiz/base/util/ common/script/org/ofbiz/common/ common/servicedef/ service/config/ service/src/org/ofbiz/service/engine/

Author: adrianc
Date: Tue Mar  6 02:16:29 2012
New Revision: 1297323

URL: http://svn.apache.org/viewvc?rev=1297323&view=rev
Log:
More JSR-233 work - added a generic script service engine.

Added:
    ofbiz/trunk/framework/common/script/org/ofbiz/common/JavaScriptTest.js
    ofbiz/trunk/framework/service/src/org/ofbiz/service/engine/ScriptEngine.java   (with props)
Modified:
    ofbiz/trunk/framework/base/src/org/ofbiz/base/util/ScriptUtil.java
    ofbiz/trunk/framework/common/script/org/ofbiz/common/GroovyServiceTest.groovy
    ofbiz/trunk/framework/common/servicedef/services_test.xml
    ofbiz/trunk/framework/service/config/serviceengine.xml

Modified: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/ScriptUtil.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/util/ScriptUtil.java?rev=1297323&r1=1297322&r2=1297323&view=diff
==============================================================================
--- ofbiz/trunk/framework/base/src/org/ofbiz/base/util/ScriptUtil.java (original)
+++ ofbiz/trunk/framework/base/src/org/ofbiz/base/util/ScriptUtil.java Tue Mar  6 02:16:29 2012
@@ -197,7 +197,7 @@ public final class ScriptUtil {
         try {
             CompiledScript compiledScript = compileScriptString(language, script);
             if (compiledScript != null) {
-                return executeScript(compiledScript, null, inputMap);
+                return executeScript(compiledScript, null, createScriptContext(inputMap), null);
             }
             ScriptEngineManager manager = new ScriptEngineManager();
             ScriptEngine engine = manager.getEngineByName(language);
@@ -221,13 +221,12 @@ public final class ScriptUtil {
      * 
      * @param script Compiled script.
      * @param functionName Optional function or method to invoke.
-     * @param context Script execution context.
+     * @param scriptContext Script execution context.
      * @return The script result.
      * @throws IllegalArgumentException
      */
-    public static Object executeScript(CompiledScript script, String functionName, Map<String, ? extends Object> context) throws ScriptException, NoSuchMethodException {
-        Assert.notNull("script", script, "context", context);
-        ScriptContext scriptContext = createScriptContext(context);
+    public static Object executeScript(CompiledScript script, String functionName, ScriptContext scriptContext, Object[] args) throws ScriptException, NoSuchMethodException {
+        Assert.notNull("script", script, "scriptContext", scriptContext);
         Object result = script.eval(scriptContext);
         if (UtilValidate.isNotEmpty(functionName)) {
             if (Debug.verboseOn()) {
@@ -236,7 +235,7 @@ public final class ScriptUtil {
             ScriptEngine engine = script.getEngine();
             try {
                 Invocable invocableEngine = (Invocable) engine;
-                result = invocableEngine.invokeFunction(functionName, EMPTY_ARGS);
+                result = invocableEngine.invokeFunction(functionName, args);
             } catch (ClassCastException e) {
                 throw new ScriptException("Script engine " + engine.getClass().getName() + " does not support function/method invocations");
             }
@@ -254,39 +253,70 @@ public final class ScriptUtil {
      * @throws IllegalArgumentException
      */
     public static Object executeScript(String filePath, String functionName, Map<String, ? extends Object> context) {
+        return executeScript(filePath, functionName, context, EMPTY_ARGS);
+    }
+
+    /**
+     * Executes the script at the specified location and returns the result.
+     * 
+     * @param filePath Script path and file name.
+     * @param functionName Optional function or method to invoke.
+     * @param scriptContext Script execution context.
+     * @param args Function/method arguments.
+     * @return The script result.
+     * @throws ScriptException 
+     * @throws MalformedURLException 
+     * @throws FileNotFoundException 
+     * @throws NoSuchMethodException 
+     * @throws IllegalArgumentException
+     */
+    public static Object executeScript(String filePath, String functionName, ScriptContext scriptContext, Object[] args) throws FileNotFoundException, MalformedURLException, ScriptException, NoSuchMethodException {
+        CompiledScript script = compileScriptFile(filePath);
+        if (script != null) {
+            return executeScript(script, functionName, scriptContext, args);
+        }
+        String fileExtension = getFileExtension(filePath);
+        ScriptEngineManager manager = new ScriptEngineManager();
+        ScriptEngine engine = manager.getEngineByExtension(fileExtension);
+        if (engine == null) {
+            throw new IllegalArgumentException("The script type is not supported for location: " + filePath);
+        }
+        if (Debug.verboseOn()) {
+            Debug.logVerbose("Begin processing script [" + script + "] using engine " + engine.getClass().getName(), module);
+        }
+        URL scriptUrl = FlexibleLocation.resolveLocation(filePath);
+        FileReader reader = new FileReader(new File(scriptUrl.getFile()));
+        Object result = engine.eval(reader, scriptContext);
+        if (UtilValidate.isNotEmpty(functionName)) {
+            try {
+                Invocable invocableEngine = (Invocable) engine;
+                result = invocableEngine.invokeFunction(functionName, args);
+            } catch (ClassCastException e) {
+                throw new ScriptException("Script engine " + engine.getClass().getName() + " does not support function/method invocations");
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Executes the script at the specified location and returns the result.
+     * 
+     * @param filePath Script path and file name.
+     * @param functionName Optional function or method to invoke.
+     * @param context Script execution context.
+     * @param args Function/method arguments.
+     * @return The script result.
+     * @throws IllegalArgumentException
+     */
+    public static Object executeScript(String filePath, String functionName, Map<String, ? extends Object> context, Object[] args) {
         Assert.notNull("filePath", filePath, "context", context);
         try {
-            CompiledScript script = compileScriptFile(filePath);
-            if (script != null) {
-                return executeScript(script, functionName, context);
-            }
             String fileExtension = getFileExtension(filePath);
             // TODO: Remove beanshell check when all beanshell code has been removed.
             if ("bsh".equals(fileExtension)) {
                 return BshUtil.runBshAtLocation(filePath, context);
-            } else {
-                ScriptEngineManager manager = new ScriptEngineManager();
-                ScriptEngine engine = manager.getEngineByExtension(fileExtension);
-                if (engine == null) {
-                    throw new IllegalArgumentException("The script type is not supported for location: " + filePath);
-                }
-                if (Debug.verboseOn()) {
-                    Debug.logVerbose("Begin processing script [" + script + "] using engine " + engine.getClass().getName(), module);
-                }
-                ScriptContext scriptContext = createScriptContext(context);
-                URL scriptUrl = FlexibleLocation.resolveLocation(filePath);
-                FileReader reader = new FileReader(new File(scriptUrl.getFile()));
-                Object result = engine.eval(reader, scriptContext);
-                if (UtilValidate.isNotEmpty(functionName)) {
-                    try {
-                        Invocable invocableEngine = (Invocable) engine;
-                        result = invocableEngine.invokeFunction(functionName, EMPTY_ARGS);
-                    } catch (ClassCastException e) {
-                        throw new ScriptException("Script engine " + engine.getClass().getName() + " does not support function/method invocations");
-                    }
-                }
-                return result;
             }
+            return executeScript(filePath, functionName, createScriptContext(context), args);
         } catch (Exception e) {
             String errMsg = "Error running script at location [" + filePath + "]: " + e.toString();
             Debug.logWarning(e, errMsg, module);

Modified: ofbiz/trunk/framework/common/script/org/ofbiz/common/GroovyServiceTest.groovy
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/common/script/org/ofbiz/common/GroovyServiceTest.groovy?rev=1297323&r1=1297322&r2=1297323&view=diff
==============================================================================
--- ofbiz/trunk/framework/common/script/org/ofbiz/common/GroovyServiceTest.groovy (original)
+++ ofbiz/trunk/framework/common/script/org/ofbiz/common/GroovyServiceTest.groovy Tue Mar  6 02:16:29 2012
@@ -32,5 +32,38 @@ if (context.message) {
     result.result = (String) "[no message received]";
     Debug.logInfo("----- No message received -----", "");
 }
-
 return result;
+
+// GroovyEngine will invoke the no-arg method.
+public Map testMethod() {
+    Debug.logInfo("----- no-arg testMethod invoked -----", "");
+    result = ServiceUtil.returnSuccess();
+    if (context.message) {
+        String message = context.message;
+        result.successMessage = (String) "Got message [$message] and finished fine";
+        result.result = message;
+        Debug.logInfo("----- Message is: $message -----", "");
+    } else {
+        result.successMessage = (String) "Got no message but finished fine anyway";
+        result.result = (String) "[no message received]";
+        Debug.logInfo("----- No message received -----", "");
+    }
+    return result;
+}
+
+// ScriptEngine (JSR-223) will invoke the arg method.
+public Map testMethod(Map context) {
+    Debug.logInfo("----- arg testMethod invoked -----", "");
+    result = ServiceUtil.returnSuccess();
+    if (context.message) {
+        String message = context.message;
+        result.successMessage = (String) "Got message [$message] and finished fine";
+        result.result = message;
+        Debug.logInfo("----- Message is: $message -----", "");
+    } else {
+        result.successMessage = (String) "Got no message but finished fine anyway";
+        result.result = (String) "[no message received]";
+        Debug.logInfo("----- No message received -----", "");
+    }
+    return result;
+}

Added: ofbiz/trunk/framework/common/script/org/ofbiz/common/JavaScriptTest.js
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/common/script/org/ofbiz/common/JavaScriptTest.js?rev=1297323&view=auto
==============================================================================
--- ofbiz/trunk/framework/common/script/org/ofbiz/common/JavaScriptTest.js (added)
+++ ofbiz/trunk/framework/common/script/org/ofbiz/common/JavaScriptTest.js Tue Mar  6 02:16:29 2012
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+if (message) {
+    var successMessage = "Got message [" + message + "] and finished fine";
+    var result = message;
+} else {
+    var successMessage = "Got no message but finished fine anyway";
+    var result = "[no message received]";
+}
+
+function testFunction(context) {
+    if (message) {
+        var successMessage = "Got message [" + message + "] and finished fine";
+        var result = message;
+    } else {
+        var successMessage = "Got no message but finished fine anyway";
+        var result = "[no message received]";
+    }
+    return result;
+}

Modified: ofbiz/trunk/framework/common/servicedef/services_test.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/common/servicedef/services_test.xml?rev=1297323&r1=1297322&r2=1297323&view=diff
==============================================================================
--- ofbiz/trunk/framework/common/servicedef/services_test.xml (original)
+++ ofbiz/trunk/framework/common/servicedef/services_test.xml Tue Mar  6 02:16:29 2012
@@ -172,6 +172,38 @@ under the License.
         <attribute name="result" type="String" mode="OUT"/>
     </service>
 
+    <service name="testGroovyMethod" engine="groovy" location="component://common/script/org/ofbiz/common/GroovyServiceTest.groovy" invoke="testMethod">
+        <description>Test Groovy Script Service Method Invocation</description>
+        <attribute name="message" type="String" mode="IN" optional="true"/>
+        <attribute name="result" type="String" mode="OUT"/>
+    </service>
+
+    <service name="testScriptEngineGroovy" engine="script" location="component://common/script/org/ofbiz/common/GroovyServiceTest.groovy" invoke="">
+        <description>Test Script Engine With Groovy Script</description>
+        <attribute name="message" type="String" mode="IN" optional="true"/>
+        <attribute name="result" type="String" mode="OUT"/>
+    </service>
+
+    <service name="testScriptEngineGroovyMethod" engine="script" location="component://common/script/org/ofbiz/common/GroovyServiceTest.groovy" invoke="testMethod">
+        <description>Test Script Engine With Groovy Script Method Invocation</description>
+        <attribute name="message" type="String" mode="IN" optional="true"/>
+        <attribute name="result" type="String" mode="OUT"/>
+    </service>
+
+    <service name="testScriptEngineJavaScript" engine="script" location="component://common/script/org/ofbiz/common/JavaScriptTest.js" invoke="">
+        <description>Test Script Engine With JavaScript</description>
+        <attribute name="message" type="String" mode="IN" optional="true"/>
+        <attribute name="result" type="String" mode="OUT"/>
+    </service>
+
+    <!-- JavaScript function invocations are not working, so commenting this out for now
+    <service name="testScriptEngineJavaScriptFunction" engine="script" location="component://common/script/org/ofbiz/common/JavaScriptTest.js" invoke="testFunction">
+        <description>Test Script Engine With JavaScript Function Invocation</description>
+        <attribute name="message" type="String" mode="IN" optional="true"/>
+        <attribute name="result" type="String" mode="OUT"/>
+    </service>
+     -->
+
     <service name="testJMSQueue" engine="jms" location="serviceMessenger" invoke="testScv">
         <description>Test JMS Queue service</description>
         <attribute name="message" type="String" mode="IN"/>

Modified: ofbiz/trunk/framework/service/config/serviceengine.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/config/serviceengine.xml?rev=1297323&r1=1297322&r2=1297323&view=diff
==============================================================================
--- ofbiz/trunk/framework/service/config/serviceengine.xml (original)
+++ ofbiz/trunk/framework/service/config/serviceengine.xml Tue Mar  6 02:16:29 2012
@@ -40,20 +40,23 @@ under the License.
         </thread-pool>
 
         <!-- Service Engine Configuration -->
-        <engine name="bsh" class="org.ofbiz.service.engine.BeanShellEngine"/>
         <engine name="entity-auto" class="org.ofbiz.service.engine.EntityAutoEngine"/>
-        <engine name="groovy" class="org.ofbiz.service.engine.GroovyEngine"/>
         <engine name="group" class="org.ofbiz.service.group.ServiceGroupEngine"/>
-        <engine name="http" class="org.ofbiz.service.engine.HttpEngine"/>
         <engine name="interface" class="org.ofbiz.service.engine.InterfaceEngine"/>
-        <engine name="jacl" class="org.ofbiz.service.engine.BSFEngine"/>
         <engine name="java" class="org.ofbiz.service.engine.StandardJavaEngine"/>
-        <engine name="javascript" class="org.ofbiz.service.engine.BSFEngine"/>
-        <engine name="jms" class="org.ofbiz.service.jms.JmsServiceEngine"/>
+        <engine name="simple" class="org.ofbiz.minilang.SimpleServiceEngine"/>
+        <engine name="script" class="org.ofbiz.service.engine.ScriptEngine"/>
+        <!-- Engines that can be replaced by the generic script engine -->
+        <engine name="bsh" class="org.ofbiz.service.engine.BeanShellEngine"/>
+        <engine name="groovy" class="org.ofbiz.service.engine.GroovyEngine"/>
+        <engine name="jacl" class="org.ofbiz.service.engine.BSFEngine"/>
+        <engine name="javascript" class="org.ofbiz.service.engine.ScriptEngine"/>
         <engine name="jpython" class="org.ofbiz.service.engine.BSFEngine"/>
+        <!--  -->
         <engine name="route" class="org.ofbiz.service.engine.RouteEngine"/>
+        <engine name="http" class="org.ofbiz.service.engine.HttpEngine"/>
+        <engine name="jms" class="org.ofbiz.service.jms.JmsServiceEngine"/>
         <engine name="rmi" class="org.ofbiz.service.rmi.RmiServiceEngine"/>
-        <engine name="simple" class="org.ofbiz.minilang.SimpleServiceEngine"/>
         <engine name="soap" class="org.ofbiz.service.engine.SOAPClientEngine"/>
         <engine name="ofbiz-workflow" class="org.ofbiz.workflow.WorkflowEngine"/>
         <engine name="workflow" class="org.ofbiz.shark.service.SharkServiceEngine"/>
@@ -63,6 +66,7 @@ under the License.
             <parameter name="login" value="admin"/>
             <parameter name="password" value="ofbiz"/>
         </engine>
+
         <service-location name="main-rmi" location="rmi://localhost:1099/RMIDispatcher"/>
         <service-location name="main-http" location="http://localhost:8080/webtools/control/httpService"/>
 

Added: ofbiz/trunk/framework/service/src/org/ofbiz/service/engine/ScriptEngine.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/org/ofbiz/service/engine/ScriptEngine.java?rev=1297323&view=auto
==============================================================================
--- ofbiz/trunk/framework/service/src/org/ofbiz/service/engine/ScriptEngine.java (added)
+++ ofbiz/trunk/framework/service/src/org/ofbiz/service/engine/ScriptEngine.java Tue Mar  6 02:16:29 2012
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *******************************************************************************/
+package org.ofbiz.service.engine;
+
+import static org.ofbiz.base.util.UtilGenerics.cast;
+
+import java.util.Map;
+
+import javax.script.ScriptContext;
+
+import javolution.util.FastMap;
+
+import org.ofbiz.base.util.Assert;
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.ScriptUtil;
+import org.ofbiz.service.DispatchContext;
+import org.ofbiz.service.GenericServiceException;
+import org.ofbiz.service.ModelService;
+import org.ofbiz.service.ServiceDispatcher;
+import org.ofbiz.service.ServiceUtil;
+
+/**
+ * Generic Script Service Engine. This service engine uses the javax.script package (JSR-223) to invoke scripts or script functions.
+ * <p>The script service engine will put the following artifacts in the script engine's bindings:<br />
+ * <ul>
+ *   <li><code>parameters</code> - the service attributes <code>Map</code></li>
+ *   <li><code>dctx</code> - a <code>DispatchContext</code> instance</li>
+ *   <li><code>dispatcher</code> - a <code>LocalDispatcher</code> instance</li>
+ *   <li><code>delegator</code> - a <code>Delegator</code> instance</li>
+ * </ul></p>
+ * <p>If the service definition includes an invoke attribute, then the matching script function/method will be called
+ * with a single argument - the bindings <code>Map</code>.</p>
+ */
+public final class ScriptEngine extends GenericAsyncEngine {
+
+    public static final String module = ScriptEngine.class.getName();
+
+    public ScriptEngine(ServiceDispatcher dispatcher) {
+        super(dispatcher);
+    }
+
+    @Override
+    public void runSyncIgnore(String localName, ModelService modelService, Map<String, Object> context) throws GenericServiceException {
+        runSync(localName, modelService, context);
+    }
+
+    @Override
+    public Map<String, Object> runSync(String localName, ModelService modelService, Map<String, Object> context) throws GenericServiceException {
+        Assert.notNull("localName", localName, "modelService.location", modelService.location, "context", context);
+        Map<String, Object> params = FastMap.newInstance();
+        params.putAll(context);
+        context.put("parameters", params);
+        DispatchContext dctx = dispatcher.getLocalContext(localName);
+        context.put("dctx", dctx);
+        context.put("dispatcher", dctx.getDispatcher());
+        context.put("delegator", dispatcher.getDelegator());
+        try {
+            ScriptContext scriptContext = ScriptUtil.createScriptContext(context);
+            Object resultObj = ScriptUtil.executeScript(getLocation(modelService), modelService.invoke, scriptContext, new Object[] { context });
+            if (resultObj == null) {
+                resultObj = scriptContext.getAttribute("result");
+            }
+            Debug.logInfo("resultObj = " + resultObj, module);
+            if (resultObj != null && resultObj instanceof Map<?, ?>) {
+                return cast(resultObj);
+            }
+            Map<String, Object> result = ServiceUtil.returnSuccess();
+            result.putAll(modelService.makeValid(scriptContext.getBindings(ScriptContext.ENGINE_SCOPE), "OUT"));
+            return result;
+        } catch (Exception e) {
+            Debug.logInfo(e, module);
+            throw new GenericServiceException(e);
+        }
+    }
+
+}

Propchange: ofbiz/trunk/framework/service/src/org/ofbiz/service/engine/ScriptEngine.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/framework/service/src/org/ofbiz/service/engine/ScriptEngine.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Rev URL