Index: dna-graph/src/main/java/org/jboss/dna/graph/ExecutionContext.java
===================================================================
--- dna-graph/src/main/java/org/jboss/dna/graph/ExecutionContext.java (revision 938)
+++ dna-graph/src/main/java/org/jboss/dna/graph/ExecutionContext.java (working copy)
@@ -42,6 +42,7 @@
import org.jboss.dna.common.component.StandardClassLoaderFactory;
import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.common.util.Logger;
+import org.jboss.dna.common.util.Reflection;
import org.jboss.dna.graph.connector.federation.FederatedLexicon;
import org.jboss.dna.graph.mimetype.ExtensionBasedMimeTypeDetector;
import org.jboss.dna.graph.mimetype.MimeTypeDetector;
@@ -528,6 +529,9 @@
* @see javax.security.auth.callback.CallbackHandler#handle(javax.security.auth.callback.Callback[])
*/
public void handle( Callback[] callbacks ) throws UnsupportedCallbackException, IOException {
+ boolean userSet = false;
+ boolean passwordSet = false;
+
for (int i = 0; i < callbacks.length; i++) {
if (callbacks[i] instanceof TextOutputCallback) {
@@ -563,6 +567,7 @@
}
nc.setName(this.userId);
+ userSet = true;
} else if (callbacks[i] instanceof PasswordCallback) {
@@ -573,9 +578,32 @@
System.out.flush();
}
pc.setPassword(this.password);
+ passwordSet = true;
} else {
- throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
+ /*
+ * Jetty uses its own callback for setting the password. Since we're using Jetty for integration
+ * testing of the web project(s), we have to accomodate this. Rather than introducing a direct
+ * dependency, we'll add code to handle the case of unexpected callback handlers with a setObject method.
+ */
+ try {
+ // Assume that a callback chain will ask for the user before the password
+ if (!userSet) {
+ new Reflection(callbacks[i].getClass()).invokeSetterMethodOnTarget("object", callbacks[i], this.userId);
+ userSet = true;
+ }
+ else if (!passwordSet) {
+ // Jetty also seems to eschew passing passwords as char arrays
+ new Reflection(callbacks[i].getClass()).invokeSetterMethodOnTarget("object", callbacks[i], new String(this.password));
+ passwordSet = true;
+ }
+ // It worked - need to continue processing the callbacks
+ continue;
+ } catch (Exception ex) {
+ // If the property cannot be set, fall through to the failure
+ }
+ throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback: "
+ + callbacks[i].getClass().getName());
}
}
Index: dna-jcr/src/main/java/org/jboss/dna/jcr/JcrEngine.java
===================================================================
--- dna-jcr/src/main/java/org/jboss/dna/jcr/JcrEngine.java (revision 938)
+++ dna-jcr/src/main/java/org/jboss/dna/jcr/JcrEngine.java (working copy)
@@ -23,7 +23,10 @@
*/
package org.jboss.dna.jcr;
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
@@ -44,6 +47,7 @@
import org.jboss.dna.graph.property.Property;
import org.jboss.dna.jcr.JcrRepository.Option;
import org.jboss.dna.repository.DnaEngine;
+import org.jboss.dna.repository.RepositoryLibrary;
import org.jboss.dna.repository.RepositoryService;
import org.jboss.dna.repository.sequencer.SequencingService;
@@ -103,6 +107,24 @@
}
/**
+ * Returns a list of the names of all available JCR repositories.
+ *
+ * In a {@code JcrEngine}, the available repositories are {@link RepositoryLibrary#getSourceNames() all repositories} except
+ * for the {@link RepositoryService#getConfigurationSourceName() the configuration repository}.
+ *
+ *
+ * @return a list of all repository names.
+ */
+ public final Collection getJcrRepositoryNames() {
+ List jcrRepositories = new ArrayList();
+ jcrRepositories.addAll(getRepositoryService().getRepositoryLibrary().getSourceNames());
+
+ jcrRepositories.remove(getRepositoryService().getConfigurationSourceName());
+
+ return jcrRepositories;
+ }
+
+ /**
* Get the {@link Repository} implementation for the named repository.
*
* @param repositoryName the name of the repository, which corresponds to the name of a configured {@link RepositorySource}
Index: extensions/dna-web-jcr-rest-war/.classpath
===================================================================
--- extensions/dna-web-jcr-rest-war/.classpath (revision 0)
+++ extensions/dna-web-jcr-rest-war/.classpath (revision 0)
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: extensions/dna-web-jcr-rest-war/.project
===================================================================
--- extensions/dna-web-jcr-rest-war/.project (revision 0)
+++ extensions/dna-web-jcr-rest-war/.project (revision 0)
@@ -0,0 +1,42 @@
+
+
+ dna-web-jcr-rest-war
+
+
+
+
+
+ org.eclipse.wst.jsdt.core.javascriptValidator
+
+
+
+
+ org.eclipse.wst.common.project.facet.core.builder
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.wst.validation.validationbuilder
+
+
+
+
+ org.maven.ide.eclipse.maven2Builder
+
+
+
+
+
+ org.eclipse.jem.workbench.JavaEMFNature
+ org.eclipse.wst.common.modulecore.ModuleCoreNature
+ org.eclipse.jdt.core.javanature
+ org.maven.ide.eclipse.maven2Nature
+ org.eclipse.wst.common.project.facet.core.nature
+ org.eclipse.wst.jsdt.core.jsNature
+
+
Index: extensions/dna-web-jcr-rest-war/.settings/.jsdtscope
===================================================================
--- extensions/dna-web-jcr-rest-war/.settings/.jsdtscope (revision 0)
+++ extensions/dna-web-jcr-rest-war/.settings/.jsdtscope (revision 0)
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
Index: extensions/dna-web-jcr-rest-war/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- extensions/dna-web-jcr-rest-war/.settings/org.eclipse.jdt.core.prefs (revision 0)
+++ extensions/dna-web-jcr-rest-war/.settings/org.eclipse.jdt.core.prefs (revision 0)
@@ -0,0 +1,7 @@
+#Wed May 27 16:41:12 EDT 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
Index: extensions/dna-web-jcr-rest-war/.settings/org.eclipse.wst.common.component
===================================================================
--- extensions/dna-web-jcr-rest-war/.settings/org.eclipse.wst.common.component (revision 0)
+++ extensions/dna-web-jcr-rest-war/.settings/org.eclipse.wst.common.component (revision 0)
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+ uses
+
+
+ uses
+
+
+ uses
+
+
+ uses
+
+
+ uses
+
+
+ uses
+
+
+ uses
+
+
+
+
+
Index: extensions/dna-web-jcr-rest-war/.settings/org.eclipse.wst.common.project.facet.core.xml
===================================================================
--- extensions/dna-web-jcr-rest-war/.settings/org.eclipse.wst.common.project.facet.core.xml (revision 0)
+++ extensions/dna-web-jcr-rest-war/.settings/org.eclipse.wst.common.project.facet.core.xml (revision 0)
@@ -0,0 +1,5 @@
+
+
+
+
+
Property changes on: extensions\dna-web-jcr-rest-war\.settings\org.eclipse.wst.common.project.facet.core.xml
___________________________________________________________________
Added: svn:keywords
+ Id Revision
Added: svn:eol-style
+ LF
Index: extensions/dna-web-jcr-rest-war/.settings/org.eclipse.wst.jsdt.ui.superType.container
===================================================================
--- extensions/dna-web-jcr-rest-war/.settings/org.eclipse.wst.jsdt.ui.superType.container (revision 0)
+++ extensions/dna-web-jcr-rest-war/.settings/org.eclipse.wst.jsdt.ui.superType.container (revision 0)
@@ -0,0 +1 @@
+org.eclipse.wst.jsdt.launching.baseBrowserLibrary
\ No newline at end of file
Index: extensions/dna-web-jcr-rest-war/.settings/org.eclipse.wst.jsdt.ui.superType.name
===================================================================
--- extensions/dna-web-jcr-rest-war/.settings/org.eclipse.wst.jsdt.ui.superType.name (revision 0)
+++ extensions/dna-web-jcr-rest-war/.settings/org.eclipse.wst.jsdt.ui.superType.name (revision 0)
@@ -0,0 +1 @@
+Window
\ No newline at end of file
Index: extensions/dna-web-jcr-rest-war/.settings/org.maven.ide.eclipse.prefs
===================================================================
--- extensions/dna-web-jcr-rest-war/.settings/org.maven.ide.eclipse.prefs (revision 0)
+++ extensions/dna-web-jcr-rest-war/.settings/org.maven.ide.eclipse.prefs (revision 0)
@@ -0,0 +1,9 @@
+#Wed May 27 16:41:08 EDT 2009
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+includeModules=true
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+skipCompilerPlugin=true
+version=1
Index: extensions/dna-web-jcr-rest-war/pom.xml
===================================================================
--- extensions/dna-web-jcr-rest-war/pom.xml (revision 0)
+++ extensions/dna-web-jcr-rest-war/pom.xml (revision 0)
@@ -0,0 +1,111 @@
+
+ 4.0.0
+
+ dna
+ org.jboss.dna
+ 0.5-SNAPSHOT
+ ../..
+
+ dna-web-jcr-rest-war
+ war
+ JBoss DNA JCR REST Servlet
+ JBoss DNA servlet that provides RESTful access to JCR items
+ http://labs.jboss.org/dna
+
+
+ org.jboss.dna
+ dna-web-jcr-rest
+ ${pom.version}
+
+
+
+ org.slf4j
+ slf4j-log4j12
+ 1.4.3
+ runtime
+
+
+
+
+ junit
+ junit-dep
+ 4.4
+ integration-test
+
+
+ org.jboss.resteasy
+ resteasy-client
+ 1.0-beta-8
+ integration-test
+
+
+
+ resources
+
+
+
+
+
+
+
+
+ org.codehaus.cargo
+ cargo-maven2-plugin
+
+
+ start-container
+ pre-integration-test
+
+ start
+
+
+
+ stop-container
+ post-integration-test
+
+ stop
+
+
+
+
+
+
+ high
+
+
+
+
+ ${project.build.directory}/test-classes/jetty-dna.policy
+
+
+ false
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ true
+
+
+
+ surefire-it
+ integration-test
+
+ test
+
+
+ false
+
+
+
+
+
+
+
+
Property changes on: extensions\dna-web-jcr-rest-war\pom.xml
___________________________________________________________________
Added: svn:keywords
+ Id Revision
Added: svn:eol-style
+ LF
Index: extensions/dna-web-jcr-rest-war/src/main/webapp/META-INF/MANIFEST.MF
===================================================================
--- extensions/dna-web-jcr-rest-war/src/main/webapp/META-INF/MANIFEST.MF (revision 0)
+++ extensions/dna-web-jcr-rest-war/src/main/webapp/META-INF/MANIFEST.MF (revision 0)
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Class-Path:
+
Index: extensions/dna-web-jcr-rest-war/src/main/webapp/WEB-INF/web.xml
===================================================================
--- extensions/dna-web-jcr-rest-war/src/main/webapp/WEB-INF/web.xml (revision 0)
+++ extensions/dna-web-jcr-rest-war/src/main/webapp/WEB-INF/web.xml (revision 0)
@@ -0,0 +1,65 @@
+
+
+
+
+ JBoss DNA JCR RESTful Interface
+
+
+ org.jboss.dna.web.jcr.rest.REPOSITORY_PROVIDER
+ org.jboss.dna.web.jcr.rest.spi.DnaJcrRepositoryProvider
+
+
+
+ resteasy.providers
+ org.jboss.dna.web.jcr.rest.JcrResources$NotFoundExceptionMapper,
+ org.jboss.dna.web.jcr.rest.JcrResources$JSONExceptionMapper,
+ org.jboss.dna.web.jcr.rest.JcrResources$RepositoryExceptionMapper
+
+
+
+
+ javax.ws.rs.core.Application
+ org.jboss.dna.web.jcr.rest.JcrApplication
+
+
+
+
+ org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
+
+
+
+
+ org.jboss.dna.web.jcr.rest.DnaJcrDeployer
+
+
+
+ Resteasy
+
+ org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
+
+
+
+
+ Resteasy
+ /*
+
+
+
\ No newline at end of file
Property changes on: extensions\dna-web-jcr-rest-war\src\main\webapp\WEB-INF\web.xml
___________________________________________________________________
Added: svn:keywords
+ Id Revision
Added: svn:eol-style
+ LF
Index: extensions/dna-web-jcr-rest/.classpath
===================================================================
--- extensions/dna-web-jcr-rest/.classpath (revision 938)
+++ extensions/dna-web-jcr-rest/.classpath (working copy)
@@ -1,9 +1,8 @@
-
-
-
-
+
+
+
Index: extensions/dna-web-jcr-rest/.project
===================================================================
--- extensions/dna-web-jcr-rest/.project (revision 938)
+++ extensions/dna-web-jcr-rest/.project (working copy)
@@ -1,23 +1,36 @@
-
-
- dna-web-jcr-rest
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.maven.ide.eclipse.maven2Builder
-
-
-
-
-
- org.eclipse.jdt.core.javanature
- org.maven.ide.eclipse.maven2Nature
-
-
+
+
+ dna-web-jcr-rest
+
+
+
+
+
+ org.eclipse.wst.common.project.facet.core.builder
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.maven.ide.eclipse.maven2Builder
+
+
+
+
+ org.eclipse.wst.validation.validationbuilder
+
+
+
+
+
+ org.eclipse.jem.workbench.JavaEMFNature
+ org.eclipse.wst.common.modulecore.ModuleCoreNature
+ org.eclipse.jdt.core.javanature
+ org.maven.ide.eclipse.maven2Nature
+ org.eclipse.wst.common.project.facet.core.nature
+
+
Index: extensions/dna-web-jcr-rest/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- extensions/dna-web-jcr-rest/.settings/org.eclipse.jdt.core.prefs (revision 0)
+++ extensions/dna-web-jcr-rest/.settings/org.eclipse.jdt.core.prefs (revision 0)
@@ -0,0 +1,7 @@
+#Wed May 27 16:41:15 EDT 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
Index: extensions/dna-web-jcr-rest/.settings/org.eclipse.wst.common.component
===================================================================
--- extensions/dna-web-jcr-rest/.settings/org.eclipse.wst.common.component (revision 0)
+++ extensions/dna-web-jcr-rest/.settings/org.eclipse.wst.common.component (revision 0)
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
Index: extensions/dna-web-jcr-rest/.settings/org.eclipse.wst.common.project.facet.core.xml
===================================================================
--- extensions/dna-web-jcr-rest/.settings/org.eclipse.wst.common.project.facet.core.xml (revision 0)
+++ extensions/dna-web-jcr-rest/.settings/org.eclipse.wst.common.project.facet.core.xml (revision 0)
@@ -0,0 +1,5 @@
+
+
+
+
+
Property changes on: extensions\dna-web-jcr-rest\.settings\org.eclipse.wst.common.project.facet.core.xml
___________________________________________________________________
Added: svn:keywords
+ Id Revision
Added: svn:eol-style
+ LF
Index: extensions/dna-web-jcr-rest/.settings/org.maven.ide.eclipse.prefs
===================================================================
--- extensions/dna-web-jcr-rest/.settings/org.maven.ide.eclipse.prefs (revision 0)
+++ extensions/dna-web-jcr-rest/.settings/org.maven.ide.eclipse.prefs (revision 0)
@@ -0,0 +1,9 @@
+#Wed May 27 16:24:52 EDT 2009
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+includeModules=false
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+skipCompilerPlugin=true
+version=1
Index: extensions/dna-web-jcr-rest/pom.xml
===================================================================
--- extensions/dna-web-jcr-rest/pom.xml (revision 938)
+++ extensions/dna-web-jcr-rest/pom.xml (working copy)
@@ -7,9 +7,8 @@
0.5-SNAPSHOT
../..
- org.jboss.dna
dna-web-jcr-rest
- war
+ jar
JBoss DNA JCR REST Servlet
JBoss DNA servlet that provides RESTful access to JCR items
http://labs.jboss.org/dna
@@ -19,7 +18,26 @@
resteasy-jaxrs
1.1-RC2
+
+ org.jboss.resteasy
+ resteasy-jaxb-provider
+ 1.1-RC2
+
+
+
+ org.jboss.dna
+ dna-jcr
+
+
+
+ org.slf4j
+ slf4j-log4j12
+ 1.4.3
+ runtime
+
@@ -42,57 +60,10 @@
integration-test
+
+ javax.xml.bind
+ jaxb-api
+ 2.1
+
-
- resources
-
-
- org.codehaus.cargo
- cargo-maven2-plugin
-
-
- start-container
- pre-integration-test
-
- start
-
-
-
- stop-container
- post-integration-test
-
- stop
-
-
-
-
- false
-
-
-
-
- org.apache.maven.plugins
- maven-surefire-plugin
-
- true
-
-
-
- surefire-it
- integration-test
-
- test
-
-
- false
-
-
-
-
-
-
-
Index: extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/DnaJcrDeployer.java
===================================================================
--- extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/DnaJcrDeployer.java (revision 0)
+++ extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/DnaJcrDeployer.java (revision 0)
@@ -0,0 +1,25 @@
+package org.jboss.dna.web.jcr.rest;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+
+
+public class DnaJcrDeployer implements ServletContextListener {
+
+ public static final String DEFAULT_JNDI_NAME = "java:comp/env/org/jboss/dna/Engine";
+
+ public static final String SYSTEM_PROPERTY_JNDI_NAME = "org.jboss.dna.dnaEngineJndiName";
+
+ public static final String INIT_PARAMETER_JNDI_NAME = "org.jboss.dna.dnaEngineJndiName";
+
+ public void contextDestroyed( ServletContextEvent event ) {
+ RepositoryFactory.shutdown();
+ }
+
+ /**
+ * Mounts a DNA engine
+ */
+ public void contextInitialized( ServletContextEvent event ) {
+ RepositoryFactory.initialize(event.getServletContext());
+ }
+}
Property changes on: extensions\dna-web-jcr-rest\src\main\java\org\jboss\dna\web\jcr\rest\DnaJcrDeployer.java
___________________________________________________________________
Added: svn:keywords
+ Id Revision
Added: svn:eol-style
+ LF
Index: extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/JcrResources.java
===================================================================
--- extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/JcrResources.java (revision 938)
+++ extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/JcrResources.java (working copy)
@@ -23,9 +23,49 @@
*/
package org.jboss.dna.web.jcr.rest;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import javax.jcr.Credentials;
+import javax.jcr.Item;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+import javax.jcr.Value;
+import javax.jcr.nodetype.PropertyDefinition;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+import org.codehaus.jettison.json.JSONArray;
+import org.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
+import org.jboss.dna.common.text.UrlEncoder;
+import org.jboss.dna.web.jcr.rest.model.RepositoryEntry;
+import org.jboss.dna.web.jcr.rest.model.WorkspaceEntry;
+import org.jboss.resteasy.spi.NotFoundException;
+import org.jboss.resteasy.spi.UnauthorizedException;
/**
* RESTEasy handler to provide the JCR resources at the URIs below. Please note that these URIs assume a context of {@code
@@ -42,45 +82,23 @@
* GET |
*
*
- * /resources/repositories |
- * returns a list of accessible repositories |
- * GET |
- *
- *
* /resources/{repositoryName} |
* returns a list of accessible workspaces within that repository |
* GET |
*
*
- * /resources/{repositoryName}/workspaces |
- * returns a list of accessible workspaces within that repository |
- * GET |
- *
- *
* /resources/{repositoryName}/{workspaceName} |
* returns a list of operations within the workspace |
* GET |
*
*
* /resources/{repositoryName}/{workspaceName}/item/{path} |
- * accesses the node at the path |
+ * accesses the item (node or property) at the path |
* ALL |
*
- *
- * /resources/{repositoryName}/{workspaceName}/item/{path}/@{propertyName} |
- * accesses the named property at the path |
- * ALL (except PUT) |
- *
- *
- * /resources/{repositoryName}/{workspaceName}/item/{path}/@{propertyName} |
- * adds the value from the body to the named property at the path |
- * PUT |
- *
- *
- * /resources/{repositoryName}/{workspaceName}/uuid/{uuid} |
+ * /resources/{repositoryName}/{workspaceName}/node/{uuid} |
* accesses the node with the given UUID |
- * ALL |
- *
+ * ALL |
*
* /resources/{repositoryName}/{workspaceName}/lock/{path} |
* locks the node at the path |
@@ -96,25 +114,543 @@
@Path( "/" )
public class JcrResources {
+ private static final UrlEncoder URL_ENCODER = new UrlEncoder();
+
+ private static final String PROPERTIES_HOLDER = "properties";
+ private static final String CHILD_NODE_HOLDER = "children";
+
+ private static final String PRIMARY_TYPE_PROPERTY = "jcr:primaryType";
+ private static final String MIXIN_TYPES_PROPERTY = "jcr:mixinTypes";
+
+ /** Name to be used when the repository name is empty string as {@code "//"} is not a valid path. */
+ public static final String EMPTY_REPOSITORY_NAME = "";
+ /** Name to be used when the workspace name is empty string as {@code "//"} is not a valid path. */
+ public static final String EMPTY_WORKSPACE_NAME = "";
+
/**
+ * Returns a reference to the named repository, if it exists.
+ *
+ * @param repositoryName the name of the repository to load
+ * @return the repository
+ * @throws RepositoryException if any other error occurs
+ */
+ private Repository getRepository( String repositoryName ) throws RepositoryException {
+ return RepositoryFactory.getRepository(repositoryName);
+ }
+
+ /**
+ * Returns an active session for the given workspace name in the named repository.
+ *
+ * @param rawRepositoryName the URL-encoded name of the repository in which the session is created
+ * @param rawWorkspaceName the URL-endecoded name of the workspace to which the session should be connected
+ * @return an active session with the given workspace in the named repository
+ * @throws RepositoryException if any other error occurs
+ */
+ private Session getSession( String rawRepositoryName,
+ String rawWorkspaceName ) throws NotFoundException, RepositoryException {
+
+ Repository repository;
+ try {
+ repository = getRepository(repositoryNameFor(rawRepositoryName));
+ } catch (RepositoryException re) {
+ throw new NotFoundException(re.getMessage(), re);
+ }
+
+ Credentials credentials = new SimpleCredentials("dnauser", "password".toCharArray());
+
+ return repository.login(credentials, workspaceNameFor(rawWorkspaceName));
+ }
+
+ /**
* Returns the list of JCR repositories available on this server
+ *
+ * @param request the servlet request; may not be null
* @return the list of JCR repositories available on this server
*/
@GET
- @Path( "/repositories" )
- public String repositories() {
- return "Hello, DNA!";
+ @Path( "/" )
+ @Produces( "application/json" )
+ public Map getRepositories( @Context HttpServletRequest request ) {
+ assert request != null;
+
+ Map repositories = new HashMap();
+
+ for (String name : RepositoryFactory.getJcrRepositoryNames()) {
+ if (name.trim().length() == 0) {
+ name = EMPTY_REPOSITORY_NAME;
+ }
+ name = URL_ENCODER.encode(name);
+ repositories.put(name, new RepositoryEntry(request.getContextPath(), name));
+ }
+
+ return repositories;
}
/**
* Returns the list of workspaces available to this user within the named repository.
- * @param repositoryName the name of the repository
+ *
+ * @param rawRepositoryName the name of the repository; may not be null
+ * @param request the servlet request; may not be null
* @return the list of workspaces available to this user within the named repository.
+ * @throws IOException if the given repository name does not map to any repositories and there is an error writing the error
+ * code to the response.
+ * @throws RepositoryException if there is any other error accessing the list of available workspaces for the repository
*/
@GET
- @Path( "/{repositoryName}/workspaces" )
- public String workspaces( @PathParam( "repositoryName" ) String repositoryName ) {
+ @Path( "/{repositoryName}" )
+ @Produces( "application/json" )
+ public Map getWorkspaces( @Context HttpServletRequest request,
+ @PathParam( "repositoryName" ) String rawRepositoryName )
+ throws RepositoryException, IOException {
+
+ assert request != null;
+ assert rawRepositoryName != null;
+
+ Map workspaces = new HashMap();
+
+ Session session = getSession(rawRepositoryName, null);
+ rawRepositoryName = URL_ENCODER.encode(rawRepositoryName);
+
+ for (String name : session.getWorkspace().getAccessibleWorkspaceNames()) {
+ if (name.trim().length() == 0) {
+ name = EMPTY_WORKSPACE_NAME;
+ }
+ name = URL_ENCODER.encode(name);
+ workspaces.put(name, new WorkspaceEntry(request.getContextPath(), rawRepositoryName, name));
+ }
+
+ return workspaces;
+ }
+
+ /**
+ * Handles GET requests for an item in a workspace.
+ *
+ * @param rawRepositoryName the URL-encoded repository name
+ * @param rawWorkspaceName the URL-encoded workspace name
+ * @param path the path to the item
+ * @param depth the depth of the node graph that should be returned if {@code path} refers to a node. @{code 0} means return
+ * the requested node only. A negative value indicates that the full subgraph under the node should be returned. This
+ * parameter defaults to {@code 0} and is ignored if {@code path} refers to a property.
+ * @return the JSON-encoded version of the item (and, if the item is a node, its subgraph, depending on the value of {@code
+ * depth})
+ * @throws NotFoundException if the named repository does not exists, the named workspace does not exist, or the user does not
+ * have access to the named workspace
+ * @throws JSONException if there is an error encoding the node
+ * @throws UnauthorizedException if the given login information is invalid
+ * @throws RepositoryException if any other error occurs
+ * @see #EMPTY_REPOSITORY_NAME
+ * @see #EMPTY_WORKSPACE_NAME
+ * @see Session#getItem(String)
+ */
+ @GET
+ @Path( "/{repositoryName}/{workspaceName}/items{path:.*}" )
+ @Produces( "application/json" )
+ public String getItem( @PathParam( "repositoryName" ) String rawRepositoryName,
+ @PathParam( "workspaceName" ) String rawWorkspaceName,
+ @PathParam( "path" ) String path,
+ @QueryParam( "dna:depth" ) @DefaultValue( "0" ) int depth )
+ throws JSONException, UnauthorizedException, RepositoryException {
+ assert path != null;
+ assert rawRepositoryName != null;
+ assert rawWorkspaceName != null;
+
+ Session session = getSession(rawRepositoryName, rawWorkspaceName);
+ Item item;
+
+ if ("/".equals(path) || "".equals(path)) {
+ item = session.getRootNode();
+ } else {
+ try {
+ item = session.getItem(path);
+ } catch (PathNotFoundException pnfe) {
+ throw new NotFoundException(pnfe.getMessage(), pnfe);
+ }
+ }
+
+ if (item instanceof Node) {
+ return jsonFor((Node)item, depth).toString();
+ }
+ return jsonFor((Property)item);
+ }
+
+ /**
+ * Returns the JSON-encoded version of the given property. If the property is single-valued, the returned string is {@code
+ * property.getValue().getString()} encoded as a JSON string. If the property is multi-valued with {@code N} values, this
+ * method returns a JSON array containing {@code property.getValues()[N].getString()} for all values of {@code N}.
+ *
+ * @param property the property to be encoded
+ * @return the JSON-encoded version of the property
+ * @throws RepositoryException if an error occurs accessing the property, its values, or its definition.
+ * @see Property#getDefinition()
+ * @see PropertyDefinition#isMultiple()
+ */
+ private String jsonFor( Property property ) throws RepositoryException {
+ if (property.getDefinition().isMultiple()) {
+ Value[] values = property.getValues();
+ List list = new ArrayList(values.length);
+ for (int i = 0; i < values.length; i++) {
+ list.add(values[i].getString());
+ }
+ return new JSONArray(list).toString();
+ }
+ return JSONObject.quote(property.getValue().getString());
+ }
+
+ /**
+ * Recursively returns the JSON-encoding of a node and its children to depth {@code toDepth}.
+ *
+ * @param node the node to be encoded
+ * @param toDepth the depth to which the recursion should extend; {@code 0} means no further recursion should occur.
+ * @return the JSON-encoding of a node and its children to depth {@code toDepth}.
+ * @throws JSONException if there is an error encoding the node
+ * @throws RepositoryException if any other error occurs
+ */
+ private JSONObject jsonFor( Node node,
+ int toDepth ) throws JSONException, RepositoryException {
+ JSONObject jsonNode = new JSONObject();
+
+ JSONObject properties = new JSONObject();
+
+ for (PropertyIterator iter = node.getProperties(); iter.hasNext();) {
+ Property prop = iter.nextProperty();
+ String propName = prop.getName();
+
+ if (prop.getDefinition().isMultiple()) {
+ Value[] values = prop.getValues();
+ JSONArray array = new JSONArray();
+ for (int i = 0; i < values.length; i++) {
+ array.put(values[i].getString());
+ }
+ properties.put(propName, array);
+
+ } else {
+ properties.put(propName, prop.getValue().getString());
+ }
+
+ }
+ if (properties.length() > 0) {
+ jsonNode.put(PROPERTIES_HOLDER, properties);
+ }
+
+ if (toDepth == 0) {
+ List children = new ArrayList();
+
+ for (NodeIterator iter = node.getNodes(); iter.hasNext();) {
+ Node child = iter.nextNode();
+
+ children.add(child.getName());
+ }
+
+ if (children.size() > 0) {
+ jsonNode.put(CHILD_NODE_HOLDER, new JSONArray(children));
+ }
+ } else {
+ JSONObject children = new JSONObject();
+
+ for (NodeIterator iter = node.getNodes(); iter.hasNext();) {
+ Node child = iter.nextNode();
+
+ children.put(child.getName(), jsonFor(child, toDepth - 1));
+ }
+
+ if (children.length() > 0) {
+ jsonNode.put(CHILD_NODE_HOLDER, children);
+ }
+ }
+
+ return jsonNode;
+ }
+
+ /**
+ * Adds the content of the request as a node (or subtree of nodes) at the location specified by {@code path}.
+ *
+ * The primary type and mixin type(s) may optionally be specified through the {@code jcr:primaryType} and {@code
+ * jcr:mixinTypes} properties.
+ *
+ *
+ * @param rawRepositoryName the URL-encoded repository name
+ * @param rawWorkspaceName the URL-encoded workspace name
+ * @param path the path to the item
+ * @param requestContent the JSON-encoded representation of the node or nodes to be added
+ * @return the JSON-encoded representation of the node or nodes that were added. This will differ from {@code requestContent}
+ * in that auto-created and protected properties (e.g., jcr:uuid) will be populated.
+ * @throws NotFoundException if the parent of the item to be added does not exist
+ * @throws UnauthorizedException if the user does not have the access required to create the node at this path
+ * @throws JSONException if there is an error encoding the node
+ * @throws RepositoryException if any other error occurs
+ */
+ @POST
+ @Path( "/{repositoryName}/{workspaceName}/items/{path:.*}" )
+ @Consumes( "application/json" )
+ public Response postItem( @PathParam( "repositoryName" ) String rawRepositoryName,
+ @PathParam( "workspaceName" ) String rawWorkspaceName,
+ @PathParam( "path" ) String path,
+ String requestContent )
+ throws NotFoundException, UnauthorizedException, RepositoryException, JSONException {
+
+ assert rawRepositoryName != null;
+ assert rawWorkspaceName != null;
+ assert path != null;
+ JSONObject body = new JSONObject(requestContent);
+
+ int lastSlashInd = path.lastIndexOf('/');
+ String parentPath = lastSlashInd == -1 ? "/" : "/" + path.substring(0, lastSlashInd);
+ String newNodeName = lastSlashInd == -1 ? path : path.substring(lastSlashInd + 1);
+
+ Session session = getSession(rawRepositoryName, rawWorkspaceName);
+
+ Node parentNode = (Node)session.getItem(parentPath);
+
+ Node newNode = addNode(parentNode, newNodeName, body);
+
+ session.save();
+
+ String json = jsonFor(newNode, -1).toString();
+ return Response.status(Status.CREATED).entity(json).build();
+ }
+
+ /**
+ * Adds the node described by {@code jsonNode} with name {@code nodeName} to the existing node {@code parentNode}.
+ *
+ * @param parentNode the parent of the node to be added
+ * @param nodeName the name of the node to be added
+ * @param jsonNode the JSON-encoded representation of the node or nodes to be added.
+ * @return the JSON-encoded representation of the node or nodes that were added. This will differ from {@code requestContent}
+ * in that auto-created and protected properties (e.g., jcr:uuid) will be populated.
+ * @throws JSONException if there is an error encoding the node
+ * @throws RepositoryException if any other error occurs
+ */
+ private Node addNode( Node parentNode,
+ String nodeName,
+ JSONObject jsonNode ) throws RepositoryException, JSONException {
+ Node newNode;
+
+ JSONObject properties = jsonNode.has(PROPERTIES_HOLDER) ? jsonNode.getJSONObject(PROPERTIES_HOLDER) : new JSONObject();
+
+ if (properties.has(PRIMARY_TYPE_PROPERTY)) {
+ String primaryType = properties.getString(PRIMARY_TYPE_PROPERTY);
+ newNode = parentNode.addNode(nodeName, primaryType);
+ } else {
+ newNode = parentNode.addNode(nodeName);
+ }
+
+ if (properties.has(MIXIN_TYPES_PROPERTY)) {
+ Object rawMixinTypes = properties.get(MIXIN_TYPES_PROPERTY);
+
+ if (rawMixinTypes instanceof JSONArray) {
+ JSONArray mixinTypes = (JSONArray)rawMixinTypes;
+ for (int i = 0; i < mixinTypes.length(); i++) {
+ newNode.addMixin(mixinTypes.getString(i));
+ }
+
+ } else {
+ newNode.addMixin(rawMixinTypes.toString());
+
+ }
+ }
+
+ for (Iterator> iter = properties.keys(); iter.hasNext();) {
+ String key = (String)iter.next();
+
+ if (PRIMARY_TYPE_PROPERTY.equals(key)) continue;
+ if (MIXIN_TYPES_PROPERTY.equals(key)) continue;
+ setPropertyOnNode(newNode, key, properties.get(key));
+ }
+
+ if (jsonNode.has(CHILD_NODE_HOLDER)) {
+ JSONObject children = jsonNode.getJSONObject(CHILD_NODE_HOLDER);
+
+ for (Iterator> iter = children.keys(); iter.hasNext();) {
+ String childName = (String)iter.next();
+ JSONObject child = children.getJSONObject(childName);
+
+ addNode(newNode, childName, child);
+ }
+ }
+
+ return newNode;
+ }
+
+ /**
+ * Sets the named property on the given node. This method expects {@code value} to be either a JSON string or a JSON array of
+ * JSON strings. If {@code value} is a JSON array, {@code Node#setProperty(String, String[]) the multi-valued property setter}
+ * will be used.
+ *
+ * @param node the node on which the property is to be set
+ * @param propName the name of the property to set
+ * @param value the JSON-encoded values to be set
+ * @throws RepositoryException if there is an error setting the property
+ * @throws JSONException if {@code value} cannot be decoded
+ */
+ private void setPropertyOnNode( Node node,
+ String propName,
+ Object value ) throws RepositoryException, JSONException {
+ if (value instanceof JSONArray) {
+ JSONArray jsonValues = (JSONArray)value;
+ String[] values = new String[jsonValues.length()];
+
+ for (int i = 0; i < values.length; i++) {
+ values[i] = jsonValues.getString(i);
+ }
+ node.setProperty(propName, values);
+ } else {
+ node.setProperty(propName, (String)value);
+ }
+
+ }
+
+ /**
+ * Deletes the item at {@code path}.
+ *
+ * @param rawRepositoryName the URL-encoded repository name
+ * @param rawWorkspaceName the URL-encoded workspace name
+ * @param path the path to the item
+ * @throws NotFoundException if no item exists at {@code path}
+ * @throws UnauthorizedException if the user does not have the access required to delete the item at this path
+ * @throws RepositoryException if any other error occurs
+ */
+ @DELETE
+ @Path( "/{repositoryName}/{workspaceName}/items{path:.*}" )
+ @Consumes( "application/json" )
+ public void deleteItem( @PathParam( "repositoryName" ) String rawRepositoryName,
+ @PathParam( "workspaceName" ) String rawWorkspaceName,
+ @PathParam( "path" ) String path )
+ throws NotFoundException, UnauthorizedException, RepositoryException {
+
+ assert rawRepositoryName != null;
+ assert rawWorkspaceName != null;
+ assert path != null;
+
+ Session session = getSession(rawRepositoryName, rawWorkspaceName);
+
+ Item item;
+ try {
+ item = session.getItem(path);
+ } catch (PathNotFoundException pnfe) {
+ throw new NotFoundException(pnfe.getMessage(), pnfe);
+ }
+ item.remove();
+ session.save();
+ }
+
+ /**
+ * Updates the properties at the path.
+ *
+ * If path points to a property, this method expects the request content to be either a JSON array or a JSON string. The array
+ * or string will become the values or value of the property. If path points to a node, this method expects the request
+ * content to be a JSON object. The keys of the objects correspond to property names that will be set and the values for the
+ * keys correspond to the values that will be set on the properties.
+ *
+ *
+ * @param rawRepositoryName the URL-encoded repository name
+ * @param rawWorkspaceName the URL-encoded workspace name
+ * @param path the path to the item
+ * @param requestContent the JSON-encoded representation of the values and, possibly, properties to be set
+ * @return the JSON-encoded representation of the node on which the property or properties were set.
+ * @throws NotFoundException if the parent of the item to be added does not exist
+ * @throws UnauthorizedException if the user does not have the access required to create the node at this path
+ * @throws JSONException if there is an error encoding the node
+ * @throws RepositoryException if any other error occurs
+ */
+ @PUT
+ @Path( "/{repositoryName}/{workspaceName}/items{path:.*}" )
+ @Consumes( "application/json" )
+ public String putItem( @PathParam( "repositoryName" ) String rawRepositoryName,
+ @PathParam( "workspaceName" ) String rawWorkspaceName,
+ @PathParam( "path" ) String path,
+ String requestContent ) throws UnauthorizedException, JSONException, RepositoryException {
+
+ assert path != null;
+ assert rawRepositoryName != null;
+ assert rawWorkspaceName != null;
+
+ Session session = getSession(rawRepositoryName, rawWorkspaceName);
+ Node node;
+ Item item;
+ if ("".equals(path) || "/".equals(path)) {
+ item = session.getRootNode();
+ } else {
+ try {
+ item = session.getItem(path);
+ } catch (PathNotFoundException pnfe) {
+ throw new NotFoundException(pnfe.getMessage(), pnfe);
+ }
+ }
+
+ if (item instanceof Node) {
+ JSONObject properties = new JSONObject(requestContent);
+ node = (Node)item;
+
+ for (Iterator> iter = properties.keys(); iter.hasNext();) {
+ String key = (String)iter.next();
+
+ setPropertyOnNode(node, key, properties.get(key));
+ }
+
+ } else {
+ /*
+ * The incoming content should be a JSON string or a JSON array. Wrap it into an object so it can be parsed more easily
+ */
+
+ JSONObject properties = new JSONObject("{ \"value\": " + requestContent + "}");
+ Property property = (Property)item;
+ node = property.getParent();
+
+ setPropertyOnNode(node, property.getName(), properties.get("value"));
+ }
+
+ return jsonFor(node, 0).toString();
+ }
+
+ private String workspaceNameFor( String rawWorkspaceName ) {
+ String workspaceName = URL_ENCODER.decode(rawWorkspaceName);
+
+ if (EMPTY_WORKSPACE_NAME.equals(workspaceName)) {
+ workspaceName = "";
+ }
+
+ return workspaceName;
+ }
+
+ private String repositoryNameFor( String rawRepositoryName ) {
+ String repositoryName = URL_ENCODER.decode(rawRepositoryName);
+
+ if (EMPTY_REPOSITORY_NAME.equals(repositoryName)) {
+ repositoryName = "";
+ }
+
return repositoryName;
}
+ @Provider
+ public static class NotFoundExceptionMapper implements ExceptionMapper {
+
+ public Response toResponse( NotFoundException exception ) {
+ return Response.status(Status.NOT_FOUND).entity(exception.getMessage()).build();
+ }
+
+ }
+
+ @Provider
+ public static class JSONExceptionMapper implements ExceptionMapper {
+
+ public Response toResponse( JSONException exception ) {
+ return Response.status(Status.BAD_REQUEST).entity(exception.getMessage()).build();
+ }
+
+ }
+
+ @Provider
+ public static class RepositoryExceptionMapper implements ExceptionMapper {
+
+ public Response toResponse( RepositoryException exception ) {
+ /*
+ * This error code is murky - the request must have been syntactically valid to get to
+ * the JCR operations, but there isn't an HTTP status code for "semantically invalid."
+ */
+ return Response.status(Status.BAD_REQUEST).entity(exception.getMessage()).build();
+ }
+
+ }
+
}
Index: extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/model/RepositoryEntry.java
===================================================================
--- extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/model/RepositoryEntry.java (revision 0)
+++ extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/model/RepositoryEntry.java (revision 0)
@@ -0,0 +1,32 @@
+package org.jboss.dna.web.jcr.rest.model;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement( name = "repository" )
+public class RepositoryEntry {
+
+ private String name;
+ private RepositoryResources resources;
+
+ public RepositoryEntry() {
+ resources = new RepositoryResources();
+ }
+
+ public RepositoryEntry( String contextName,
+ String repositoryName ) {
+ this.name = repositoryName;
+
+ resources = new RepositoryResources(contextName, repositoryName);
+ }
+
+ @XmlElement
+ public String getName() {
+ return name;
+ }
+
+ @XmlElement
+ public RepositoryResources getResources() {
+ return resources;
+ }
+}
Property changes on: extensions\dna-web-jcr-rest\src\main\java\org\jboss\dna\web\jcr\rest\model\RepositoryEntry.java
___________________________________________________________________
Added: svn:keywords
+ Id Revision
Added: svn:eol-style
+ LF
Index: extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/model/RepositoryResources.java
===================================================================
--- extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/model/RepositoryResources.java (revision 0)
+++ extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/model/RepositoryResources.java (revision 0)
@@ -0,0 +1,21 @@
+package org.jboss.dna.web.jcr.rest.model;
+
+import javax.xml.bind.annotation.XmlElement;
+
+public class RepositoryResources {
+ private String baseUri;
+
+ public RepositoryResources() {
+ }
+
+ public RepositoryResources( String contextName,
+ String repositoryName ) {
+ this.baseUri = contextName + "/" + repositoryName;
+ }
+
+ @XmlElement( name = "workspaces" )
+ public String getWorkspaces() {
+ return baseUri;
+ }
+}
+
Property changes on: extensions\dna-web-jcr-rest\src\main\java\org\jboss\dna\web\jcr\rest\model\RepositoryResources.java
___________________________________________________________________
Added: svn:keywords
+ Id Revision
Added: svn:eol-style
+ LF
Index: extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/model/WorkspaceEntry.java
===================================================================
--- extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/model/WorkspaceEntry.java (revision 0)
+++ extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/model/WorkspaceEntry.java (revision 0)
@@ -0,0 +1,34 @@
+package org.jboss.dna.web.jcr.rest.model;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement( name = "workspace" )
+public class WorkspaceEntry {
+
+ private String name;
+ private WorkspaceResources resources;
+
+ public WorkspaceEntry() {
+
+ }
+
+ public WorkspaceEntry( String contextName,
+ String repositoryName,
+ String workspaceName ) {
+ this.name = workspaceName;
+
+ resources = new WorkspaceResources(contextName, repositoryName, workspaceName);
+ }
+
+ @XmlElement
+ public String getName() {
+ return name;
+ }
+
+ @XmlElement
+ public WorkspaceResources getResources() {
+ return resources;
+ }
+}
+
Property changes on: extensions\dna-web-jcr-rest\src\main\java\org\jboss\dna\web\jcr\rest\model\WorkspaceEntry.java
___________________________________________________________________
Added: svn:keywords
+ Id Revision
Added: svn:eol-style
+ LF
Index: extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/model/WorkspaceResources.java
===================================================================
--- extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/model/WorkspaceResources.java (revision 0)
+++ extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/model/WorkspaceResources.java (revision 0)
@@ -0,0 +1,22 @@
+package org.jboss.dna.web.jcr.rest.model;
+
+import javax.xml.bind.annotation.XmlElement;
+
+public class WorkspaceResources {
+ private String baseUri;
+
+ public WorkspaceResources() {
+ }
+
+ public WorkspaceResources( String contextName,
+ String repositoryName,
+ String workspaceName ) {
+ this.baseUri = contextName + "/" + repositoryName + "/" + workspaceName;
+ }
+
+ @XmlElement( name = "items" )
+ public String getWorkspaces() {
+ return baseUri + "/items";
+ }
+}
+
Property changes on: extensions\dna-web-jcr-rest\src\main\java\org\jboss\dna\web\jcr\rest\model\WorkspaceResources.java
___________________________________________________________________
Added: svn:keywords
+ Id Revision
Added: svn:eol-style
+ LF
Index: extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/RepositoryFactory.java
===================================================================
--- extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/RepositoryFactory.java (revision 0)
+++ extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/RepositoryFactory.java (revision 0)
@@ -0,0 +1,41 @@
+package org.jboss.dna.web.jcr.rest;
+
+import java.util.Collection;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.servlet.ServletContext;
+import org.jboss.dna.web.jcr.rest.spi.RepositoryProvider;
+
+public class RepositoryFactory {
+
+ public static final String PROVIDER_KEY = "org.jboss.dna.web.jcr.rest.REPOSITORY_PROVIDER";
+
+ private static RepositoryProvider provider;
+
+ private RepositoryFactory() {
+
+ }
+
+ static void initialize( ServletContext context ) {
+ String className = context.getInitParameter(PROVIDER_KEY);
+
+ try {
+ Class extends RepositoryProvider> providerClass = Class.forName(className).asSubclass(RepositoryProvider.class);
+ provider = providerClass.newInstance();
+ } catch (Exception ex) {
+ throw new IllegalStateException(ex);
+ }
+ }
+
+ public static Repository getRepository( String repositoryName ) throws RepositoryException {
+ return provider.getRepository(repositoryName);
+ }
+
+ public static Collection getJcrRepositoryNames() {
+ return provider.getJcrRepositoryNames();
+ }
+
+ static void shutdown() {
+ provider.shutdown();
+ }
+}
Property changes on: extensions\dna-web-jcr-rest\src\main\java\org\jboss\dna\web\jcr\rest\RepositoryFactory.java
___________________________________________________________________
Added: svn:keywords
+ Id Revision
Added: svn:eol-style
+ LF
Index: extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/spi/DnaJcrRepositoryProvider.java
===================================================================
--- extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/spi/DnaJcrRepositoryProvider.java (revision 0)
+++ extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/spi/DnaJcrRepositoryProvider.java (revision 0)
@@ -0,0 +1,46 @@
+package org.jboss.dna.web.jcr.rest.spi;
+
+import java.util.HashSet;
+import java.util.Set;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource;
+import org.jboss.dna.jcr.JcrConfiguration;
+import org.jboss.dna.jcr.JcrEngine;
+
+public class DnaJcrRepositoryProvider implements RepositoryProvider {
+
+ private JcrEngine jcrEngine;
+
+ public DnaJcrRepositoryProvider() {
+ jcrEngine = new JcrConfiguration().withConfigurationRepository()
+ .usingClass(InMemoryRepositorySource.class.getName())
+ .loadedFromClasspath()
+ .describedAs("Configuration Repository")
+ .with("name").setTo("configuration")
+ .with("retryLimit")
+ .setTo(5)
+ .and()
+ .addRepository("Source2")
+ .usingClass(InMemoryRepositorySource.class.getName())
+ .loadedFromClasspath()
+ .describedAs("description")
+ .with("name").setTo("JCR Repository")
+ .and()
+ .build();
+ jcrEngine.start();
+
+ }
+
+ public Set getJcrRepositoryNames() {
+ return new HashSet(jcrEngine.getJcrRepositoryNames());
+ }
+
+ public Repository getRepository( String repositoryName ) throws RepositoryException {
+ return jcrEngine.getRepository(repositoryName);
+ }
+
+ public void shutdown() {
+ jcrEngine.shutdown();
+ }
+}
Property changes on: extensions\dna-web-jcr-rest\src\main\java\org\jboss\dna\web\jcr\rest\spi\DnaJcrRepositoryProvider.java
___________________________________________________________________
Added: svn:keywords
+ Id Revision
Added: svn:eol-style
+ LF
Index: extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/spi/RepositoryProvider.java
===================================================================
--- extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/spi/RepositoryProvider.java (revision 0)
+++ extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/spi/RepositoryProvider.java (revision 0)
@@ -0,0 +1,35 @@
+package org.jboss.dna.web.jcr.rest.spi;
+
+import java.util.Set;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+
+/**
+ * Interface for any class that provides access to one or more local JCR repositories. Repository providers must provide a public,
+ * no-argument constructor.
+ */
+public interface RepositoryProvider {
+
+ /**
+ * Returns a reference to the named repository
+ *
+ * @param repositoryName the name of the repository to retrieve; may be null
+ * @return the repository with the given name; may not be null
+ * @throws RepositoryException if no repository with the given name exists or there is an error obtaining a reference to the
+ * named repository
+ */
+ Repository getRepository( String repositoryName ) throws RepositoryException;
+
+ /**
+ * Returns the available repository names
+ *
+ * @return the available repository names; may not be null
+ */
+ Set getJcrRepositoryNames();
+
+ /**
+ * Signals the repository provider that it should complete any pending transactions, shutdown, and release
+ * any external resource held.
+ */
+ void shutdown();
+}
Property changes on: extensions\dna-web-jcr-rest\src\main\java\org\jboss\dna\web\jcr\rest\spi\RepositoryProvider.java
___________________________________________________________________
Added: svn:keywords
+ Id Revision
Added: svn:eol-style
+ LF
Index: extensions/dna-web-jcr-rest/src/main/webapp/WEB-INF/web.xml
===================================================================
--- extensions/dna-web-jcr-rest/src/main/webapp/WEB-INF/web.xml (revision 938)
+++ extensions/dna-web-jcr-rest/src/main/webapp/WEB-INF/web.xml (working copy)
@@ -1,54 +1,65 @@
-
+
+ JBoss DNA JCR RESTful Interface
- JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
- is licensed to you 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.
+
+ org.jboss.dna.web.jcr.rest.REPOSITORY_PROVIDER
+ org.jboss.dna.web.jcr.rest.spi.DnaJcrRepositoryProvider
+
- JBoss DNA 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.
+
+ resteasy.providers
+ org.jboss.dna.web.jcr.rest.JcrResources$NotFoundExceptionMapper,
+ org.jboss.dna.web.jcr.rest.JcrResources$JSONExceptionMapper,
+ org.jboss.dna.web.jcr.rest.JcrResources$RepositoryExceptionMapper
+
+
- 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.
+
+ javax.ws.rs.core.Application
+ org.jboss.dna.web.jcr.rest.JcrApplication
+
- -->
-
- JBoss DNA JCR RESTful Interface
+
+
+ org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
+
+
-
- javax.ws.rs.core.Application
- org.jboss.dna.web.jcr.rest.JcrApplication
-
+
+ org.jboss.dna.web.jcr.rest.DnaJcrDeployer
+
-
-
- org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
-
-
-
-
- Resteasy
-
- org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
+
+ Resteasy
+
+ org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
-
+
-
- Resteasy
- /*
-
+
+ Resteasy
+ /*
+
\ No newline at end of file
Index: extensions/dna-web-jcr-rest/src/test/java/org/jboss/dna/web/jcr/rest/JcrResourcesTest.java
===================================================================
--- extensions/dna-web-jcr-rest/src/test/java/org/jboss/dna/web/jcr/rest/JcrResourcesTest.java (revision 938)
+++ extensions/dna-web-jcr-rest/src/test/java/org/jboss/dna/web/jcr/rest/JcrResourcesTest.java (working copy)
@@ -1,75 +0,0 @@
-/*
- * JBoss DNA (http://www.jboss.org/dna)
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership. Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- * See the AUTHORS.txt file in the distribution for a full listing of
- * individual contributors.
- *
- * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
- * is licensed to you 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.
- *
- * JBoss DNA 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.jboss.dna.web.jcr.rest;
-
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-import org.jboss.resteasy.client.ClientRequest;
-import org.jboss.resteasy.client.ClientResponse;
-import org.junit.Ignore;
-import org.junit.Test;
-
-public class JcrResourcesTest {
-
- private static final String SERVER_URL = "http://localhost:8080/resources";
-
- private ClientRequest request;
- private ClientResponse> response;
-
- private ClientRequest requestFor(String path) {
- return new ClientRequest(SERVER_URL + path);
- }
-
- @Ignore
- @Test
- public void shouldServeContentAtRoot() throws Exception {
- request = requestFor("/");
-
- response = request.get();
-
- assertThat(response.getStatus(), is(200));
-
- }
-
- @Test
- public void shouldServeListOfRepositories() throws Exception {
- request = requestFor("/repositories");
-
- response = request.get();
-
- assertThat(response.getStatus(), is(200));
-
- }
-
- @Test
- public void shouldServeListOfWorkspaces() throws Exception {
- String validRepositoryName = "foo"; // Stub this for now
- request = requestFor("/" + validRepositoryName + "/workspaces");
-
- response = request.get();
-
- assertThat(response.getStatus(), is(200));
- }
-
-}