Author: dpillot
Date: Thu Jun 28 17:17:07 2007
New Revision: 17825
URL: https://svndev.jahia.net/websvn/listing.php?sc=3D1&rev=3D17825&repname=
=3Djahia
Log:
http://www.jahia.net/jira/browse/JAHIA-1988:
added new JahiaGroovy engine extending the groovy engine with dependecies c=
heck control
Added:
branches/JAHIA-5-0-SP-BRANCH/core/src/java/org/jahia/services/events/Ja=
hiaGroovyEngine.java
Modified:
branches/JAHIA-5-0-SP-BRANCH/core/src/java/org/jahia/services/events/Gr=
oovyEventListener.java
branches/JAHIA-5-0-SP-BRANCH/core/src/webapp/WEB-INF/etc/spring/applica=
tioncontext-basejahiaconfig.xml
Modified: branches/JAHIA-5-0-SP-BRANCH/core/src/java/org/jahia/services/eve=
nts/GroovyEventListener.java
URL: https://svndev.jahia.net/websvn/diff.php?path=3D/branches/JAHIA-5-0-SP=
-BRANCH/core/src/java/org/jahia/services/events/GroovyEventListener.java&re=
v=3D17825&repname=3Djahia
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- branches/JAHIA-5-0-SP-BRANCH/core/src/java/org/jahia/services/events/Gr=
oovyEventListener.java (original)
+++ branches/JAHIA-5-0-SP-BRANCH/core/src/java/org/jahia/services/events/Gr=
oovyEventListener.java Thu Jun 28 17:17:07 2007
@@ -18,7 +18,8 @@
package org.jahia.services.events;
=
import groovy.lang.Binding;
-import groovy.util.GroovyScriptEngine;
+import org.apache.commons.collections.FastHashMap;
+import org.jahia.bin.Jahia;
import org.jahia.content.events.ContentActivationEvent;
import org.jahia.content.events.ContentObjectDeleteEvent;
import org.jahia.content.events.ContentObjectRestoreVersionEvent;
@@ -29,7 +30,6 @@
import org.jahia.params.ProcessingContext;
import org.jahia.services.timebasedpublishing.RetentionRuleEvent;
import org.jahia.services.workflow.WorkflowEvent;
-import org.apache.commons.collections.FastHashMap;
=
import java.io.File;
import java.util.Map;
@@ -59,8 +59,8 @@
"events/EventListener.groovy";
private static final String GROOVY_FILE_NAME =3D "EventListener.groovy=
";
=
- private GroovyScriptEngine groovyScriptEngine;
-
+ private JahiaGroovyEngine jahiaScriptEngine;
+ private static long lastCall=3D0;// used for performance mode
private boolean checkConfig (ProcessingContext processingContext) {
if (configLoaded)
return configLoaded;
@@ -82,7 +82,7 @@
=
defaultPathToGroovy =3D GroovyEventListener.DEFAULT_PATH_TO_GROOVY;
groovyFileName =3D GroovyEventListener.GROOVY_FILE_NAME;
- groovyScriptEngine =3D (GroovyScriptEngine) SpringContextSingleton=
.getInstance().getContext().getBean("groovyScriptEngine");
+ jahiaScriptEngine =3D (JahiaGroovyEngine) SpringContextSingleton.g=
etInstance().getContext().getBean("groovyScriptEngine");
=
configLoaded =3D true;
}
@@ -96,12 +96,23 @@
try {
String groovyFileName =3D resolveGroovyFullFileName(proces=
singContext);
=
+ // Developement mode flag
+ boolean checkDependances=3DJahia.getSettings().isDevelopme=
ntMode();
long startTime =3D System.currentTimeMillis();
- synchronized (groovyScriptEngine) {
+
+ //performance mode
+ if(startTime-lastCall<1500 && checkDependances && enabledP=
erformanceMode){
+ //under heavy load we avoid the checking bottleneck re=
peatedly, assuming script unchanged and dependencies too
+ checkDependances=3Dfalse;
+ logger.debug("lapse between 2 dependency checks too cl=
ose: no checks");
+ }
+ if(lastCall=3D=3D0) checkDependances=3Dtrue;//only the fir=
st time
+ lastCall=3DstartTime;
+ synchronized (jahiaScriptEngine) {
Binding binding =3D new Binding();
binding.setVariable("eventName", eventName);
binding.setVariable("jahiaEvent", je);
- groovyScriptEngine.run(groovyFileName, binding);
+ jahiaScriptEngine.run(groovyFileName, binding, checkDe=
pendances);
}
long endTime =3D System.currentTimeMillis();
long executionTime =3D endTime - startTime;
@@ -323,4 +334,6 @@
}
}
}
+ // this flag could be use to control the repeated dependencies check f=
rom groovy script
+ public static boolean enabledPerformanceMode=3Dtrue;
}
Added: branches/JAHIA-5-0-SP-BRANCH/core/src/java/org/jahia/services/events=
/JahiaGroovyEngine.java
URL: https://svndev.jahia.net/websvn/filedetails.php?path=3D/branches/JAHIA=
-5-0-SP-BRANCH/core/src/java/org/jahia/services/events/JahiaGroovyEngine.ja=
va&rev=3D17825&repname=3Djahia
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- branches/JAHIA-5-0-SP-BRANCH/core/src/java/org/jahia/services/events/Ja=
hiaGroovyEngine.java (added)
+++ branches/JAHIA-5-0-SP-BRANCH/core/src/java/org/jahia/services/events/Ja=
hiaGroovyEngine.java Thu Jun 28 17:17:07 2007
@@ -0,0 +1,182 @@
+package org.jahia.services.events;
+
+import groovy.lang.Binding;
+import groovy.lang.GroovyClassLoader;
+import groovy.lang.Script;
+import groovy.util.GroovyScriptEngine;
+import groovy.util.ResourceConnector;
+import groovy.util.ResourceException;
+import groovy.util.ScriptException;
+import org.codehaus.groovy.control.CompilationFailedException;
+import org.codehaus.groovy.runtime.InvokerHelper;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Jahia groovy script engine
+ *
+ */
+public class JahiaGroovyEngine extends GroovyScriptEngine {
+
+ private static org.apache.log4j.Logger logger =3D
+ org.apache.log4j.Logger.getLogger (JahiaGroovyEngine.class);
+
+ private static class ScriptCacheEntry {
+ private Class scriptClass;
+ private long lastModified;
+ private Map dependencies =3D new HashMap();
+ }
+
+ //private URL[] roots;
+ private Map scriptCache =3D Collections.synchronizedMap(new HashMap());
+ private ResourceConnector rc;
+
+ /**
+ * The groovy script engine will run groovy scripts and reload them and
+ * their dependencies when they are modified. This is useful for embed=
ding
+ * groovy in other containers like games and application servers.
+ *
+ * @param roots This an array of URLs where Groovy scripts will be sto=
red. They should
+ * be layed out using their package structure like Java c=
lasses
+ */
+ public JahiaGroovyEngine(URL[] roots) {
+ super(roots);
+ this.rc=3Dthis;
+ logger.debug("length URLS:"+roots.length);
+ for(int i=3D0;i<roots.length;i++){
+ logger.debug(i+" "+roots[i].getFile());
+ }
+
+ }
+
+ /**
+ * Run a script identified by name with dependencies control.
+ *
+ * @param scriptName name of the script to run
+ * @param binding binding to pass to the script
+ * @param DependenciesCheck boolean to control dependency check
+ * @return an object
+ * @throws groovy.util.ResourceException resource issue
+ * @throws groovy.util.ScriptException script parsing issue
+ */
+ public Object run(String scriptName, Binding binding,boolean Dependenc=
iesCheck) throws ResourceException, ScriptException {
+ ScriptCacheEntry entry =3D updateCacheEntry(scriptName, getParentC=
lassLoader(),DependenciesCheck);
+ Script scriptObject =3D InvokerHelper.createScript(entry.scriptCla=
ss, binding);
+ return scriptObject.run();
+ }
+
+ /**
+ * Locate the class and reload it or any of its dependencies
+ * (from private method of parent class)
+ * @param scriptName
+ * @param parentClassLoader
+ * @return the scriptName cache entry
+ * @throws ResourceException
+ * @throws ScriptException
+ */
+ private ScriptCacheEntry updateCacheEntry(String scriptName, final Cla=
ssLoader parentClassLoader, boolean dependenciesCheck)
+ throws ResourceException, ScriptException
+ {
+ ScriptCacheEntry entry;
+
+ scriptName =3D scriptName.intern();
+ synchronized (scriptName) {
+
+ URLConnection groovyScriptConn =3D rc.getResourceConnection(sc=
riptName);
+
+ // URL last modified
+ long lastModified =3D groovyScriptConn.getLastModified();
+ // Check the cache for the scriptName
+ entry =3D (ScriptCacheEntry) scriptCache.get(scriptName);
+ // If the entry isn't null check all the dependencies
+
+ boolean dependencyOutOfDate =3D false;
+
+ //checks only if dependenciesCheck is requested by caller or s=
cript is modified
+ if ((entry !=3D null && dependenciesCheck)||(entry !=3D null &=
& entry.lastModified < lastModified)) {
+
+ logger.debug("checking "+entry.dependencies.keySet().size(=
)+" dependencies");
+ for (Iterator i =3D entry.dependencies.keySet().iterator()=
; i.hasNext();) {
+ URLConnection urlc =3D null;
+ URL url =3D (URL) i.next();
+ try {
+ urlc =3D url.openConnection();
+ urlc.setDoInput(false);
+ urlc.setDoOutput(false);
+ long dependentLastModified =3D urlc.getLastModifie=
d();
+ if (dependentLastModified > ((Long) entry.dependen=
cies.get(url)).longValue()) {
+ dependencyOutOfDate =3D true;
+ break;
+ }
+ } catch (IOException ioe) {
+ dependencyOutOfDate =3D true;
+ break;
+ }
+ }
+ =
+ }
+
+ if (entry =3D=3D null || entry.lastModified < lastModified || =
dependencyOutOfDate) {
+ String loggermessage=3D"updating cache entry because ";
+ if(entry =3D=3D null)
+ loggermessage+=3D"entry is null, creating...";
+ if(entry !=3D null && entry.lastModified < lastModified)
+ loggermessage+=3D"entry is modified, updating...";
+ if(dependencyOutOfDate)
+ loggermessage+=3D"dependencies need to be updated";
+ logger.debug(loggermessage);
+ // Make a new entry
+ entry =3D new ScriptCacheEntry();
+
+ // Closure variable
+ final ScriptCacheEntry finalEntry =3D entry;
+
+ // Compile the scriptName into an object
+ GroovyClassLoader groovyLoader =3D
+ (GroovyClassLoader) AccessController.doPrivileged(=
new PrivilegedAction() {
+ public Object run() {
+ return new GroovyClassLoader(parentClassLo=
ader) {
+ protected Class findClass(String class=
Name) throws ClassNotFoundException {
+ String filename =3D className.repl=
ace('.', File.separatorChar) + ".groovy";
+ URLConnection dependentScriptConn =
=3D null;
+ try {
+ dependentScriptConn =3D rc.get=
ResourceConnection(filename);
+ finalEntry.dependencies.put(
+ dependentScriptConn.ge=
tURL(),
+ new Long(dependentScri=
ptConn.getLastModified()));
+ } catch (ResourceException e1) {
+ throw new ClassNotFoundExcepti=
on("Could not read " + className + ": " + e1);
+ }
+ try {
+ return parseClass(dependentScr=
iptConn.getInputStream(), filename);
+ } catch (CompilationFailedExceptio=
n e2) {
+ throw new ClassNotFoundExcepti=
on("Syntax error in " + className + ": " + e2);
+ } catch (IOException e2) {
+ throw new ClassNotFoundExcepti=
on("Problem reading " + className + ": " + e2);
+ }
+ }
+ };
+ }
+ });
+
+ try {
+ entry.scriptClass =3D groovyLoader.parseClass(groovySc=
riptConn.getInputStream(), scriptName);
+ } catch (Exception e) {
+ throw new ScriptException("Could not parse scriptName:=
" + scriptName, e);
+ }
+ entry.lastModified =3D lastModified;
+ scriptCache.put(scriptName, entry);
+ }
+ }
+ return entry;
+ }
+}
Modified: branches/JAHIA-5-0-SP-BRANCH/core/src/webapp/WEB-INF/etc/spring/a=
pplicationcontext-basejahiaconfig.xml
URL: https://svndev.jahia.net/websvn/diff.php?path=3D/branches/JAHIA-5-0-SP=
-BRANCH/core/src/webapp/WEB-INF/etc/spring/applicationcontext-basejahiaconf=
ig.xml&rev=3D17825&repname=3Djahia
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- branches/JAHIA-5-0-SP-BRANCH/core/src/webapp/WEB-INF/etc/spring/applica=
tioncontext-basejahiaconfig.xml (original)
+++ branches/JAHIA-5-0-SP-BRANCH/core/src/webapp/WEB-INF/etc/spring/applica=
tioncontext-basejahiaconfig.xml Thu Jun 28 17:17:07 2007
@@ -159,7 +159,7 @@
</property>
</bean>
=
- <bean id=3D"groovyScriptEngine" class=3D"groovy.util.GroovyScriptEngin=
e">
+ <bean id=3D"groovyScriptEngine" class=3D"org.jahia.services.events.Jah=
iaGroovyEngine">
<constructor-arg>
<list>
<value>file:///${jahiaWebAppRoot}/WEB-INF/var/scripts/groo=
vy/</value>
_______________________________________________
cvs_list mailing list
[email protected]
http://lists.jahia.org/cgi-bin/mailman/listinfo/cvs_list