Author: aparfonov
Date: 2010-12-23 10:06:33 -0500 (Thu, 23 Dec 2010)
New Revision: 3720
Added:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/BaseGroovyScriptManager.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/GroovyScript2RestUpdateListener.java
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/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/main/java/org/exoplatform/services/jcr/ext/script/groovy/NodeScriptKey.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/SimpleScriptKey.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/URLScriptKey.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/XMLGroovyScript2Rest.java
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/GroovyCompilerTest.java
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyScript2RestLoaderTest.java
Log:
EXOJCR-1105
Added:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/BaseGroovyScriptManager.java
===================================================================
---
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/BaseGroovyScriptManager.java
(rev 0)
+++
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/BaseGroovyScriptManager.java 2010-12-23
15:06:33 UTC (rev 3720)
@@ -0,0 +1,138 @@
+/*
+ * 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.rest.ext.groovy.GroovyJaxrsPublisher;
+import org.exoplatform.services.rest.ext.groovy.ResourceId;
+import org.exoplatform.services.rest.impl.ResourcePublicationException;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.List;
+
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+
+/**
+ * @author <a href="mailto:andrey.parfonov@exoplatform.com">Andrey
Parfonov</a>
+ * @version $Id$
+ * @deprecated
+ */
+// Contains all method what we do not need any more in GroovyScript2RestLoader
+// but need to keep for back compatibility.
+public abstract class BaseGroovyScriptManager
+{
+ protected GroovyJaxrsPublisher groovyPublisher;
+
+ public BaseGroovyScriptManager(GroovyJaxrsPublisher groovyPublisher)
+ {
+ this.groovyPublisher = groovyPublisher;
+ }
+
+ public boolean isLoaded(ScriptKey key)
+ {
+ return groovyPublisher.isPublished(key);
+ }
+
+ public boolean isLoaded(String key)
+ {
+ return isLoaded(new SimpleScriptKey(key));
+ }
+
+ public boolean isLoaded(URL url)
+ {
+ return isLoaded(new URLScriptKey(url));
+ }
+
+ public Response load(String repository, String workspace, String path, boolean state)
+ {
+ return load(repository, workspace, path, state, null);
+ }
+
+ public abstract Response load(String repository, String workspace, String path,
boolean state, List<String> sources,
+ List<String> files, List<String> extensions, MultivaluedMap<String,
String> properties);
+
+ public Response load(String repository, String workspace, String path, boolean state,
+ MultivaluedMap<String, String> properties)
+ {
+ return load(repository, workspace, path, state, null, null, null, properties);
+ }
+
+ public boolean loadScript(ScriptKey key, String name, InputStream stream) throws
IOException
+ {
+ try
+ {
+ groovyPublisher.publishPerRequest(stream, key, null);
+ return true;
+ }
+ catch (ResourcePublicationException e)
+ {
+ return false;
+ }
+ }
+
+ public boolean loadScript(String key, InputStream stream) throws IOException
+ {
+ return loadScript(key, null, stream);
+ }
+
+ public boolean loadScript(String key, String name, InputStream stream) throws
IOException
+ {
+ return loadScript(new SimpleScriptKey(key), name, stream);
+ }
+
+ public boolean loadScript(URL url) throws IOException
+ {
+ ResourceId key = new URLScriptKey(url);
+ try
+ {
+ groovyPublisher.publishPerRequest(new BufferedInputStream(url.openStream()),
key, null);
+ return true;
+ }
+ catch (ResourcePublicationException e)
+ {
+ return true;
+ }
+ }
+
+ public boolean unloadScript(ScriptKey key)
+ {
+ return null != groovyPublisher.unpublishResource(key);
+ }
+
+ public boolean unloadScript(String key)
+ {
+ return unloadScript(new SimpleScriptKey(key));
+ }
+
+ public void unloadScript(URL url)
+ {
+ unloadScript(new URLScriptKey(url));
+ }
+
+ public Response validateScript(String name, final InputStream script)
+ {
+ return validateScript(name, script, null, null, null);
+ }
+
+ public abstract Response validateScript(String name, InputStream script,
List<String> sources, List<String> files,
+ List<String> extensions);
+}
Property changes on:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/BaseGroovyScriptManager.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/GroovyScript2RestLoader.java
===================================================================
---
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyScript2RestLoader.java 2010-12-23
15:04:43 UTC (rev 3719)
+++
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyScript2RestLoader.java 2010-12-23
15:06:33 UTC (rev 3720)
@@ -18,9 +18,8 @@
*/
package org.exoplatform.services.jcr.ext.script.groovy;
-import groovy.lang.GroovyClassLoader;
-
import org.apache.commons.fileupload.FileItem;
+import org.codehaus.groovy.control.CompilationFailedException;
import org.exoplatform.commons.utils.SecurityHelper;
import org.exoplatform.container.component.ComponentPlugin;
import org.exoplatform.container.configuration.ConfigurationManager;
@@ -33,21 +32,24 @@
import org.exoplatform.services.jcr.ext.common.SessionProvider;
import org.exoplatform.services.jcr.ext.registry.RegistryEntry;
import org.exoplatform.services.jcr.ext.registry.RegistryService;
+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.ClassPath;
+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.exoplatform.services.rest.ext.groovy.GroovyJaxrsPublisher;
+import org.exoplatform.services.rest.ext.groovy.MalformedScriptException;
import org.exoplatform.services.rest.ext.groovy.ResourceId;
import org.exoplatform.services.rest.impl.ResourceBinder;
import org.exoplatform.services.rest.impl.ResourcePublicationException;
-import org.exoplatform.services.rest.resource.ResourceContainer;
import org.exoplatform.services.script.groovy.GroovyScriptInstantiator;
import org.picocontainer.Startable;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
-import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
@@ -93,8 +95,9 @@
* @version $Id: GroovyScript2RestLoader.java 34445 2009-07-24 07:51:18Z
* dkatayev $
*/
+@SuppressWarnings("deprecation")
@Path("script/groovy")
-public class GroovyScript2RestLoader implements Startable
+public class GroovyScript2RestLoader extends BaseGroovyScriptManager implements
Startable
{
protected static class InnerGroovyJaxrsPublisher extends GroovyJaxrsPublisher
{
@@ -132,7 +135,7 @@
/** Keeps configuration for observation listener. */
private ObservationListenerConfiguration observationListenerConfiguration;
- protected GroovyJaxrsPublisher groovyPublisher;
+ //protected GroovyJaxrsPublisher groovyPublisher;
protected List<GroovyScript2RestLoaderPlugin> loadPlugins;
@@ -186,6 +189,7 @@
ConfigurationManager configurationManager, RegistryService registryService,
GroovyJaxrsPublisher groovyPublisher,
org.exoplatform.services.jcr.ext.resource.jcr.Handler jcrUrlHandler, InitParams
params)
{
+ super(groovyPublisher);
this.binder = binder;
this.repositoryService = repositoryService;
this.configurationManager = configurationManager;
@@ -196,72 +200,6 @@
}
/**
- * Remove script with specified URL from ResourceBinder.
- *
- * @param url the URL. The <code>url.toString()</code> must be
corresponded
- * to script class.
- * @see GroovyScriptRestLoader#loadScript(URL).
- * @deprecated
- */
- public void unloadScript(URL url)
- {
- unloadScript(new URLScriptKey(url));
- }
-
- /**
- * 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)
- * @deprecated
- */
- public boolean unloadScript(String key)
- {
- return unloadScript(new SimpleScriptKey(key));
- }
-
- /**
- * @param key
- * @return
- * @deprecated
- */
- public boolean unloadScript(ScriptKey key)
- {
- return null != groovyPublisher.unpublishResource(key);
- }
-
- /**
- * @param key script's key
- * @return true if script loaded false otherwise
- * @deprecated
- */
- public boolean isLoaded(String key)
- {
- return isLoaded(new SimpleScriptKey(key));
- }
-
- /**
- * @param url script's URL
- * @return true if script loaded false otherwise
- * @deprecated
- */
- public boolean isLoaded(URL url)
- {
- return isLoaded(new URLScriptKey(url));
- }
-
- /**
- * @param key script's key. With this key script was created.
- * @return true if script loaded false otherwise
- * @deprecated
- */
- public boolean isLoaded(ScriptKey key)
- {
- return groovyPublisher.isPublished(key);
- }
-
- /**
* Get node type for store scripts, may throw {@link IllegalStateException}
* if <tt>nodeType</tt> not initialized yet.
*
@@ -277,80 +215,8 @@
}
/**
- * @param url the URL for loading script.
- * @throws IOException it script can't be loaded.
- * @deprecated
+ * @see org.picocontainer.Startable#start()
*/
- public boolean loadScript(URL url) throws IOException
- {
- ResourceId key = new URLScriptKey(url);
- try
- {
- groovyPublisher.publishPerRequest(new BufferedInputStream(url.openStream()),
key, null);
- return true;
- }
- catch (ResourcePublicationException e)
- {
- return true;
- }
- }
-
- /**
- * 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
- * @throws IOException if script can't be loaded or parsed.
- * @see ResourceBinder#bind(ResourceContainer)
- * @deprecated
- */
- public boolean loadScript(String key, InputStream stream) throws IOException
- {
- return loadScript(key, null, stream);
- }
-
- /**
- * 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
- * @param stream the stream which represents groovy script.
- * @return if script loaded false otherwise
- * @throws IOException if script can't be loaded or parsed.
- * @see ResourceBinder#bind(ResourceContainer)
- * @deprecated
- */
- public boolean loadScript(String key, String name, InputStream stream) throws
IOException
- {
- return loadScript(new SimpleScriptKey(key), name, stream);
- }
-
- /**
- * @param key the key which must be corresponded to object class name
- * @param name script name
- * @param stream the stream which represents groovy script.
- * @return if script loaded false otherwise
- * @throws IOException if script can't be loaded or parsed
- * @deprecated
- */
- public boolean loadScript(ScriptKey key, String name, InputStream stream) throws
IOException
- {
- try
- {
- groovyPublisher.publishPerRequest(stream, key, null);
- return true;
- }
- catch (ResourcePublicationException e)
- {
- return false;
- }
- }
-
- /**
- * {@inheritDoc}
- */
public void start()
{
if (registryService != null && initParams != null &&
!registryService.getForceXMLConfigurationValue(initParams))
@@ -431,8 +297,19 @@
continue;
}
-
this.groovyPublisher.publishPerRequest(node.getProperty("jcr:data").getStream(),
new NodeScriptKey(
- repositoryName, workspaceName, node), null);
+ try
+ {
+
groovyPublisher.publishPerRequest(node.getProperty("jcr:data").getStream(), new
NodeScriptKey(
+ repositoryName, workspaceName, node), null);
+ }
+ catch (CompilationFailedException e)
+ {
+ LOG.error(e.getMessage(), e);
+ }
+ catch (ResourcePublicationException e)
+ {
+ LOG.error(e.getMessage(), e);
+ }
}
session
@@ -458,16 +335,13 @@
}
/**
- * {@inheritDoc}
+ * @see org.picocontainer.Startable#stop()
*/
public void stop()
{
// nothing to do!
}
- /**
- * @param cp See {@link ComponentPlugin}
- */
public void addPlugin(ComponentPlugin cp)
{
if (cp instanceof GroovyScript2RestLoaderPlugin)
@@ -593,7 +467,6 @@
protected void readParamsFromRegistryService(SessionProvider sessionProvider) throws
PathNotFoundException,
RepositoryException
{
-
if (LOG.isDebugEnabled())
{
LOG.debug("<<< Read init parametrs from registry service.");
@@ -743,6 +616,8 @@
}
}
+ ////////////////////////////////////////////////////////////////////////////////////
+
/**
* This method is useful for clients that can send script in request body
* without form-data. At required to set specific Content-type header
@@ -795,52 +670,14 @@
}
/**
- * @param name script name
- * @param stream script for validation
- */
- @POST
- @Consumes({"script/groovy"})
- @Path("validate{name:.*}")
- public Response validateScript(@PathParam("name") String name, final
InputStream script)
- {
-
- final GroovyClassLoader groovyClassLoader =
groovyPublisher.getGroovyClassLoader();
- if (name == null || name.length() == 0)
- {
- name = groovyClassLoader.generateScriptName();
- }
- else if (name.startsWith("/"))
- {
- name = name.substring(1);
- }
-
- try
- {
- final String fName = name;
- SecurityHelper.doPrivilegedExceptionAction(new
PrivilegedExceptionAction<Void>() {
- public Void run() throws Exception
- {
- groovyClassLoader.parseClass(script, fName);
- return null;
- }
- });
-
- return Response.status(Response.Status.OK).build();
- }
- catch (Exception e)
- {
- LOG.error(e.getMessage(), e);
- return
Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).type(MediaType.TEXT_PLAIN).build();
- }
-
- }
-
- /**
- * 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'.
+ * This method is useful for clients that send scripts as file in
+ * 'multipart/*' request body. <br/>
+ * NOTE even we use iterator item should be only one, rule one address - one
+ * 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 stream the stream that contains groovy source code
+ * @param items iterator {@link FileItem}
* @param uriInfo see {@link UriInfo}
* @param repository repository name
* @param workspace workspace name
@@ -848,9 +685,9 @@
* @return Response with status 'created'
*/
@POST
- @Consumes({"script/groovy"})
- @Path("update/{repository}/{workspace}/{path:.*}")
- public Response updateScript(InputStream stream, @Context UriInfo uriInfo,
+ @Consumes({"multipart/*"})
+ @Path("add/{repository}/{workspace}/{path:.*}")
+ public Response addScript(Iterator<FileItem> items, @Context UriInfo uriInfo,
@PathParam("repository") String repository,
@PathParam("workspace") String workspace,
@PathParam("path") String path)
{
@@ -860,8 +697,24 @@
ses =
sessionProviderService.getSessionProvider(null).getSession(workspace,
repositoryService.getRepository(repository));
- Node node = (Node)ses.getItem("/" + path);
- node.getNode("jcr:content").setProperty("jcr:data",
stream);
+ Node node = (Node)ses.getItem(getPath(path));
+ InputStream stream = null;
+ boolean autoload = false;
+ while (items.hasNext())
+ {
+ FileItem fitem = items.next();
+ if (fitem.isFormField() && fitem.getFieldName() != null
+ && fitem.getFieldName().equalsIgnoreCase("autoload"))
+ {
+ autoload = Boolean.valueOf(fitem.getString());
+ }
+ else if (!fitem.isFormField())
+ {
+ stream = fitem.getInputStream();
+ }
+ }
+
+ createScript(node, getName(path), autoload, stream);
ses.save();
URI location = uriInfo.getBaseUriBuilder().path(getClass(),
"getScript").build(repository, workspace, path);
return Response.created(location).build();
@@ -888,14 +741,76 @@
}
/**
- * This method is useful for clients that send scripts as file in
- * 'multipart/*' request body. <br/>
- * NOTE even we use iterator item should be only one, rule one address - one
- * 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.
+ * Check is specified source <code>script</code> contains valid Groovy
source
+ * code.
*
- * @param items iterator {@link FileItem}
+ * @param name script name. This name will be used by GroovyClassLoader to
+ * identify script, e.g. specified name will be used in error
+ * message in compilation of Groovy fails. If this parameter is
+ * <code>null</code> then GroovyClassLoader will use
automatically
+ * generated name
+ * @param script Groovy source stream
+ * @param sources locations (URL) of source folders that should be add in
+ * class path when compile Groovy script
+ * @param files locations (URL) of source files that should be add in class
+ * path when compile Groovy script
+ * @param extensions extensions of files from source folders that should be
+ * added in class path. By default only files with .groovy
+ * extension are processed. Extensions must be set in form
+ * '.{extensions}'
+ * @return Response with corresponded status. 200 if source code is valid
+ */
+ @POST
+ @Consumes({"script/groovy"})
+ @Path("validate{name:.*}")
+ public Response validateScript(@PathParam("name") String name, final
InputStream script,
+ @QueryParam("sources") List<String> sources,
@QueryParam("file") List<String> files,
+ @QueryParam("extension") List<String> extensions)
+ {
+ try
+ {
+ validateScript(name, script, createClassPath(sources, files, extensions));
+ return Response.ok().build();
+ }
+ catch (MalformedScriptException e)
+ {
+ LOG.error(e.getMessage(), e);
+ return
Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).type(MediaType.TEXT_PLAIN).build();
+ }
+ catch (MalformedURLException e)
+ {
+ LOG.error(e.getMessage(), e);
+ return
Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).type(MediaType.TEXT_PLAIN).build();
+ }
+ }
+
+ /**
+ * Check is specified source <code>script</code> contains valid Groovy
source
+ * code.
+ *
+ * @param name script name. This name will be used by GroovyClassLoader to
+ * identify script, e.g. specified name will be used in error
+ * message in compilation of Groovy fails. If this parameter is
+ * <code>null</code> then GroovyClassLoader will use
automatically
+ * generated name
+ * @param script Groovy source stream
+ * @param classPath class path
+ * @throws MalformedScriptException if <code>script</code> contains not
valid
+ * source code
+ */
+ public void validateScript(String name, InputStream script, ClassPath classPath)
throws MalformedScriptException
+ {
+ if (name != null && name.length() > 0 &&
name.startsWith("/"))
+ name = name.substring(1);
+ groovyPublisher.validateResource(script, name, classPath);
+ }
+
+ /**
+ * 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
* @param workspace workspace name
@@ -903,9 +818,9 @@
* @return Response with status 'created'
*/
@POST
- @Consumes({"multipart/*"})
- @Path("add/{repository}/{workspace}/{path:.*}")
- public Response addScript(Iterator<FileItem> items, @Context UriInfo uriInfo,
+ @Consumes({"script/groovy"})
+ @Path("update/{repository}/{workspace}/{path:.*}")
+ public Response updateScript(InputStream stream, @Context UriInfo uriInfo,
@PathParam("repository") String repository,
@PathParam("workspace") String workspace,
@PathParam("path") String path)
{
@@ -915,24 +830,8 @@
ses =
sessionProviderService.getSessionProvider(null).getSession(workspace,
repositoryService.getRepository(repository));
- Node node = (Node)ses.getItem(getPath(path));
- InputStream stream = null;
- boolean autoload = false;
- while (items.hasNext())
- {
- FileItem fitem = items.next();
- if (fitem.isFormField() && fitem.getFieldName() != null
- && fitem.getFieldName().equalsIgnoreCase("autoload"))
- {
- autoload = Boolean.valueOf(fitem.getString());
- }
- else if (!fitem.isFormField())
- {
- stream = fitem.getInputStream();
- }
- }
-
- createScript(node, getName(path), autoload, stream);
+ Node node = (Node)ses.getItem("/" + path);
+ node.getNode("jcr:content").setProperty("jcr:data",
stream);
ses.save();
URI location = uriInfo.getBaseUriBuilder().path(getClass(),
"getScript").build(repository, workspace, path);
return Response.created(location).build();
@@ -1020,35 +919,105 @@
}
/**
- * Get source code of groovy script.
+ * Deploy groovy script as REST service. If this property set to 'true' then
+ * 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 JCR path to node that contains script
- * @return groovy script as stream
+ * @param path the path to JCR node that contains groovy script to be
+ * 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>
+ * @param sources locations (URL) of source folders that should be add in
+ * class path when compile Groovy script
+ * @param files locations (URL) of source files that should be add in class
+ * path when compile Groovy script
+ * @param extensions extensions of files from source folders that should be
+ * added in class path. By default only files with .groovy
+ * extension are processed. Extensions must be set in form
+ * '.{extensions}'
+ * @param properties optional properties to be applied to loaded resource.
+ * Ignored if <code>state</code> parameter is false
*/
@POST
- @Produces({"script/groovy"})
- @Path("src/{repository}/{workspace}/{path:.*}")
- public Response getScript(@PathParam("repository") String repository,
@PathParam("workspace") String workspace,
- @PathParam("path") String path)
+ @Path("load/{repository}/{workspace}/{path:.*}")
+ @RolesAllowed({"administrators"})
+ public Response load(@PathParam("repository") String repository,
@PathParam("workspace") String workspace,
+ @PathParam("path") String path, @DefaultValue("true")
@QueryParam("state") boolean state,
+ @QueryParam("sources") List<String> sources,
@QueryParam("file") List<String> files,
+ @QueryParam("extension") List<String> extensions,
MultivaluedMap<String, String> properties)
{
+ try
+ {
+ return load(repository, workspace, path, state, properties,
createClassPath(sources, files, extensions));
+ }
+ catch (MalformedURLException e)
+ {
+ LOG.error(e.getMessage(), e);
+ return
Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).type(MediaType.TEXT_PLAIN).build();
+ }
+ }
+
+ /**
+ * Deploy groovy script as REST service. If this property set to 'true' then
+ * 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
+ * @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>
+ * @param properties optional properties to be applied to loaded resource.
+ * Ignored if <code>state</code> parameter is false
+ * @param classPath class path
+ */
+ public Response load(String repository, String workspace, String path, boolean state,
+ MultivaluedMap<String, String> properties, ClassPath classPath)
+ {
Session ses = null;
try
{
ses =
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();
+ Node script = ((Node)ses.getItem("/" +
path)).getNode("jcr:content");
+ ResourceId key = new NodeScriptKey(repository, workspace, script);
+ if (state)
+ {
+ groovyPublisher.unpublishResource(key);
+
groovyPublisher.publishPerRequest(script.getProperty("jcr:data").getStream(),
key, properties, classPath);
+ }
+ else
+ {
+ 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.NO_CONTENT).build();
}
+ catch (CompilationFailedException e)
+ {
+ return
Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).type(MediaType.TEXT_PLAIN).build();
+ }
+ catch (ResourcePublicationException e)
+ {
+ return
Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).type(MediaType.TEXT_PLAIN).build();
+ }
catch (PathNotFoundException e)
{
String msg = "Path " + path + " does not exists";
LOG.error(msg);
- return
Response.status(Response.Status.NOT_FOUND).entity(msg).entity(MediaType.TEXT_PLAIN).build();
+ return
Response.status(Response.Status.NOT_FOUND).entity(msg).type(MediaType.TEXT_PLAIN).build();
}
catch (Exception e)
{
@@ -1066,18 +1035,16 @@
}
/**
- * Get groovy script's meta-information.
+ * Remove node that contains groovy script.
*
* @param repository repository name
* @param workspace workspace name
* @param path JCR path to node that contains script
- * @return groovy script's meta-information
*/
@POST
- @Produces({MediaType.APPLICATION_JSON})
- @Path("meta/{repository}/{workspace}/{path:.*}")
- public Response getScriptMetadata(@PathParam("repository") String
repository,
- @PathParam("workspace") String workspace, @PathParam("path")
String path)
+ @Path("delete/{repository}/{workspace}/{path:.*}")
+ public Response deleteScript(@PathParam("repository") String repository,
@PathParam("workspace") String workspace,
+ @PathParam("path") String path)
{
Session ses = null;
try
@@ -1085,14 +1052,9 @@
ses =
sessionProviderService.getSessionProvider(null).getSession(workspace,
repositoryService.getRepository(repository));
- Node script = ((Node)ses.getItem("/" +
path)).getNode("jcr:content");
- ResourceId key = new NodeScriptKey(repository, workspace, script);
-
- ScriptMetadata meta = new
ScriptMetadata(script.getProperty("exo:autoload").getBoolean(), //
- groovyPublisher.isPublished(key), //
- script.getProperty("jcr:mimeType").getString(), //
-
script.getProperty("jcr:lastModified").getDate().getTimeInMillis());
- return
Response.status(Response.Status.OK).entity(meta).type(MediaType.APPLICATION_JSON).build();
+ ses.getItem("/" + path).remove();
+ ses.save();
+ return Response.status(Response.Status.NO_CONTENT).build();
}
catch (PathNotFoundException e)
{
@@ -1116,16 +1078,22 @@
}
/**
- * Remove node that contains groovy script.
+ * 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
*/
@POST
- @Path("delete/{repository}/{workspace}/{path:.*}")
- public Response deleteScript(@PathParam("repository") String repository,
@PathParam("workspace") String workspace,
- @PathParam("path") String path)
+ @Path("autoload/{repository}/{workspace}/{path:.*}")
+ public Response autoload(@PathParam("repository") String repository,
@PathParam("workspace") String workspace,
+ @PathParam("path") String path, @DefaultValue("true")
@QueryParam("state") boolean state)
{
Session ses = null;
try
@@ -1133,7 +1101,8 @@
ses =
sessionProviderService.getSessionProvider(null).getSession(workspace,
repositoryService.getRepository(repository));
- ses.getItem("/" + path).remove();
+ Node script = ((Node)ses.getItem("/" +
path)).getNode("jcr:content");
+ script.setProperty("exo:autoload", state);
ses.save();
return Response.status(Response.Status.NO_CONTENT).build();
}
@@ -1159,22 +1128,18 @@
}
/**
- * 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.
+ * Get source code of groovy script.
*
* @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
+ * @return groovy script as stream
*/
@POST
- @Path("autoload/{repository}/{workspace}/{path:.*}")
- public Response autoload(@PathParam("repository") String repository,
@PathParam("workspace") String workspace,
- @PathParam("path") String path, @DefaultValue("true")
@QueryParam("state") boolean state)
+ @Produces({"script/groovy"})
+ @Path("src/{repository}/{workspace}/{path:.*}")
+ public Response getScript(@PathParam("repository") String repository,
@PathParam("workspace") String workspace,
+ @PathParam("path") String path)
{
Session ses = null;
try
@@ -1182,10 +1147,10 @@
ses =
sessionProviderService.getSessionProvider(null).getSession(workspace,
repositoryService.getRepository(repository));
- Node script = ((Node)ses.getItem("/" +
path)).getNode("jcr:content");
- script.setProperty("exo:autoload", state);
- ses.save();
- return Response.status(Response.Status.NO_CONTENT).build();
+ 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();
}
catch (PathNotFoundException e)
{
@@ -1209,27 +1174,18 @@
}
/**
- * Deploy groovy script as REST service. If this property set to 'true' then
- * 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.
+ * Get groovy script's meta-information.
*
* @param repository repository name
* @param workspace workspace name
- * @param path the path to JCR node that contains groovy script to be
- * 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>
- * @param properties optional properties to be applied to loaded resource.
- * Ignored if <code>state</code> parameter is false
+ * @param path JCR path to node that contains script
+ * @return groovy script's meta-information
*/
@POST
- @Path("load/{repository}/{workspace}/{path:.*}")
- @RolesAllowed({"administrators"})
- public Response load(@PathParam("repository") String repository,
@PathParam("workspace") String workspace,
- @PathParam("path") String path, @DefaultValue("true")
@QueryParam("state") boolean state,
- MultivaluedMap<String, String> properties)
+ @Produces({MediaType.APPLICATION_JSON})
+ @Path("meta/{repository}/{workspace}/{path:.*}")
+ public Response getScriptMetadata(@PathParam("repository") String
repository,
+ @PathParam("workspace") String workspace, @PathParam("path")
String path)
{
Session ses = null;
try
@@ -1239,32 +1195,19 @@
repositoryService.getRepository(repository));
Node script = ((Node)ses.getItem("/" +
path)).getNode("jcr:content");
ResourceId key = new NodeScriptKey(repository, workspace, script);
- if (state)
- {
- groovyPublisher.unpublishResource(key);
-
groovyPublisher.publishPerRequest(script.getProperty("jcr:data").getStream(),
key, properties);
- }
- else
- {
- 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.NO_CONTENT).build();
+
+ ScriptMetadata meta = new
ScriptMetadata(script.getProperty("exo:autoload").getBoolean(), //
+ groovyPublisher.isPublished(key), //
+ script.getProperty("jcr:mimeType").getString(), //
+
script.getProperty("jcr:lastModified").getDate().getTimeInMillis());
+ return
Response.status(Response.Status.OK).entity(meta).type(MediaType.APPLICATION_JSON).build();
}
catch (PathNotFoundException e)
{
String msg = "Path " + path + " does not exists";
LOG.error(msg);
- return
Response.status(Response.Status.NOT_FOUND).entity(msg).type(MediaType.TEXT_PLAIN).build();
+ return
Response.status(Response.Status.NOT_FOUND).entity(msg).entity(MediaType.TEXT_PLAIN).build();
}
- catch (ResourcePublicationException e)
- {
- return
Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).type(MediaType.TEXT_PLAIN).build();
- }
catch (Exception e)
{
LOG.error(e.getMessage(), e);
@@ -1280,21 +1223,15 @@
}
}
- @Deprecated
- public Response load(String repository, String workspace, String path, boolean state)
- {
- return load(repository, workspace, path, state, null);
- }
-
/**
* 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
+ * @param repository repository name
+ * @param workspace workspace name
+ * @param name additional search parameter. If not empty method returns the
* list of script names matching wildcard else returns all the
* scripts found in workspace.
- * @return
+ * @return list of groovy services
*/
@POST
@Produces(MediaType.APPLICATION_JSON)
@@ -1377,6 +1314,48 @@
}
}
+
///////////////////////////////////////////////////////////////////////////////////////
+
+ private ClassPath createClassPath(List<String> sources, List<String>
files, List<String> extensions)
+ throws MalformedURLException
+ {
+ if ((sources == null || sources.size() == 0) && (files == null ||
files.size() == 0)
+ && (extensions == null || extensions.size() == 0))
+ return null;
+
+ List<ClassPathEntry> classPathEntries = new
ArrayList<ClassPathEntry>();
+
+ if (sources != null && sources.size() > 0)
+ {
+ for (String src : sources)
+ {
+ if (src.startsWith("jcr://"))
+ classPathEntries.add(new JcrClassPathEntry(EntryType.SRC_DIR, new
URL(null, src, UnifiedNodeReference
+ .getURLStreamHandler())));
+ else
+ classPathEntries.add(new JcrClassPathEntry(EntryType.SRC_DIR, new
URL(src)));
+ }
+ }
+
+ if (files != null && files.size() > 0)
+ {
+ for (String file : files)
+ {
+ if (file.startsWith("jcr://"))
+ classPathEntries.add(new JcrClassPathEntry(EntryType.FILE, new URL(null,
file, UnifiedNodeReference
+ .getURLStreamHandler())));
+ else
+ classPathEntries.add(new JcrClassPathEntry(EntryType.FILE, new
URL(file)));
+ }
+ }
+
+ ClassPath classPath =
+ new ClassPath(classPathEntries.toArray(new
ClassPathEntry[classPathEntries.size()]),
+ (extensions != null && extensions.size() > 0) ?
extensions.toArray(new String[extensions.size()]) : null);
+
+ return classPath;
+ }
+
/**
* Extract path to node's parent from full path.
*
@@ -1406,7 +1385,6 @@
*/
public static class ScriptMetadata
{
-
/** Is script autoload. */
private final boolean autoload;
@@ -1465,13 +1443,10 @@
*/
public static class ScriptList
{
-
/** The list of scripts. */
private List<String> list;
/**
- * Returns the list of scripts.
- *
* @return the list of scripts.
*/
public List<String> getList()
@@ -1480,14 +1455,11 @@
}
/**
- * ScriptList constructor.
- *
* @param the list of scripts
*/
public ScriptList(List<String> scriptList)
{
this.list = scriptList;
}
-
}
}
Modified:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyScript2RestUpdateListener.java
===================================================================
---
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyScript2RestUpdateListener.java 2010-12-23
15:04:43 UTC (rev 3719)
+++
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyScript2RestUpdateListener.java 2010-12-23
15:06:33 UTC (rev 3720)
@@ -35,9 +35,9 @@
* @version $Id: GroovyScript2RestUpdateListener.java 34445 2009-07-24 07:51:18Z
* dkatayev $
*/
+@SuppressWarnings("deprecation")
public class GroovyScript2RestUpdateListener implements EventListener
{
-
/** Logger. */
private static final Log LOG =
ExoLogger.getLogger("exo.jcr.component.ext.GroovyScript2RestUpdateListener");
Modified:
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 2010-12-23
15:04:43 UTC (rev 3719)
+++
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrClassPathEntry.java 2010-12-23
15:06:33 UTC (rev 3720)
@@ -22,6 +22,7 @@
import org.exoplatform.services.rest.ext.groovy.ClassPathEntry;
import java.net.MalformedURLException;
+import java.net.URL;
/**
* @author <a href="mailto:andrey.parfonov@exoplatform.com">Andrey
Parfonov</a>
@@ -29,8 +30,13 @@
*/
public class JcrClassPathEntry extends ClassPathEntry
{
+ public JcrClassPathEntry(EntryType type, URL path)
+ {
+ super(type, path);
+ }
+
public JcrClassPathEntry(EntryType type, UnifiedNodeReference path) throws
MalformedURLException
{
- super(type, path.getURL());
+ this(type, path.getURL());
}
}
Modified:
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 2010-12-23
15:04:43 UTC (rev 3719)
+++
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyClassLoaderProvider.java 2010-12-23
15:06:33 UTC (rev 3720)
@@ -20,9 +20,10 @@
import groovy.lang.GroovyClassLoader;
+import org.exoplatform.services.rest.ext.groovy.ClassPath;
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.exoplatform.services.rest.ext.groovy.ClassPathEntry.EntryType;
import java.net.MalformedURLException;
import java.net.URL;
@@ -33,29 +34,34 @@
/**
* @author <a href="mailto:andrey.parfonov@exoplatform.com">Andrey
Parfonov</a>
- * @version $Id$
+ * @version $Id: JcrGroovyClassLoaderProvider.java 3702 2010-12-22 10:24:13Z
+ * aparfonov $
*/
public class JcrGroovyClassLoaderProvider extends GroovyClassLoaderProvider
{
/**
- * @see
org.exoplatform.services.rest.ext.groovy.GroovyClassLoaderProvider#getGroovyClassLoader(org.exoplatform.services.rest.ext.groovy.ClassPathEntry[])
+ * @see
org.exoplatform.services.rest.ext.groovy.GroovyClassLoaderProvider#getGroovyClassLoader(org.exoplatform.services.rest.ext.groovy.ClassPath)
*/
@Override
- public GroovyClassLoader getGroovyClassLoader(ClassPathEntry[] classPath) throws
MalformedURLException
+ public GroovyClassLoader getGroovyClassLoader(ClassPath classPath) throws
MalformedURLException
{
List<URL> files = new ArrayList<URL>();
List<URL> roots = new ArrayList<URL>();
- for (int i = 0; i < classPath.length; i++)
+ ClassPathEntry[] classPathEntries = classPath.getEntries();
+ if (classPathEntries != null && classPathEntries.length > 0)
{
- ClassPathEntry classPathEntry = classPath[i];
- if (EntryType.SRC_DIR == classPathEntry.getType())
+ for (int i = 0; i < classPathEntries.length; i++)
{
- roots.add(classPathEntry.getPath());
+ ClassPathEntry classPathEntry = classPathEntries[i];
+ if (EntryType.SRC_DIR == classPathEntry.getType())
+ {
+ roots.add(classPathEntry.getPath());
+ }
+ else
+ {
+ files.add(classPathEntry.getPath());
+ }
}
- else
- {
- files.add(classPathEntry.getPath());
- }
}
final GroovyClassLoader parent = getGroovyClassLoader();
GroovyClassLoader classLoader = AccessController.doPrivileged(new
PrivilegedAction<GroovyClassLoader>() {
@@ -65,7 +71,7 @@
}
});
classLoader.setResourceLoader(new JcrGroovyResourceLoader(roots.toArray(new
URL[roots.size()]), files
- .toArray(new URL[files.size()])));
+ .toArray(new URL[files.size()]), classPath.getExtensions()));
return classLoader;
}
}
\ No newline at end of file
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-23
15:04:43 UTC (rev 3719)
+++
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyCompiler.java 2010-12-23
15:06:33 UTC (rev 3720)
@@ -27,6 +27,7 @@
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.ClassPath;
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;
@@ -76,18 +77,23 @@
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);
+ return doCompile(classLoaderProvider.getGroovyClassLoader(new ClassPath(classPath,
null)), sourceReferences);
}
- public Class<?>[] compile(ClassPathEntry[] classPath, UnifiedNodeReference...
sourceReferences) throws IOException
+ public Class<?>[] compile(ClassPath 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];
+ ClassPathEntry[] classPathEntries = classPath.getEntries();
+ if (classPathEntries == null)
+ classPathEntries = new ClassPathEntry[0];
+ ClassPathEntry[] fullClassPath = new ClassPathEntry[compiled.length +
classPathEntries.length];
System.arraycopy(compiled, 0, fullClassPath, 0, compiled.length);
- System.arraycopy(classPath, 0, fullClassPath, compiled.length, classPath.length);
- return doCompile(classLoaderProvider.getGroovyClassLoader(fullClassPath),
sourceReferences);
+ System.arraycopy(classPathEntries, 0, fullClassPath, compiled.length,
classPathEntries.length);
+ return doCompile(
+ classLoaderProvider.getGroovyClassLoader(new ClassPath(fullClassPath,
classPath.getExtensions())),
+ sourceReferences);
}
private Class<?>[] doCompile(final GroovyClassLoader cl, final
UnifiedNodeReference... sourceReferences)
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-23
15:04:43 UTC (rev 3719)
+++
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyResourceLoader.java 2010-12-23
15:06:33 UTC (rev 3720)
@@ -61,9 +61,14 @@
return res;
}
+ public JcrGroovyResourceLoader(URL[] roots, URL[] files, String[] extensions) throws
MalformedURLException
+ {
+ super(normalizeJcrURL(roots), files, extensions);
+ }
+
public JcrGroovyResourceLoader(URL[] roots, URL[] files) throws MalformedURLException
{
- super(normalizeJcrURL(roots), files);
+ this(roots, files, null);
}
public JcrGroovyResourceLoader(URL[] roots) throws MalformedURLException
Modified:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/NodeScriptKey.java
===================================================================
---
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/NodeScriptKey.java 2010-12-23
15:04:43 UTC (rev 3719)
+++
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/NodeScriptKey.java 2010-12-23
15:06:33 UTC (rev 3720)
@@ -29,7 +29,6 @@
*/
public class NodeScriptKey extends BaseResourceId implements ScriptKey
{
-
private final String repositoryName;
private final String workspaceName;
@@ -63,5 +62,4 @@
{
return path;
}
-
}
Modified:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/SimpleScriptKey.java
===================================================================
---
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/SimpleScriptKey.java 2010-12-23
15:04:43 UTC (rev 3719)
+++
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/SimpleScriptKey.java 2010-12-23
15:06:33 UTC (rev 3720)
@@ -27,10 +27,8 @@
*/
public class SimpleScriptKey extends BaseResourceId implements ScriptKey
{
-
public SimpleScriptKey(String key)
{
super(key);
}
-
}
Modified:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/URLScriptKey.java
===================================================================
---
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/URLScriptKey.java 2010-12-23
15:04:43 UTC (rev 3719)
+++
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/URLScriptKey.java 2010-12-23
15:06:33 UTC (rev 3720)
@@ -28,10 +28,8 @@
*/
public class URLScriptKey extends BaseResourceId implements ScriptKey
{
-
public URLScriptKey(URL url)
{
super(url.toString());
}
-
}
Modified:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/XMLGroovyScript2Rest.java
===================================================================
---
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/XMLGroovyScript2Rest.java 2010-12-23
15:04:43 UTC (rev 3719)
+++
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/XMLGroovyScript2Rest.java 2010-12-23
15:06:33 UTC (rev 3720)
@@ -24,22 +24,13 @@
*/
public class XMLGroovyScript2Rest
{
-
- /**
- * Script name.
- */
+ /** Script name. */
private String name;
- /**
- * From this URL script will be loaded.
- */
+ /** From this URL script will be loaded. */
private String path;
- /**
- * If this parameter true script will be loaded automatically.
- *
- * @see {@link GroovyScript2RestLoader}
- */
+ /** If this parameter true script will be loaded automatically. */
private boolean autoload;
public XMLGroovyScript2Rest(String name, String path, boolean autoload)
@@ -112,5 +103,4 @@
this.autoload).append("}");
return sb.toString();
}
-
}
Modified:
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 2010-12-23
15:04:43 UTC (rev 3719)
+++
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/script/groovy/BaseGroovyTest.java 2010-12-23
15:06:33 UTC (rev 3720)
@@ -45,7 +45,17 @@
return createScript(parent, packageName, name, new
ByteArrayInputStream(text.getBytes()));
}
- protected String createScript(Node parent, String packageName, String name,
InputStream text) throws RepositoryException
+ /**
+ * @param parent parent node
+ * @param packageName package name. Segment of package name must be separated
+ * by '.'. If required folders in hierarchy does not exists they
+ * will be created
+ * @param name name of file with extension
+ * @param text source code
+ * @return path where script was created
+ */
+ protected String createScript(Node parent, String packageName, String name,
InputStream text)
+ throws RepositoryException
{
Node current = parent;
if (packageName != null && packageName.length() > 0)
@@ -58,7 +68,7 @@
current = current.getNode(s);
}
}
- Node script = current.addNode(name + ".groovy", "nt:file");
+ Node script = current.addNode(name, "nt:file");
Node scriptContent = script.addNode("jcr:content",
"nt:resource");
scriptContent.setProperty("jcr:mimeType", "script/groovy");
scriptContent.setProperty("jcr:lastModified", Calendar.getInstance());
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-23
15:04:43 UTC (rev 3719)
+++
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyCompilerTest.java 2010-12-23
15:06:33 UTC (rev 3720)
@@ -22,6 +22,7 @@
import groovy.lang.GroovyObject;
import org.exoplatform.services.jcr.ext.resource.UnifiedNodeReference;
+import org.exoplatform.services.rest.ext.groovy.ClassPath;
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;
@@ -50,11 +51,11 @@
otherGroovyRepo = root.addNode("otherGroovyRepo",
"nt:folder");
// Add script in shared "dependency repository".
- scriptA = createScript(groovyRepo, "org.exoplatform", "A", //
+ scriptA = createScript(groovyRepo, "org.exoplatform",
"A.groovy", //
"package org.exoplatform\n" + //
"class A { String message = 'groovy compiler test' }");
- scriptB = createScript(groovyRepo, "org.exoplatform.test", "B",
//
+ scriptB = createScript(groovyRepo, "org.exoplatform.test",
"B.groovy", //
"package org.exoplatform.test\n" + //
"import org.exoplatform.A\n" + //
"class B extends A {}");
@@ -91,8 +92,10 @@
{
GroovyClassLoaderProvider classLoaderProvider = new GroovyClassLoaderProvider();
JcrGroovyCompiler compiler = new JcrGroovyCompiler(classLoaderProvider);
+ ClassPathEntry[] classPathEntries =
+ new ClassPathEntry[]{new JcrClassPathEntry(EntryType.FILE, new
UnifiedNodeReference("db1", "ws", scriptA))};
Class<?>[] classes = compiler.compile( //
- new ClassPathEntry[]{new JcrClassPathEntry(EntryType.FILE, new
UnifiedNodeReference("db1", "ws", scriptA))}, //
+ new ClassPath(classPathEntries, null), //
new UnifiedNodeReference("db1", "ws", scriptB));
assertEquals(1, classes.length);
GroovyObject go = (GroovyObject)classes[0].newInstance();
@@ -101,20 +104,20 @@
public void testCombinedDependencies() throws Exception
{
- String scriptC = createScript(otherGroovyRepo, "org.exoplatform.test",
"C", //
+ String scriptC = createScript(otherGroovyRepo, "org.exoplatform.test",
"C.groovy", //
"package org.exoplatform.test\n" + //
"import org.exoplatform.*\n" + //
"class C extends B {}");
- String scriptD = createScript(otherGroovyRepo,
"org.exoplatform.test.other", "D", //
+ String scriptD = createScript(otherGroovyRepo,
"org.exoplatform.test.other", "D.groovy", //
"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),
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-23
15:04:43 UTC (rev 3719)
+++
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyScript2RestLoaderTest.java 2010-12-23
15:06:33 UTC (rev 3720)
@@ -21,6 +21,7 @@
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;
+import org.exoplatform.services.jcr.ext.resource.UnifiedNodeReference;
import
org.exoplatform.services.jcr.ext.script.groovy.GroovyScript2RestLoader.ScriptMetadata;
import org.exoplatform.services.rest.RequestHandler;
import org.exoplatform.services.rest.ext.method.filter.MethodAccessFilter;
@@ -39,6 +40,7 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.net.URLEncoder;
import java.security.Principal;
import java.util.Calendar;
import java.util.HashSet;
@@ -143,7 +145,7 @@
assertEquals(resourceNumber, binder.getSize());
}
- public void testRemoteAccessGetMetatData() throws Exception
+ public void testGetMetatData() throws Exception
{
MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
headers.putSingle("Accept", MediaType.APPLICATION_JSON);
@@ -155,7 +157,7 @@
assertTrue(Boolean.valueOf(data.getLoad()));
}
- public void testRemoteAccessAutoload() throws Exception
+ public void testAutoload() throws Exception
{
ContainerResponse cres =
@@ -170,7 +172,7 @@
assertTrue(script.getProperty("exo:autoload").getBoolean());
}
- public void testRemoteAccessLoad() throws Exception
+ public void testLoad() throws Exception
{
EnvironmentContext ctx = new EnvironmentContext();
ctx.put(SecurityContext.class, adminSecurityContext);
@@ -186,8 +188,105 @@
assertEquals(resourceNumber + 1, binder.getSize());
}
- public void testRemoteAccessDelete() throws Exception
+ public void testLoadNoExtClassPath() throws Exception
{
+ String path = createScript(testRoot, "test.load",
"Test000.groovy", //
+ "import test.load.User000\n" + //
+ "(a)javax.ws.rs.Path('test/load') class Test000 {\n" + //
+ "def user = new User(name:'test')\n" + //
+ "(a)javax.ws.rs.GET def m() {user}" + //
+ "}\n");
+ EnvironmentContext ctx = new EnvironmentContext();
+ ctx.put(SecurityContext.class, adminSecurityContext);
+
+ int before = binder.getSize();
+ ContainerResponse cres = launcher.service("POST",
"/script/groovy/load/db1/ws" + path, "", null, null, ctx);
+ assertEquals(400, cres.getStatus());
+ int after = binder.getSize();
+ assertEquals(before, after);
+ }
+
+ public void testLoadNoExtClassPath_File() throws Exception
+ {
+ String scriptPath = createScript(testRoot, "test.load",
"Test001.groovy", //
+ "import test.load.User001\n" + //
+ "(a)javax.ws.rs.Path('test/load_001') class Test001 {\n" +
//
+ "def user = new User001(name:'test')\n" + //
+ "(a)javax.ws.rs.GET def m() {user}" + //
+ "}\n");
+ String user = createScript(testRoot, "test.load",
"User001.groovy",//
+ "package test.load\n" + //
+ "class User001 {def name}");
+
+ EnvironmentContext ctx = new EnvironmentContext();
+ ctx.put(SecurityContext.class, adminSecurityContext);
+ String path =
+ "/script/groovy/load/db1/ws" + scriptPath //
+ + "?file=" //
+ + URLEncoder.encode(new UnifiedNodeReference(repository.getName(),
workspace.getName(), user).getURL()
+ .toString(), "UTF-8");
+ int before = binder.getSize();
+ ContainerResponse cres = launcher.service("POST", path, "",
null, null, ctx);
+ assertEquals(204, cres.getStatus());
+ int after = binder.getSize();
+ assertEquals(before + 1, after);
+ }
+
+ public void testLoadNoExtClassPath_SourceFolder() throws Exception
+ {
+ String scriptPath = createScript(testRoot, "test.load",
"Test002.groovy", //
+ "import test.load.User002\n" + //
+ "(a)javax.ws.rs.Path('test/load_002') class Test002 {\n" +
//
+ "def user = new User002(name:'test')\n" + //
+ "(a)javax.ws.rs.GET def m() {user}" + //
+ "}\n");
+ createScript(testRoot, "test.load", "User002.groovy",//
+ "package test.load\n" + //
+ "class User002 {def name}");
+
+ EnvironmentContext ctx = new EnvironmentContext();
+ ctx.put(SecurityContext.class, adminSecurityContext);
+ String path =
+ "/script/groovy/load/db1/ws" + scriptPath //
+ + "?sources=" //
+ + URLEncoder.encode(new UnifiedNodeReference(repository.getName(),
workspace.getName(), testRoot.getPath())
+ .getURL().toString(), "UTF-8");
+ int before = binder.getSize();
+ ContainerResponse cres = launcher.service("POST", path, "",
null, null, ctx);
+ assertEquals(204, cres.getStatus());
+ int after = binder.getSize();
+ assertEquals(before + 1, after);
+ }
+
+ public void testLoadNoExtClassPath_CustomExtension() throws Exception
+ {
+ String scriptPath = createScript(testRoot, "test.load",
"Test003.groovy", //
+ "import test.load.User003\n" + //
+ "(a)javax.ws.rs.Path('test/load_003') class Test003 {\n" +
//
+ "def user = new User003(name:'test')\n" + //
+ "(a)javax.ws.rs.GET def m() {user}" + //
+ "}\n");
+ createScript(testRoot, "test.load", "User003.otherGroovy",//
+ "package test.load\n" + //
+ "class User003 {def name}");
+
+ EnvironmentContext ctx = new EnvironmentContext();
+ ctx.put(SecurityContext.class, adminSecurityContext);
+ String path =
+ "/script/groovy/load/db1/ws" + scriptPath //
+ + "?sources=" //
+ + URLEncoder.encode(new UnifiedNodeReference(repository.getName(),
workspace.getName(), testRoot.getPath())
+ .getURL().toString(), "UTF-8") + //
+ "&extension=.otherGroovy";
+ int before = binder.getSize();
+ ContainerResponse cres = launcher.service("POST", path, "",
null, null, ctx);
+ assertEquals(204, cres.getStatus());
+ int after = binder.getSize();
+ assertEquals(before + 1, after);
+ }
+
+ public void testDelete() throws Exception
+ {
ContainerResponse cres =
launcher.service("POST",
"/script/groovy/delete/db1/ws/testRoot/script", "", null, null,
null);
@@ -195,7 +294,7 @@
assertEquals(resourceNumber, binder.getSize());
}
- public void testRemoteAccessGetScript() throws Exception
+ public void testGetScript() throws Exception
{
MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
headers.putSingle("Accept", "script/groovy");
@@ -206,7 +305,7 @@
compareStream(script.getProperty("jcr:data").getStream(), new
ByteArrayInputStream(wr.getBody()));
}
- public void testRemoteAccessAddScript() throws Exception
+ public void testAddScript() throws Exception
{
script.getParent().remove();
session.save();
@@ -271,13 +370,91 @@
script = "public class Test { def a = 0\ndef b = 1\n }\n";
cres = launcher.service("POST", "/script/groovy/validate/",
"", headers, script.getBytes(), null);
assertEquals(200, cres.getStatus());
+ }
+ public void testValidateNoExtClassPath() throws Exception
+ {
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+ headers.putSingle("Content-Type", "script/groovy");
+ String script = "import test.validate.User000\n" + //
+ "(a)javax.ws.rs.Path('test/validate') class Test {\n" + //
+ "def user = new User000(name:'test')\n" + //
+ "(a)javax.ws.rs.GET def m() {user}" + //
+ " }\n";
+ ContainerResponse cres =
+ launcher.service("POST", "/script/groovy/validate/Test",
"", headers, script.getBytes(), null);
+ assertEquals(400, cres.getStatus());
+ System.out.println(cres.getEntity());
}
+ public void testValidateExtClassPath_File() throws Exception
+ {
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+ headers.putSingle("Content-Type", "script/groovy");
+ String script = "import test.validate.User001\n" + //
+ "(a)javax.ws.rs.Path('test/validate') class Test {\n" + //
+ "def user = new User001(name:'test')\n" + //
+ "(a)javax.ws.rs.GET def m() {user}" + //
+ " }\n";
+ String user = createScript(testRoot, "test.validate",
"User001.groovy",//
+ "package test.validate\n" + //
+ "class User001 {def name}");
+ // Specify source file location.
+ String path =
+ "/script/groovy/validate/Test?file=" //
+ + URLEncoder.encode(new UnifiedNodeReference(repository.getName(),
workspace.getName(), user).getURL()
+ .toString(), "UTF-8");
+ ContainerResponse cres = launcher.service("POST", path, "",
headers, script.getBytes(), null);
+ assertEquals(200, cres.getStatus());
+ }
+
+ public void testValidateExtClassPath_SourceFolder() throws Exception
+ {
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+ headers.putSingle("Content-Type", "script/groovy");
+ String script = "import test.validate.User002\n" + //
+ "(a)javax.ws.rs.Path('test/validate') class Test {\n" + //
+ "def user = new User002(name:'test')\n" + //
+ "(a)javax.ws.rs.GET def m() {user}" + //
+ " }\n";
+ createScript(testRoot, "test.validate", "User002.groovy",//
+ "package test.validate\n" + //
+ "class User002 {def name}");
+ // Specify source folder location.
+ String path =
+ "/script/groovy/validate/Test?sources=" //
+ + URLEncoder.encode(new UnifiedNodeReference(repository.getName(),
workspace.getName(), testRoot.getPath())
+ .getURL().toString(), "UTF-8");
+ ContainerResponse cres = launcher.service("POST", path, "",
headers, script.getBytes(), null);
+ assertEquals(200, cres.getStatus());
+ }
+
+ public void testValidateExtClassPath_CustomExtension() throws Exception
+ {
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+ headers.putSingle("Content-Type", "script/groovy");
+ String script = "import test.validate.User003\n" + //
+ "(a)javax.ws.rs.Path('test/validate') class Test {\n" + //
+ "def user = new User003(name:'test')\n" + //
+ "(a)javax.ws.rs.GET def m() {user}" + //
+ " }\n";
+ createScript(testRoot, "test.validate",
"User003.otherGroovy",//
+ "package test.validate\n" + //
+ "class User003 {def name}");
+ // Specify source folder location and customized extension '.otherGroovy'.
+ String path =
+ "/script/groovy/validate/Test?sources=" //
+ + URLEncoder.encode(new UnifiedNodeReference(repository.getName(),
workspace.getName(), testRoot.getPath())
+ .getURL().toString(), "UTF-8") + //
+ "&extension=.otherGroovy";
+ ContainerResponse cres = launcher.service("POST", path, "",
headers, script.getBytes(), null);
+ assertEquals(200, cres.getStatus());
+ }
+
public void testGroovyDependency() throws Exception
{
// Add script in dependency repository
- createScript(groovyRepo, "dependencies", "Dep1", //
+ createScript(groovyRepo, "dependencies", "Dep1.groovy", //
"package dependencies\n" + //
"class Dep1 { String name = getClass().getName() }");
@@ -292,7 +469,6 @@
ContainerResponse cres = launcher.service("GET",
"/groovy-test-dependency", "", null, null, null);
assertEquals(200, cres.getStatus());
assertEquals("dependencies.Dep1", cres.getEntity());
-
}
private byte[] getResourceAsBytes(String resource) throws IOException
@@ -305,9 +481,7 @@
byte[] buf = new byte[1024];
int r = -1;
while ((r = stream.read(buf)) != -1)
- {
bout.write(buf, 0, r);
- }
data = bout.toByteArray();
}
return data;