[exo-jcr-commits] exo-jcr SVN: r3702 - in jcr/trunk/exo.jcr.component.ext/src: test/java/org/exoplatform/services/jcr/ext/script/groovy and 1 other directories.
do-not-reply at jboss.org
do-not-reply at jboss.org
Wed Dec 22 05:24:13 EST 2010
Author: aparfonov
Date: 2010-12-22 05:24:13 -0500 (Wed, 22 Dec 2010)
New Revision: 3702
Added:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrClassPathEntry.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyClassLoaderProvider.java
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/script/groovy/BaseGroovyTest.java
Modified:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyScript2RestLoader.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyCompiler.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyResourceLoader.java
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyCompilerTest.java
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyScript2RestLoaderTest.java
jcr/trunk/exo.jcr.component.ext/src/test/resources/conf/standalone/test-configuration.xml
Log:
EXOJCR-1105
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyScript2RestLoader.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyScript2RestLoader.java 2010-12-22 10:15:37 UTC (rev 3701)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyScript2RestLoader.java 2010-12-22 10:24:13 UTC (rev 3702)
@@ -35,6 +35,7 @@
import org.exoplatform.services.jcr.ext.registry.RegistryService;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
+import org.exoplatform.services.rest.ext.groovy.GroovyClassLoaderProvider;
import org.exoplatform.services.rest.ext.groovy.GroovyJaxrsPublisher;
import org.exoplatform.services.rest.ext.groovy.ResourceId;
import org.exoplatform.services.rest.impl.ResourceBinder;
@@ -95,6 +96,14 @@
@Path("script/groovy")
public class GroovyScript2RestLoader implements Startable
{
+ protected static class InnerGroovyJaxrsPublisher extends GroovyJaxrsPublisher
+ {
+ public InnerGroovyJaxrsPublisher(ResourceBinder binder, GroovyScriptInstantiator instantiator,
+ GroovyClassLoaderProvider classLoaderProvider)
+ {
+ super(binder, instantiator, classLoaderProvider);
+ }
+ }
/** Logger. */
static final Log LOG = ExoLogger.getLogger("exo.jcr.component.ext.GroovyScript2RestLoader");
@@ -149,7 +158,8 @@
InitParams params)
{
this(binder, groovyScriptInstantiator, repositoryService, sessionProviderService, configurationManager, null,
- new GroovyJaxrsPublisher(binder, groovyScriptInstantiator), jcrUrlHandler, params);
+ new InnerGroovyJaxrsPublisher(binder, groovyScriptInstantiator, new JcrGroovyClassLoaderProvider()),
+ jcrUrlHandler, params);
}
/**
@@ -167,7 +177,8 @@
org.exoplatform.services.jcr.ext.resource.jcr.Handler jcrUrlHandler, InitParams params)
{
this(binder, groovyScriptInstantiator, repositoryService, sessionProviderService, configurationManager,
- registryService, new GroovyJaxrsPublisher(binder, groovyScriptInstantiator), jcrUrlHandler, params);
+ registryService, new InnerGroovyJaxrsPublisher(binder, groovyScriptInstantiator,
+ new JcrGroovyClassLoaderProvider()), jcrUrlHandler, params);
}
public GroovyScript2RestLoader(ResourceBinder binder, GroovyScriptInstantiator groovyScriptInstantiator,
@@ -186,9 +197,9 @@
/**
* Remove script with specified URL from ResourceBinder.
- *
+ *
* @param url the URL. The <code>url.toString()</code> must be corresponded
- * to script class.
+ * to script class.
* @see GroovyScriptRestLoader#loadScript(URL).
* @deprecated
*/
@@ -199,7 +210,7 @@
/**
* Remove script by specified key from ResourceBinder.
- *
+ *
* @param key the key with which script was created.
* @see GroovyScript2RestLoader#loadScript(String, InputStream)
* @see GroovyScript2RestLoader#loadScript(String, String, InputStream)
@@ -253,7 +264,7 @@
/**
* Get node type for store scripts, may throw {@link IllegalStateException}
* if <tt>nodeType</tt> not initialized yet.
- *
+ *
* @return return node type
*/
public String getNodeType()
@@ -286,7 +297,7 @@
/**
* Load script from given stream.
- *
+ *
* @param key the key which must be corresponded to object class name.
* @param stream the stream which represents groovy script.
* @return if script loaded false otherwise
@@ -301,10 +312,10 @@
/**
* Load script from given stream.
- *
+ *
* @param key the key which must be corresponded to object class name.
* @param name this name will be passed to compiler to get understandable if
- * compilation failed
+ * compilation failed
* @param stream the stream which represents groovy script.
* @return if script loaded false otherwise
* @throws IOException if script can't be loaded or parsed.
@@ -424,10 +435,12 @@
repositoryName, workspaceName, node), null);
}
- session.getWorkspace().getObservationManager().addEventListener(
- new GroovyScript2RestUpdateListener(repositoryName, workspaceName, this, session),
- Event.PROPERTY_ADDED | Event.PROPERTY_CHANGED | Event.PROPERTY_REMOVED, "/", true, null,
- new String[]{getNodeType()}, false);
+ session
+ .getWorkspace()
+ .getObservationManager()
+ .addEventListener(new GroovyScript2RestUpdateListener(repositoryName, workspaceName, this, session),
+ Event.PROPERTY_ADDED | Event.PROPERTY_CHANGED | Event.PROPERTY_REMOVED, "/", true, null,
+ new String[]{getNodeType()}, false);
}
}
catch (Exception e)
@@ -552,7 +565,7 @@
/**
* Create JCR node.
- *
+ *
* @param parent parent node
* @param name name of node to be created
* @param stream data stream for property jcr:data
@@ -572,7 +585,7 @@
/**
* Read parameters from RegistryService.
- *
+ *
* @param sessionProvider the SessionProvider
* @throws RepositoryException
* @throws PathNotFoundException
@@ -622,7 +635,7 @@
/**
* Write parameters to RegistryService.
- *
+ *
* @param sessionProvider the SessionProvider
* @throws ParserConfigurationException
* @throws SAXException
@@ -637,8 +650,7 @@
LOG.debug(">>> Save init parametrs in registry service.");
}
- Document doc = SecurityHelper.doPriviledgedParserConfigurationAction(new PrivilegedExceptionAction<Document>()
- {
+ Document doc = SecurityHelper.doPriviledgedParserConfigurationAction(new PrivilegedExceptionAction<Document>() {
public Document run() throws Exception
{
return DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
@@ -675,7 +687,7 @@
/**
* Get attribute value.
- *
+ *
* @param element The element to get attribute value
* @param attr The attribute name
* @return Value of attribute if present and null in other case
@@ -687,7 +699,7 @@
/**
* Set attribute value. If value is null the attribute will be removed.
- *
+ *
* @param element The element to set attribute value
* @param attr The attribute name
* @param value The value of attribute
@@ -735,7 +747,7 @@
* This method is useful for clients that can send script in request body
* without form-data. At required to set specific Content-type header
* 'script/groovy'.
- *
+ *
* @param stream the stream that contains groovy source code
* @param uriInfo see {@link UriInfo}
* @param repository repository name
@@ -805,8 +817,7 @@
try
{
final String fName = name;
- SecurityHelper.doPriviledgedExceptionAction(new PrivilegedExceptionAction<Void>()
- {
+ SecurityHelper.doPriviledgedExceptionAction(new PrivilegedExceptionAction<Void>() {
public Void run() throws Exception
{
groovyClassLoader.parseClass(script, fName);
@@ -828,7 +839,7 @@
* This method is useful for clients that can send script in request body
* without form-data. At required to set specific Content-type header
* 'script/groovy'.
- *
+ *
* @param stream the stream that contains groovy source code
* @param uriInfo see {@link UriInfo}
* @param repository repository name
@@ -883,7 +894,7 @@
* script. This method is created just for comfort loading script from HTML
* form. NOT use this script for uploading few files in body of
* 'multipart/form-data' or other type of multipart.
- *
+ *
* @param items iterator {@link FileItem}
* @param uriInfo see {@link UriInfo}
* @param repository repository name
@@ -954,7 +965,7 @@
* script. This method is created just for comfort loading script from HTML
* form. NOT use this script for uploading few files in body of
* 'multipart/form-data' or other type of multipart.
- *
+ *
* @param items iterator {@link FileItem}
* @param uriInfo see {@link UriInfo}
* @param repository repository name
@@ -1010,7 +1021,7 @@
/**
* Get source code of groovy script.
- *
+ *
* @param repository repository name
* @param workspace workspace name
* @param path JCR path to node that contains script
@@ -1029,8 +1040,9 @@
sessionProviderService.getSessionProvider(null).getSession(workspace,
repositoryService.getRepository(repository));
Node scriptFile = (Node)ses.getItem("/" + path);
- return Response.status(Response.Status.OK).entity(
- scriptFile.getNode("jcr:content").getProperty("jcr:data").getStream()).type("script/groovy").build();
+ return Response.status(Response.Status.OK)
+ .entity(scriptFile.getNode("jcr:content").getProperty("jcr:data").getStream()).type("script/groovy")
+ .build();
}
catch (PathNotFoundException e)
{
@@ -1055,7 +1067,7 @@
/**
* Get groovy script's meta-information.
- *
+ *
* @param repository repository name
* @param workspace workspace name
* @param path JCR path to node that contains script
@@ -1105,7 +1117,7 @@
/**
* Remove node that contains groovy script.
- *
+ *
* @param repository repository name
* @param workspace workspace name
* @param path JCR path to node that contains script
@@ -1150,14 +1162,14 @@
* Change exo:autoload property. If this property is 'true' script will be
* deployed automatically when JCR repository startup and automatically
* re-deployed when script source code changed.
- *
+ *
* @param repository repository name
* @param workspace workspace name
* @param path JCR path to node that contains script
* @param state value for property exo:autoload, if it is not specified then
- * 'true' will be used as default. <br />
- * Example: .../scripts/groovy/test1.groovy/load is the same to
- * .../scripts/groovy/test1.groovy/load?state=true
+ * 'true' will be used as default. <br />
+ * Example: .../scripts/groovy/test1.groovy/load is the same to
+ * .../scripts/groovy/test1.groovy/load?state=true
*/
@POST
@Path("autoload/{repository}/{workspace}/{path:.*}")
@@ -1201,16 +1213,16 @@
* script will be deployed as REST service if 'false' the script will be
* undeployed. NOTE is script already deployed and <tt>state</tt> is
* <tt>true</tt> script will be re-deployed.
- *
+ *
* @param repository repository name
* @param workspace workspace name
* @param path the path to JCR node that contains groovy script to be
- * deployed
+ * deployed
* @param state <code>true</code> if resource should be loaded and
- * <code>false</code> otherwise. If this attribute is not present in
- * HTTP request then it will be considered as <code>true</code>
+ * <code>false</code> otherwise. If this attribute is not present
+ * in HTTP request then it will be considered as <code>true</code>
* @param properties optional properties to be applied to loaded resource.
- * Ignored if <code>state</code> parameter is false
+ * Ignored if <code>state</code> parameter is false
*/
@POST
@Path("load/{repository}/{workspace}/{path:.*}")
@@ -1236,9 +1248,9 @@
{
if (null == groovyPublisher.unpublishResource(key))
{
- return Response.status(Response.Status.BAD_REQUEST).entity(
- "Can't unbind script " + path + ", not bound or has wrong mapping to the resource class ").type(
- MediaType.TEXT_PLAIN).build();
+ return Response.status(Response.Status.BAD_REQUEST)
+ .entity("Can't unbind script " + path + ", not bound or has wrong mapping to the resource class ")
+ .type(MediaType.TEXT_PLAIN).build();
}
}
return Response.status(Response.Status.NO_CONTENT).build();
@@ -1276,12 +1288,12 @@
/**
* Returns the list of all groovy-scripts found in workspace.
- *
+ *
* @param repository Repository name.
* @param workspace Workspace name.
* @param name Additional search parameter. If not emtpy method returns the
- * list of script names matching wildcard else returns all the scripts
- * found in workspace.
+ * list of script names matching wildcard else returns all the
+ * scripts found in workspace.
* @return
*/
@POST
@@ -1367,7 +1379,7 @@
/**
* Extract path to node's parent from full path.
- *
+ *
* @param fullPath full path to node
* @return node's parent path
*/
@@ -1379,7 +1391,7 @@
/**
* Extract node's name from full node path.
- *
+ *
* @param fullPath full path to node
* @return node's name
*/
@@ -1459,7 +1471,7 @@
/**
* Returns the list of scripts.
- *
+ *
* @return the list of scripts.
*/
public List<String> getList()
@@ -1469,7 +1481,7 @@
/**
* ScriptList constructor.
- *
+ *
* @param the list of scripts
*/
public ScriptList(List<String> scriptList)
Added: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrClassPathEntry.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrClassPathEntry.java (rev 0)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrClassPathEntry.java 2010-12-22 10:24:13 UTC (rev 3702)
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2010 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.ext.script.groovy;
+
+import org.exoplatform.services.jcr.ext.resource.UnifiedNodeReference;
+import org.exoplatform.services.rest.ext.groovy.ClassPathEntry;
+
+import java.net.MalformedURLException;
+
+/**
+ * @author <a href="mailto:andrey.parfonov at exoplatform.com">Andrey Parfonov</a>
+ * @version $Id$
+ */
+public class JcrClassPathEntry extends ClassPathEntry
+{
+ public JcrClassPathEntry(EntryType type, UnifiedNodeReference path) throws MalformedURLException
+ {
+ super(type, path.getURL());
+ }
+}
Property changes on: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrClassPathEntry.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyClassLoaderProvider.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyClassLoaderProvider.java (rev 0)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyClassLoaderProvider.java 2010-12-22 10:24:13 UTC (rev 3702)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.ext.script.groovy;
+
+import groovy.lang.GroovyClassLoader;
+
+import org.exoplatform.services.rest.ext.groovy.ClassPathEntry;
+import org.exoplatform.services.rest.ext.groovy.GroovyClassLoaderProvider;
+import org.exoplatform.services.rest.ext.groovy.ClassPathEntry.EntryType;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:andrey.parfonov at exoplatform.com">Andrey Parfonov</a>
+ * @version $Id$
+ */
+public class JcrGroovyClassLoaderProvider extends GroovyClassLoaderProvider
+{
+ /**
+ * @see org.exoplatform.services.rest.ext.groovy.GroovyClassLoaderProvider#getGroovyClassLoader(org.exoplatform.services.rest.ext.groovy.ClassPathEntry[])
+ */
+ @Override
+ public GroovyClassLoader getGroovyClassLoader(ClassPathEntry[] classPath) throws MalformedURLException
+ {
+ List<URL> files = new ArrayList<URL>();
+ List<URL> roots = new ArrayList<URL>();
+ for (int i = 0; i < classPath.length; i++)
+ {
+ ClassPathEntry classPathEntry = classPath[i];
+ if (EntryType.SRC_DIR == classPathEntry.getType())
+ {
+ roots.add(classPathEntry.getPath());
+ }
+ else
+ {
+ files.add(classPathEntry.getPath());
+ }
+ }
+ final GroovyClassLoader parent = getGroovyClassLoader();
+ GroovyClassLoader classLoader = AccessController.doPrivileged(new PrivilegedAction<GroovyClassLoader>() {
+ public GroovyClassLoader run()
+ {
+ return new GroovyClassLoader(parent);
+ }
+ });
+ classLoader.setResourceLoader(new JcrGroovyResourceLoader(roots.toArray(new URL[roots.size()]), files
+ .toArray(new URL[files.size()])));
+ return classLoader;
+ }
+}
\ No newline at end of file
Property changes on: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyClassLoaderProvider.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyCompiler.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyCompiler.java 2010-12-22 10:15:37 UTC (rev 3701)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyCompiler.java 2010-12-22 10:24:13 UTC (rev 3702)
@@ -23,22 +23,23 @@
import groovy.lang.GroovyCodeSource;
import org.codehaus.groovy.control.CompilationFailedException;
-import org.exoplatform.commons.utils.SecurityHelper;
-import org.exoplatform.container.component.ComponentPlugin;
import org.exoplatform.services.jcr.ext.resource.JcrURLConnection;
import org.exoplatform.services.jcr.ext.resource.UnifiedNodeReference;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
+import org.exoplatform.services.rest.ext.groovy.ClassPathEntry;
+import org.exoplatform.services.rest.ext.groovy.ClassPathEntry.EntryType;
+import org.exoplatform.services.rest.ext.groovy.GroovyClassLoaderProvider;
import org.picocontainer.Startable;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
+import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
-import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -46,7 +47,7 @@
/**
* JcrGroovyCompiler can load source code of groovy script from JCR and parse it
* via GroovyClassLoader.
- *
+ *
* @author <a href="mailto:andrew00x at gmail.com">Andrey Parfonov</a>
* @version $Id$
*/
@@ -55,36 +56,43 @@
/** Logger. */
private static final Log LOG = ExoLogger.getLogger(JcrGroovyCompiler.class);
- protected GroovyClassLoader gcl;
+ protected final GroovyClassLoaderProvider classLoaderProvider;
protected List<GroovyScriptAddRepoPlugin> addRepoPlugins;
- public JcrGroovyCompiler()
+ protected JcrGroovyCompiler(GroovyClassLoaderProvider classLoaderProvider)
{
- this.gcl = SecurityHelper.doPriviledgedAction(new PrivilegedAction<GroovyClassLoader>()
- {
- public GroovyClassLoader run()
- {
- return new GroovyClassLoader(getClass().getClassLoader());
- }
- });
+ this.classLoaderProvider = classLoaderProvider;
}
- public void addPlugin(ComponentPlugin cp)
+ public JcrGroovyCompiler()
{
- if (cp instanceof GroovyScriptAddRepoPlugin)
- {
- if (addRepoPlugins == null)
- {
- addRepoPlugins = new ArrayList<GroovyScriptAddRepoPlugin>();
- }
- addRepoPlugins.add((GroovyScriptAddRepoPlugin)cp);
- }
+ classLoaderProvider = new JcrGroovyClassLoaderProvider();
}
public Class<?>[] compile(UnifiedNodeReference... sourceReferences) throws IOException
{
- final GroovyClassLoader cl = getGroovyClassLoader();
+ // Add all compiled entries in class-path. Need to do this to resolve dependencies between compiled files.
+ ClassPathEntry[] classPath = new ClassPathEntry[sourceReferences.length];
+ for (int i = 0; i < classPath.length; i++)
+ classPath[i] = new JcrClassPathEntry(EntryType.FILE, sourceReferences[i]);
+ return doCompile(classLoaderProvider.getGroovyClassLoader(classPath), sourceReferences);
+ }
+
+ public Class<?>[] compile(ClassPathEntry[] classPath, UnifiedNodeReference... sourceReferences) throws IOException
+ {
+ ClassPathEntry[] compiled = new ClassPathEntry[sourceReferences.length];
+ for (int i = 0; i < compiled.length; i++)
+ compiled[i] = new JcrClassPathEntry(EntryType.FILE, sourceReferences[i]);
+ ClassPathEntry[] fullClassPath = new ClassPathEntry[compiled.length + classPath.length];
+ System.arraycopy(compiled, 0, fullClassPath, 0, compiled.length);
+ System.arraycopy(classPath, 0, fullClassPath, compiled.length, classPath.length);
+ return doCompile(classLoaderProvider.getGroovyClassLoader(fullClassPath), sourceReferences);
+ }
+
+ private Class<?>[] doCompile(final GroovyClassLoader cl, final UnifiedNodeReference... sourceReferences)
+ throws IOException
+ {
Class<?>[] classes = new Class<?>[sourceReferences.length];
for (int i = 0; i < sourceReferences.length; i++)
{
@@ -98,8 +106,7 @@
Class<?> clazz;
try
{
- clazz = SecurityHelper.doPriviledgedExceptionAction(new PrivilegedExceptionAction<Class<?>>()
- {
+ clazz = AccessController.doPrivileged(new PrivilegedExceptionAction<Class<?>>() {
public Class<?> run() throws Exception
{
return cl.parseClass(createCodeSource(fConn.getInputStream(), url.toString()));
@@ -110,30 +117,20 @@
{
Throwable cause = pae.getCause();
if (cause instanceof CompilationFailedException)
- {
throw (CompilationFailedException)cause;
- }
else if (cause instanceof IOException)
- {
throw (IOException)cause;
- }
else if (cause instanceof RuntimeException)
- {
throw (RuntimeException)cause;
- }
else
- {
throw new RuntimeException(cause);
- }
}
classes[i] = clazz;
}
finally
{
if (conn != null)
- {
conn.disconnect();
- }
}
}
return classes;
@@ -142,24 +139,49 @@
/**
* @return get underling groovy class loader
*/
+ @Deprecated
public GroovyClassLoader getGroovyClassLoader()
{
- return gcl;
+ return classLoaderProvider.getGroovyClassLoader();
}
/**
* Set groovy class loader.
- *
+ *
* @param gcl groovy class loader
* @throws NullPointerException if <code>gcl == null</code>
*/
+ @Deprecated
public void setGroovyClassLoader(GroovyClassLoader gcl)
{
- if (gcl == null)
- throw new NullPointerException("GroovyClassLoader may not be null.");
- this.gcl = gcl;
+ classLoaderProvider.setGroovyClassLoader(gcl);
}
+ /**
+ * Create {@link GroovyCodeSource} from given stream and name. Code base
+ * 'file:/groovy/script' (default code base used for all Groovy classes) will
+ * be used.
+ *
+ * @param in groovy source code stream
+ * @param name code source name
+ * @return GroovyCodeSource
+ */
+ // Override this method if need other behavior.
+ protected GroovyCodeSource createCodeSource(final InputStream in, final String name)
+ {
+ GroovyCodeSource gcs = AccessController.doPrivileged(new PrivilegedAction<GroovyCodeSource>() {
+ public GroovyCodeSource run()
+ {
+ return new GroovyCodeSource(in, name, "/groovy/script");
+ }
+ });
+ gcs.setCachable(false);
+ return gcs;
+ }
+
+ /**
+ * @see org.picocontainer.Startable#start()
+ */
public void start()
{
if (addRepoPlugins != null && addRepoPlugins.size() > 0)
@@ -168,10 +190,9 @@
{
Set<URL> repos = new HashSet<URL>();
for (GroovyScriptAddRepoPlugin pl : addRepoPlugins)
- {
repos.addAll(pl.getRepositories());
- }
- getGroovyClassLoader().setResourceLoader(new JcrGroovyResourceLoader(repos.toArray(new URL[repos.size()])));
+ classLoaderProvider.getGroovyClassLoader().setResourceLoader(
+ new JcrGroovyResourceLoader(repos.toArray(new URL[repos.size()])));
}
catch (MalformedURLException e)
{
@@ -180,31 +201,10 @@
}
}
- public void stop()
- {
- }
-
/**
- * Create {@link GroovyCodeSource} from given stream and name. Code base
- * 'file:/groovy/script' (default code base used for all Groovy classes) will
- * be used.
- *
- * @param in groovy source code stream
- * @param name code source name
- * @return GroovyCodeSource
+ * @see org.picocontainer.Startable#stop()
*/
- // Override this method if need other behavior.
- protected GroovyCodeSource createCodeSource(final InputStream in, final String name)
+ public void stop()
{
- GroovyCodeSource gcs = SecurityHelper.doPriviledgedAction(new PrivilegedAction<GroovyCodeSource>()
- {
- public GroovyCodeSource run()
- {
- return new GroovyCodeSource(in, name, "/groovy/script");
- }
- });
-
- gcs.setCachable(false);
- return gcs;
}
}
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyResourceLoader.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyResourceLoader.java 2010-12-22 10:15:37 UTC (rev 3701)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyResourceLoader.java 2010-12-22 10:24:13 UTC (rev 3702)
@@ -19,6 +19,8 @@
package org.exoplatform.services.jcr.ext.script.groovy;
import org.exoplatform.services.jcr.ext.resource.JcrURLConnection;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
import org.exoplatform.services.rest.ext.groovy.DefaultGroovyResourceLoader;
import java.io.IOException;
@@ -31,6 +33,7 @@
*/
public class JcrGroovyResourceLoader extends DefaultGroovyResourceLoader
{
+ private static final Log LOG = ExoLogger.getLogger(JcrGroovyResourceLoader.class);
private static URL[] normalizeJcrURL(URL[] src) throws MalformedURLException
{
@@ -58,72 +61,89 @@
return res;
}
+ public JcrGroovyResourceLoader(URL[] roots, URL[] files) throws MalformedURLException
+ {
+ super(normalizeJcrURL(roots), files);
+ }
+
public JcrGroovyResourceLoader(URL[] roots) throws MalformedURLException
{
- super(normalizeJcrURL(roots));
+ this(roots, new URL[0]);
}
+ public JcrGroovyResourceLoader(URL root) throws MalformedURLException
+ {
+ this(new URL[]{root}, new URL[0]);
+ }
+
+ /**
+ * @see org.exoplatform.services.rest.ext.groovy.DefaultGroovyResourceLoader#getResource(java.lang.String)
+ */
@Override
protected URL getResource(String filename) throws MalformedURLException
{
+ if (LOG.isDebugEnabled())
+ LOG.debug("Process file: " + filename);
+
+ URL resource = null;
filename = filename.intern();
- URL resource = null;
synchronized (filename)
{
resource = resources.get(filename);
boolean inCache = resource != null;
- for (URL root : roots)
+ if (inCache && !checkResource(resource))
+ resource = null;
+ for (int i = 0; i < files.length && resource == null; i++)
{
- if (resource == null)
- {
- if ("jcr".equals(root.getProtocol()))
- {
- // In JCR URL path represented by fragment
- // jcr://repository/workspace#/path
- String ref = root.getRef();
- resource = new URL(root, "#" + ref + filename);
- }
- else
- {
- resource = new URL(root, filename);
- }
- }
- URLConnection connection = null;
- try
- {
- if (GroovyScript2RestLoader.LOG.isDebugEnabled())
- GroovyScript2RestLoader.LOG.debug("Try to load resource from URL : " + resource);
-
- connection = resource.openConnection();
- connection.getInputStream().close();
-
- break;
- }
- catch (IOException e)
- {
- if (GroovyScript2RestLoader.LOG.isDebugEnabled())
- GroovyScript2RestLoader.LOG.debug("Can't open URL : " + resource);
-
- resource = null;
- }
- finally
- {
- if (connection != null && resource != null && "jcr".equals(resource.getProtocol()))
- {
- ((JcrURLConnection)connection).disconnect();
- }
- }
+ URL tmp = files[i];
+ if (tmp.toString().endsWith(filename) && checkResource(tmp))
+ resource = tmp;
}
+ for (int i = 0; i < roots.length && resource == null; i++)
+ {
+ // In JCR URL path represented by fragment jcr://repository/workspace#/path
+ URL tmp =
+ ("jcr".equals(roots[i].getProtocol())) ? new URL(roots[i], "#" + roots[i].getRef() + filename)
+ : new URL(roots[i], filename);
+ if (checkResource(tmp))
+ resource = tmp;
+ }
if (resource != null)
- {
resources.put(filename, resource);
- }
else if (inCache)
- {
- // Remove from map if resource is unreachable
resources.remove(filename);
- }
}
return resource;
}
+
+ /**
+ * @see org.exoplatform.services.rest.ext.groovy.DefaultGroovyResourceLoader#checkResource(java.net.URL)
+ */
+ @Override
+ protected boolean checkResource(URL resource)
+ {
+ URLConnection connection = null;
+ try
+ {
+ if (LOG.isDebugEnabled())
+ LOG.debug("Try to load resource from URL : " + resource);
+
+ connection = resource.openConnection();
+ connection.getInputStream().close();
+
+ return true;
+ }
+ catch (IOException e)
+ {
+ if (LOG.isDebugEnabled())
+ LOG.debug("Can't open URL : " + resource);
+
+ return false;
+ }
+ finally
+ {
+ if (connection != null && resource != null && "jcr".equals(resource.getProtocol()))
+ ((JcrURLConnection)connection).disconnect();
+ }
+ }
}
\ No newline at end of file
Added: jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/script/groovy/BaseGroovyTest.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/script/groovy/BaseGroovyTest.java (rev 0)
+++ jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/script/groovy/BaseGroovyTest.java 2010-12-22 10:24:13 UTC (rev 3702)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2010 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.ext.script.groovy;
+
+import org.exoplatform.services.jcr.ext.BaseStandaloneTest;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.Calendar;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+/**
+ * @author <a href="mailto:andrey.parfonov at exoplatform.com">Andrey Parfonov</a>
+ * @version $Id$
+ */
+public abstract class BaseGroovyTest extends BaseStandaloneTest
+{
+
+ @Override
+ public void setUp() throws Exception
+ {
+ super.setUp();
+ }
+
+ protected String createScript(Node parent, String packageName, String name, String text) throws RepositoryException
+ {
+ return createScript(parent, packageName, name, new ByteArrayInputStream(text.getBytes()));
+ }
+
+ protected String createScript(Node parent, String packageName, String name, InputStream text) throws RepositoryException
+ {
+ Node current = parent;
+ if (packageName != null && packageName.length() > 0)
+ {
+ for (String s : packageName.split("\\."))
+ {
+ if (!current.hasNode(s))
+ current = current.addNode(s, "nt:folder");
+ else
+ current = current.getNode(s);
+ }
+ }
+ Node script = current.addNode(name + ".groovy", "nt:file");
+ Node scriptContent = script.addNode("jcr:content", "nt:resource");
+ scriptContent.setProperty("jcr:mimeType", "script/groovy");
+ scriptContent.setProperty("jcr:lastModified", Calendar.getInstance());
+ scriptContent.setProperty("jcr:data", text);
+ session.save();
+ return script.getPath();
+ }
+}
Property changes on: jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/script/groovy/BaseGroovyTest.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Modified: jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyCompilerTest.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyCompilerTest.java 2010-12-22 10:15:37 UTC (rev 3701)
+++ jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyCompilerTest.java 2010-12-22 10:24:13 UTC (rev 3702)
@@ -21,56 +21,104 @@
import groovy.lang.GroovyObject;
-import org.exoplatform.services.jcr.ext.BaseStandaloneTest;
import org.exoplatform.services.jcr.ext.resource.UnifiedNodeReference;
+import org.exoplatform.services.rest.ext.groovy.ClassPathEntry;
+import org.exoplatform.services.rest.ext.groovy.GroovyClassLoaderProvider;
+import org.exoplatform.services.rest.ext.groovy.ClassPathEntry.EntryType;
-import java.util.Calendar;
-
import javax.jcr.Node;
/**
* @author <a href="mailto:andrew00x at gmail.com">Andrey Parfonov</a>
* @version $Id$
*/
-public class GroovyCompilerTest extends BaseStandaloneTest
+public class GroovyCompilerTest extends BaseGroovyTest
{
+ private Node groovyRepo;
+
+ private Node otherGroovyRepo;
+
+ private String scriptA;
+
+ private String scriptB;
+
public void setUp() throws Exception
{
super.setUp();
- Node groovyRepo = root.addNode("groovyRepo", "nt:folder");
- Node org = groovyRepo.addNode("org", "nt:folder");
- Node exo = org.addNode("exoplatform", "nt:folder");
- Node a = exo.addNode("A.groovy", "nt:file");
- a = a.addNode("jcr:content", "nt:resource");
- a.setProperty("jcr:mimeType", "script/groovy");
- a.setProperty("jcr:lastModified", Calendar.getInstance());
- a.setProperty("jcr:data", //
+ groovyRepo = root.addNode("groovyRepo", "nt:folder");
+ otherGroovyRepo = root.addNode("otherGroovyRepo", "nt:folder");
+
+ // Add script in shared "dependency repository".
+ scriptA = createScript(groovyRepo, "org.exoplatform", "A", //
"package org.exoplatform\n" + //
- " class A { String message = 'groovy compiler test' }");
+ "class A { String message = 'groovy compiler test' }");
- Node test = exo.addNode("test", "nt:folder");
- Node b = test.addNode("B.groovy", "nt:file");
- b = b.addNode("jcr:content", "nt:resource");
- b.setProperty("jcr:mimeType", "script/groovy");
- b.setProperty("jcr:lastModified", Calendar.getInstance());
- b.setProperty("jcr:data", //
+ scriptB = createScript(groovyRepo, "org.exoplatform.test", "B", //
"package org.exoplatform.test\n" + //
- " import org.exoplatform.A\n" + //
- " class B extends A {}");
- session.save();
+ "import org.exoplatform.A\n" + //
+ "class B extends A {}");
}
- public void testGroovyDependency() throws Exception
+ public void testSnaredDependencies() throws Exception
{
- JcrGroovyCompiler compiler = new JcrGroovyCompiler();
- compiler.getGroovyClassLoader().setResourceLoader(
+ GroovyClassLoaderProvider classLoaderProvider = new GroovyClassLoaderProvider();
+ classLoaderProvider.getGroovyClassLoader().setResourceLoader(
new JcrGroovyResourceLoader(new java.net.URL[]{new java.net.URL("jcr://db1/ws#/groovyRepo")}));
+ JcrGroovyCompiler compiler = new JcrGroovyCompiler(classLoaderProvider);
+
+ Class<?>[] classes = compiler.compile(new UnifiedNodeReference("db1", "ws", scriptB));
+ assertEquals(1, classes.length);
+ GroovyObject go = (GroovyObject)classes[0].newInstance();
+ assertEquals("groovy compiler test", go.invokeMethod("getMessage", new Object[0]));
+ }
+
+ public void testDependenciesBetweenCompiled() throws Exception
+ {
+ GroovyClassLoaderProvider classLoaderProvider = new GroovyClassLoaderProvider();
+ JcrGroovyCompiler compiler = new JcrGroovyCompiler(classLoaderProvider);
Class<?>[] classes =
- compiler.compile(new UnifiedNodeReference("db1", "ws", "/groovyRepo/org/exoplatform/test/B.groovy"));
+ compiler.compile(new UnifiedNodeReference("db1", "ws", scriptB),
+ new UnifiedNodeReference("db1", "ws", scriptA));
+ assertEquals(2, classes.length);
+ GroovyObject go = (GroovyObject)classes[0].newInstance();
+ assertEquals("groovy compiler test", go.invokeMethod("getMessage", new Object[0]));
+ go = (GroovyObject)classes[1].newInstance();
+ assertEquals("groovy compiler test", go.invokeMethod("getMessage", new Object[0]));
+ }
+
+ public void testAddDependenciesInRuntime() throws Exception
+ {
+ GroovyClassLoaderProvider classLoaderProvider = new GroovyClassLoaderProvider();
+ JcrGroovyCompiler compiler = new JcrGroovyCompiler(classLoaderProvider);
+ Class<?>[] classes = compiler.compile( //
+ new ClassPathEntry[]{new JcrClassPathEntry(EntryType.FILE, new UnifiedNodeReference("db1", "ws", scriptA))}, //
+ new UnifiedNodeReference("db1", "ws", scriptB));
assertEquals(1, classes.length);
GroovyObject go = (GroovyObject)classes[0].newInstance();
assertEquals("groovy compiler test", go.invokeMethod("getMessage", new Object[0]));
}
+ public void testCombinedDependencies() throws Exception
+ {
+ String scriptC = createScript(otherGroovyRepo, "org.exoplatform.test", "C", //
+ "package org.exoplatform.test\n" + //
+ "import org.exoplatform.*\n" + //
+ "class C extends B {}");
+
+ String scriptD = createScript(otherGroovyRepo, "org.exoplatform.test.other", "D", //
+ "package org.exoplatform.test.other\n" + //
+ "import org.exoplatform.test.C\n" + //
+ "class D extends C {}");
+
+ GroovyClassLoaderProvider classLoaderProvider = new GroovyClassLoaderProvider();
+ classLoaderProvider.getGroovyClassLoader().setResourceLoader(
+ new JcrGroovyResourceLoader(new java.net.URL[]{new java.net.URL("jcr://db1/ws#/groovyRepo")}));
+
+ JcrGroovyCompiler compiler = new JcrGroovyCompiler(classLoaderProvider);
+ Class<?>[] classes =
+ compiler.compile(new UnifiedNodeReference("db1", "ws", scriptD),
+ new UnifiedNodeReference("db1", "ws", scriptC));
+ assertEquals(2, classes.length);
+ }
}
Modified: jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyScript2RestLoaderTest.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyScript2RestLoaderTest.java 2010-12-22 10:15:37 UTC (rev 3701)
+++ jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyScript2RestLoaderTest.java 2010-12-22 10:24:13 UTC (rev 3702)
@@ -18,7 +18,6 @@
*/
package org.exoplatform.services.jcr.ext.script.groovy;
-import org.exoplatform.services.jcr.ext.BaseStandaloneTest;
import org.exoplatform.services.jcr.ext.app.ThreadLocalSessionProviderService;
import org.exoplatform.services.jcr.ext.common.SessionProvider;
import org.exoplatform.services.jcr.ext.registry.RESTRegistryTest.DummyContainerResponseWriter;
@@ -56,7 +55,7 @@
* @author <a href="mailto:andrew00x at gmail.com">Andrey Parfonov</a>
* @version $Id: $
*/
-public class GroovyScript2RestLoaderTest extends BaseStandaloneTest
+public class GroovyScript2RestLoaderTest extends BaseGroovyTest
{
private Node testRoot;
@@ -111,17 +110,16 @@
providers.addMethodInvokerFilter(new MethodAccessFilter());
session.save();
-
+
Set<String> adminRoles = new HashSet<String>();
adminRoles.add("administrators");
- adminSecurityContext = new DummySecurityContext(new Principal()
- {
+ adminSecurityContext = new DummySecurityContext(new Principal() {
public String getName()
{
return "root";
}
}, adminRoles);
-
+
}
public void testStartQuery() throws Exception
@@ -279,18 +277,13 @@
public void testGroovyDependency() throws Exception
{
// Add script in dependency repository
- Node deps = groovyRepo.addNode("dependencies", "nt:folder");
- Node dep = deps.addNode("Dep1.groovy", "nt:file");
- dep = dep.addNode("jcr:content", "nt:resource");
- dep.setProperty("jcr:mimeType", "script/groovy");
- dep.setProperty("jcr:lastModified", Calendar.getInstance());
- dep.setProperty("jcr:data", "package dependencies; class Dep1 { String name = getClass().getName() }");
+ createScript(groovyRepo, "dependencies", "Dep1", //
+ "package dependencies\n" + //
+ "class Dep1 { String name = getClass().getName() }");
- session.save();
+ script.setProperty("jcr:data",
+ Thread.currentThread().getContextClassLoader().getResourceAsStream("TestDependency.groovy"));
- script.setProperty("jcr:data", Thread.currentThread().getContextClassLoader().getResourceAsStream(
- "TestDependency.groovy"));
-
session.save();
// must be rebounded , not created other one
Modified: jcr/trunk/exo.jcr.component.ext/src/test/resources/conf/standalone/test-configuration.xml
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/test/resources/conf/standalone/test-configuration.xml 2010-12-22 10:15:37 UTC (rev 3701)
+++ jcr/trunk/exo.jcr.component.ext/src/test/resources/conf/standalone/test-configuration.xml 2010-12-22 10:24:13 UTC (rev 3702)
@@ -40,7 +40,7 @@
<property name="log4j.rootLogger" value="INFO, stdout, file" />
<property name="log4j.appender.stdout" value="org.apache.log4j.ConsoleAppender" />
- <property name="log4j.appender.stdout.threshold" value="INFO" />
+ <property name="log4j.appender.stdout.threshold" value="DEBUG" />
<property name="log4j.appender.stdout.layout" value="org.apache.log4j.PatternLayout" />
<property name="log4j.appender.stdout.layout.ConversionPattern" value="%d{dd.MM.yyyy HH:mm:ss} *%-5p* [%t] %c{1}: %m (%F, line %L) %n" />
@@ -55,6 +55,8 @@
<property name="log4j.category.ext.BackupManagerImpl" value="DEBUG"/ -->
<property name="log4j.category.jcr.ext.RestRepositoryService" value="DEBUG"/>
+ <!-- property name="log4j.category.org.exoplatform.services.jcr.ext.script.groovy.JcrGroovyResourceLoader" value="DEBUG" / -->
+
</properties-param>
</init-params>
</component>
More information about the exo-jcr-commits
mailing list