svn commit: r660695 - /ofbiz/trunk/framework/base/src/base/org/ofbiz/base/util/GroovyUtil.java

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

svn commit: r660695 - /ofbiz/trunk/framework/base/src/base/org/ofbiz/base/util/GroovyUtil.java

jonesde
Author: jonesde
Date: Tue May 27 13:44:13 2008
New Revision: 660695

URL: http://svn.apache.org/viewvc?rev=660695&view=rev
Log:
Based on some comments from Joe Eckard and looking at the source for GroovyScriptEngine to see what it caches this now caches and runs based on parsed scripts, increasing performance

Modified:
    ofbiz/trunk/framework/base/src/base/org/ofbiz/base/util/GroovyUtil.java

Modified: ofbiz/trunk/framework/base/src/base/org/ofbiz/base/util/GroovyUtil.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/base/org/ofbiz/base/util/GroovyUtil.java?rev=660695&r1=660694&r2=660695&view=diff
==============================================================================
--- ofbiz/trunk/framework/base/src/base/org/ofbiz/base/util/GroovyUtil.java (original)
+++ ofbiz/trunk/framework/base/src/base/org/ofbiz/base/util/GroovyUtil.java Tue May 27 13:44:13 2008
@@ -28,9 +28,11 @@
 import org.ofbiz.base.util.cache.UtilCache;
 
 import groovy.lang.Binding;
+import groovy.lang.GroovyClassLoader;
 import groovy.lang.GroovyShell;
 import groovy.lang.Script;
 import org.codehaus.groovy.control.CompilationFailedException;
+import org.codehaus.groovy.runtime.InvokerHelper;
 
 /**
  * GroovyUtil - Groovy Utilities
@@ -40,10 +42,9 @@
 
     public static final String module = GroovyUtil.class.getName();
 
-    //public static UtilCache<String, Script> parsedScripts = new UtilCache<String, Script>("script.GroovyLocationParsedCache", 0, 0, false);
-    public static UtilCache<String, String> sourceScripts = new UtilCache<String, String>("script.GroovyLocationSourceCache", 0, 0, false);
+    public static UtilCache<String, Class> parsedScripts = new UtilCache<String, Class>("script.GroovyLocationParsedCache", 0, 0, false);
     
-    public static GroovyShell emptyGroovyShell = new GroovyShell();
+    public static GroovyClassLoader groovyClassLoader = new GroovyClassLoader();
 
     private static Binding getBinding(Map<String, Object> context) {
         Binding binding = new Binding();
@@ -62,10 +63,30 @@
 
     public static Object runScriptAtLocation(String location, Map<String, Object> context) throws GeneralException {
         try {
-         /* NOTE DEJ20080526: this approach uses a pre-parsed script but it is not thread safe
-         *
-         * the groovy Script object contains both the parsed script AND the context, which is weird when trying to run a cached Script
-         * there is no available clone() method on the Script object, so we can't clone and set the context/binding to get around thread-safe issues
+            Class scriptClass = parsedScripts.get(location);
+            if (scriptClass == null) {
+                URL scriptUrl = FlexibleLocation.resolveLocation(location);
+                if (scriptUrl == null) {
+                    throw new GeneralException("Script not found at location [" + location + "]");
+                }
+                
+                scriptClass = groovyClassLoader.parseClass(scriptUrl.openStream(), scriptUrl.getFile());
+                if (Debug.verboseOn()) Debug.logVerbose("Caching Groovy script at: " + location, module);
+                parsedScripts.put(location, scriptClass);
+            }
+
+            return InvokerHelper.createScript(scriptClass, getBinding(context)).run();
+
+            /* This code is just to test performance of the parsed versus unparsed approaches
+            long startTimeParsed = System.currentTimeMillis();
+            InvokerHelper.createScript(scriptClass, getBinding(context)).run();
+            if (Debug.timingOn()) Debug.logTiming("Ran parsed groovy script in [" + (System.currentTimeMillis() - startTimeParsed) + "]ms at: " + location, module);
+            */
+            
+            /* NOTE DEJ20080526: this approach uses a pre-parsed script but it is not thread safe
+             *
+             * the groovy Script object contains both the parsed script AND the context, which is weird when trying to run a cached Script
+             * there is no available clone() method on the Script object, so we can't clone and set the context/binding to get around thread-safe issues
             Script script = parsedScripts.get(location);
             if (script == null) {
                 URL scriptUrl = FlexibleLocation.resolveLocation(location);
@@ -80,8 +101,12 @@
             
             script.setBinding(getBinding(context));
             return script.run();
-            */
+             */
 
+            /* NOTE DEJ20080527: this approach works but only caches script text, not the parsed script
+            public static UtilCache<String, String> sourceScripts = new UtilCache<String, String>("script.GroovyLocationSourceCache", 0, 0, false);
+            
+            public static GroovyShell emptyGroovyShell = new GroovyShell();
             String scriptString = sourceScripts.get(location);
             if (scriptString == null) {
                 URL scriptUrl = FlexibleLocation.resolveLocation(location);
@@ -102,6 +127,7 @@
             if (Debug.timingOn()) Debug.logTiming("Parsed and ran groovy script in [" + (System.currentTimeMillis() - startTime) + "]ms at: " + location, module);
             
             return scriptResult;
+             */
         } catch (MalformedURLException e) {
             String errMsg = "Error loading Groovy script at [" + location + "]: " + e.toString();
             throw new GeneralException(errMsg, e);