]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-173, CSPACE-325, CSPACE-71, CSPACE-72, CSPACE-73, CSPACE-74. Introduced key...
authorSanjay Dalal <sanjay.dalal@berkeley.edu>
Fri, 24 Jul 2009 18:29:44 +0000 (18:29 +0000)
committerSanjay Dalal <sanjay.dalal@berkeley.edu>
Fri, 24 Jul 2009 18:29:44 +0000 (18:29 +0000)
40 files changed:
services/JaxRsServiceProvider/pom.xml
services/JaxRsServiceProvider/src/main/java/org/collectionspace/services/jaxrs/CollectionSpaceJaxRsApplication.java
services/JaxRsServiceProvider/src/main/webapp/WEB-INF/jboss-web.xml
services/collectionobject/client/src/test/java/org/collectionspace/services/client/test/CollectionObjectServiceTest.java
services/collectionobject/service/pom.xml
services/collectionobject/service/src/main/java/org/collectionspace/services/CollectionObjectResource.java [deleted file]
services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/CollectionObjectResource.java [new file with mode: 0644]
services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/CollectionObjectService.java [moved from services/collectionobject/service/src/main/java/org/collectionspace/services/CollectionObjectService.java with 90% similarity]
services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/nuxeo/CollectionObjectConstants.java [new file with mode: 0644]
services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/nuxeo/CollectionObjectDocumentModelHandler.java [new file with mode: 0644]
services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/nuxeo/CollectionObjectHandlerFactory.java [new file with mode: 0644]
services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/nuxeo/CollectionObjectRepresenationHandler.java [new file with mode: 0644]
services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/nuxeo/CollectionObjectServiceNuxeoImpl.java [moved from services/collectionobject/service/src/main/java/org/collectionspace/services/CollectionObjectServiceNuxeoImpl.java with 85% similarity]
services/common/src/main/config/service-config.xml
services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java
services/common/src/main/java/org/collectionspace/services/common/repository/BadRequestException.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/common/repository/DocumentException.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/common/repository/DocumentHandler.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/common/repository/DocumentNotFoundException.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/common/repository/DocumentWrapper.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/common/repository/RepositoryClient.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/common/repository/RepositoryClientFactory.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/nuxeo/CollectionSpaceServiceNuxeoImpl.java
services/common/src/main/java/org/collectionspace/services/nuxeo/NuxeoCallback.java [deleted file]
services/common/src/main/java/org/collectionspace/services/nuxeo/NuxeoCallbackHandler.java [deleted file]
services/common/src/main/java/org/collectionspace/services/nuxeo/NuxeoLoginConfiguration.java [deleted file]
services/common/src/main/java/org/collectionspace/services/nuxeo/NuxeoLoginContextFactory.java [deleted file]
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/DocumentModelHandler.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/DocumentModelListWrapper.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/DocumentModelWrapper.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoConnector.java [moved from services/common/src/main/java/org/collectionspace/services/nuxeo/NuxeoConnector.java with 89% similarity]
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryJavaClient.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/nuxeo/client/rest/NuxeoRESTClient.java [moved from services/common/src/main/java/org/collectionspace/services/nuxeo/NuxeoRESTClient.java with 76% similarity]
services/common/src/main/java/org/collectionspace/services/nuxeo/client/rest/PortalSSOAuthenticationProvider.java [moved from services/common/src/main/java/org/collectionspace/services/nuxeo/PortalSSOAuthenticationProvider.java with 97% similarity]
services/common/src/main/java/org/collectionspace/services/nuxeo/client/rest/RepositoryRESTClient.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/nuxeo/client/rest/RepresentationHandler.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/nuxeo/client/rest/RepresentationWrapper.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/nuxeo/util/NuxeoUtils.java [moved from services/common/src/main/java/org/collectionspace/services/nuxeo/NuxeoUtils.java with 59% similarity]
services/common/src/main/resources/service-config.xsd
services/intake/service/src/main/java/org/collectionspace/services/IntakeServiceNuxeoImpl.java

index 80073564a6200099463975051acaf7990d918feb..a57a6c969bd09d34ee9861e15b5fa5ccae76e385 100644 (file)
@@ -24,8 +24,8 @@
         <nuxeo.version.5.2>5.2-SNAPSHOT</nuxeo.version.5.2>\r
         <nuxeo.version.1.5>1.5-SNAPSHOT</nuxeo.version.1.5>\r
     </properties>\r
-    \r
-    \r
+\r
+\r
     <dependencies>\r
         <dependency>\r
             <groupId>org.collectionspace.services</groupId>\r
@@ -74,9 +74,9 @@
             <version>4.1</version>\r
             <scope>test</scope>\r
         </dependency>\r
-        \r
+\r
         <!-- javax -->\r
-        \r
+\r
         <!-- jboss -->\r
         <dependency>\r
             <groupId>jboss</groupId>\r
         </dependency>\r
 \r
     </dependencies>\r
-    \r
+\r
     <build>\r
         <finalName>cspace-services</finalName>\r
         <plugins>\r
                         <goals>\r
                             <goal>undeploy</goal>\r
                         </goals>\r
+                        <phase>pre-integration-test</phase>\r
                         <configuration>\r
                             <fileNames>\r
                                 <param>${project.build.directory}/${project.build.finalName}.war</param>\r
                         <goals>\r
                             <goal>deploy</goal>\r
                         </goals>\r
+                        <phase>pre-integration-test</phase>\r
                         <configuration>\r
                             <fileNames>\r
                                 <param>${project.build.directory}/${project.build.finalName}.war</param>\r
         </plugins>\r
     </build>\r
 </project>\r
+\r
index f5d9fe086055526ddd4c52527d9f49985c926af9..d9f1845fe398e174ec63478bac34084fc78c2ade 100644 (file)
@@ -1,6 +1,6 @@
 package org.collectionspace.services.jaxrs;
 
-import org.collectionspace.services.CollectionObjectResource;
+import org.collectionspace.services.collectionobject.CollectionObjectResource;
 import org.collectionspace.services.id.IDResource;
 import org.collectionspace.services.IntakeResource;
 
index c91efe0843df09aa89484f29076010fd5bb33af9..33a2262182f718600c02d1540e26ad14b9cef530 100644 (file)
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>\r
 <jboss-web>\r
-     <!-- All secure web resources will use this security domain -->\r
-    <security-domain>java:/jaas/cspace</security-domain>\r
-</jboss-web>
\ No newline at end of file
+  <!-- All secure web resources will use this security domain -->\r
+  <security-domain>java:/jaas/cspace</security-domain>\r
+  <context-root>/cspace-services</context-root>\r
+</jboss-web>\r
index 093400cc83442f4561877a65246c5db472e480e4..f9d778bd7f8cb0cd43c0eb53386fba121b3863b5 100644 (file)
@@ -34,6 +34,7 @@ public class CollectionObjectServiceTest {
 
         CollectionObject collectionObject = createCollectionObject(identifier);
         ClientResponse<Response> res = collectionObjectClient.createCollectionObject(collectionObject);
+        verbose("createCollectionObject: status = " + res.getStatus());
         Assert.assertEquals(res.getStatus(), Response.Status.CREATED.getStatusCode());
 
         //store updateId locally for "update" test
@@ -48,6 +49,7 @@ public class CollectionObjectServiceTest {
     @Test(dependsOnMethods = {"createCollectionObject"})
     public void updateCollectionObject() {
         ClientResponse<CollectionObject> res = collectionObjectClient.getCollectionObject(updateId);
+        verbose("getCollectionObject: status = " + res.getStatus());
         CollectionObject collectionObject = res.getEntity();
         verbose("Got CollectionObject to update with ID: " + updateId,
                 collectionObject, CollectionObject.class);
@@ -58,7 +60,7 @@ public class CollectionObjectServiceTest {
 
         // make call to update service
         res = collectionObjectClient.updateCollectionObject(updateId, collectionObject);
-
+        verbose("updateCollectionObject: status = " + res.getStatus());
         // check the response
         CollectionObject updatedCollectionObject = res.getEntity();
         Assert.assertEquals(updatedCollectionObject.getObjectName(), collectionObject.getObjectName());
@@ -77,7 +79,10 @@ public class CollectionObjectServiceTest {
     @Test(dependsOnMethods = {"createCollection"})
     public void getCollectionObjectList() {
         //the resource method is expected to return at least an empty list
-        CollectionObjectList coList = collectionObjectClient.getCollectionObjectList().getEntity();
+        ClientResponse<CollectionObjectList> res = collectionObjectClient.getCollectionObjectList();
+        CollectionObjectList coList = res.getEntity();
+        verbose("getCollectionObjectList: status = " + res.getStatus());
+
         List<CollectionObjectList.CollectionObjectListItem> coItemList = coList.getCollectionObjectListItem();
         int i = 0;
         for(CollectionObjectList.CollectionObjectListItem pli : coItemList){
@@ -94,7 +99,7 @@ public class CollectionObjectServiceTest {
         ClientResponse<Response> res = collectionObjectClient.deleteCollectionObject(deleteId);
         verbose("deleteCollectionObject: csid=" + deleteId);
         verbose("deleteCollectionObject: status = " + res.getStatus());
-        Assert.assertEquals(res.getStatus(), Response.Status.NO_CONTENT.getStatusCode());
+        Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode());
     }
 
     private CollectionObject createCollectionObject(long identifier) {
index 203fc596fc20dc5ef0ee6ff9d07e9ec3d47369aa..a040d515c89845c8c25e1971cfbb85624ed2001f 100644 (file)
             <artifactId>org.collectionspace.services.collectionobject.jaxb</artifactId>\r
             <version>1.0</version>\r
         </dependency>\r
+        <dependency>\r
+            <groupId>org.slf4j</groupId>\r
+            <artifactId>slf4j-api</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.slf4j</groupId>\r
+            <artifactId>slf4j-log4j12</artifactId>\r
+        </dependency>\r
         \r
         <dependency>\r
             <groupId>junit</groupId>\r
             <version>5.6</version>\r
         </dependency>\r
         \r
-\r
+        <!-- apache -->\r
+        <dependency>\r
+            <groupId>commons-beanutils</groupId>\r
+            <artifactId>commons-beanutils</artifactId>\r
+            <version>1.6.1</version>\r
+        </dependency>\r
+        <!-- use explict 1.1 version to prevent errors coming from Nuxeo client -->\r
+        <dependency>\r
+            <groupId>commons-logging</groupId>\r
+            <artifactId>commons-logging</artifactId>\r
+            <version>1.1</version>\r
+        </dependency>\r
       <!-- javax -->\r
 \r
 \r
diff --git a/services/collectionobject/service/src/main/java/org/collectionspace/services/CollectionObjectResource.java b/services/collectionobject/service/src/main/java/org/collectionspace/services/CollectionObjectResource.java
deleted file mode 100644 (file)
index 28b6ea9..0000000
+++ /dev/null
@@ -1,266 +0,0 @@
-package org.collectionspace.services;
-
-import java.util.Iterator;
-import java.util.List;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriBuilder;
-import javax.ws.rs.core.UriInfo;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.Marshaller;
-
-import org.collectionspace.services.CollectionObjectService;
-import org.collectionspace.services.collectionobject.*;
-import org.collectionspace.services.collectionobject.CollectionObjectList.*;
-import org.collectionspace.services.CollectionObjectJAXBSchema;
-
-import org.dom4j.Document;
-import org.dom4j.Element;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Path("/collectionobjects")
-@Consumes("application/xml")
-@Produces("application/xml")
-public class CollectionObjectResource {
-
-       final Logger logger = LoggerFactory
-                       .getLogger(CollectionObjectResource.class);
-
-       // This should be a DI wired by a container like Spring, Seam, or EJB3
-       final static CollectionObjectService service = new CollectionObjectServiceNuxeoImpl();
-
-       public CollectionObjectResource() {
-               // do nothing
-       }
-
-       @GET
-       public CollectionObjectList getCollectionObjectList(@Context UriInfo ui) {
-               CollectionObjectList p = new CollectionObjectList();
-               try {
-                       Document document = service.getCollectionObjectList();
-                       Element root = document.getRootElement();
-
-                       // debug
-                       System.err.println(document.asXML());
-
-                       List<CollectionObjectList.CollectionObjectListItem> list = p
-                                       .getCollectionObjectListItem();
-                       for (Iterator i = root.elementIterator(); i.hasNext();) {
-                               Element element = (Element) i.next();
-                               // debug
-                               System.err.println();
-                               element.asXML();
-
-                               // set the CollectionObject list item entity elements
-                               CollectionObjectListItem pli = new CollectionObjectListItem();
-                               pli.setObjectNumber(element.attributeValue("title"));
-                               pli.setUri(element.attributeValue("url"));
-                               pli.setCsid(element.attributeValue("id"));
-                               list.add(pli);
-                       }
-
-               } catch (Exception e) {
-                       e.printStackTrace();
-               }
-
-               return p;
-       }
-
-       @POST
-       public Response createCollectionObject(CollectionObject co) {
-               
-               String csid = null;
-               try {
-
-                       Document document = service.postCollectionObject(co);
-                       Element root = document.getRootElement();
-                       for (Iterator i = root.elementIterator(); i.hasNext();) {
-                               Element element = (Element) i.next();
-                               if ("docRef".equals(element.getName())) {
-                                       csid = (String) element.getData();
-                                       co.setCsid(csid);
-                               }
-                       }
-               } catch (Exception e) {
-                       Response response = Response.status(Response.Status.NOT_FOUND)
-                                       .entity("Create failed").type("text/plain").build();
-                       throw new WebApplicationException(response);
-               }
-
-               verbose("createCollectionObject: ", co);
-               UriBuilder path = UriBuilder
-                               .fromResource(CollectionObjectResource.class);
-               path.path("" + csid);
-               Response response = Response.created(path.build()).build();
-
-               return response;
-       }
-
-       @GET
-       @Path("{csid}")
-       public CollectionObject getCollectionObject(@PathParam("csid") String csid) {
-
-               CollectionObject co = null;
-               try {
-                       Document document = service.getCollectionObject(csid);
-                       Element root = document.getRootElement();
-                       co = new CollectionObject();
-
-                       // TODO: recognize schema thru namespace uri
-                       // Namespace ns = new Namespace("collectionobject",
-                       // "http://collectionspace.org/collectionobject");
-
-                       Iterator<Element> siter = root.elementIterator("schema");
-                       while (siter.hasNext()) {
-
-                               Element schemaElement = siter.next();
-                               System.err
-                                               .println("CollectionObject.getCollectionObject() called.");
-
-                               // TODO: recognize schema thru namespace uri
-                               if (CollectionObjectService.CO_SCHEMA_NAME.equals(schemaElement.attribute("name")
-                                               .getValue())) {
-                                       Element ele = schemaElement
-                                                       .element(CollectionObjectJAXBSchema.OBJECT_NUMBER);
-                                       if (ele != null) {
-                                               co.setObjectNumber((String) ele.getData());
-                                       }
-                                       ele = schemaElement
-                                                       .element(CollectionObjectJAXBSchema.OTHER_NUMBER);
-                                       if (ele != null) {
-                                               co.setOtherNumber((String) ele.getData());
-                                       }
-                                       ele = schemaElement
-                                                       .element(CollectionObjectJAXBSchema.BRIEF_DESCRIPTION);
-                                       if (ele != null) {
-                                               co.setBriefDescription((String) ele.getData());
-                                       }
-                                       ele = schemaElement
-                                                       .element(CollectionObjectJAXBSchema.COMMENTS);
-                                       if (ele != null) {
-                                               co.setComments((String) ele.getData());
-                                       }
-                                       ele = schemaElement
-                                                       .element(CollectionObjectJAXBSchema.DIST_FEATURES);
-                                       if (ele != null) {
-                                               co.setDistFeatures((String) ele.getData());
-                                       }
-                                       ele = schemaElement
-                                                       .element(CollectionObjectJAXBSchema.OBJECT_NAME);
-                                       if (ele != null) {
-                                               co.setObjectName((String) ele.getData());
-                                       }
-                                       ele = schemaElement
-                                                       .element(CollectionObjectJAXBSchema.RESPONSIBLE_DEPT);
-                                       if (ele != null) {
-                                               co.setResponsibleDept((String) ele.getData());
-                                       }
-                                       ele = schemaElement
-                                                       .element(CollectionObjectJAXBSchema.TITLE);
-                                       if (ele != null) {
-                                               co.setTitle((String) ele.getData());
-                                       }
-                               }
-                       }
-               } catch (Exception e) {
-                       e.printStackTrace();
-                       Response response = Response.status(
-                                       Response.Status.INTERNAL_SERVER_ERROR).entity("Get failed")
-                                       .type("text/plain").build();
-                       throw new WebApplicationException(response);
-               }
-               if (co == null) {
-                       Response response = Response.status(Response.Status.NOT_FOUND)
-                                       .entity(
-                                                       "Get failed, the requested CollectionObject CSID:"
-                                                                       + csid + ": was not found.").type(
-                                                       "text/plain").build();
-                       throw new WebApplicationException(response);
-               }
-               verbose("getCollectionObject: ", co);
-
-               return co;
-       }
-
-       @PUT
-       @Path("{csid}")
-       public CollectionObject updateCollectionObject(
-                       @PathParam("csid") String csid, CollectionObject theUpdate) {
-
-               verbose("updateCollectionObject with input: ", theUpdate);
-
-               String status = null;
-               try {
-
-                       Document document = service.putCollectionObject(csid, theUpdate);
-                       Element root = document.getRootElement();
-                       for (Iterator i = root.elementIterator(); i.hasNext();) {
-                               Element element = (Element) i.next();
-                               if ("docRef".equals(element.getName())) {
-                                       status = (String) element.getData();
-                                       verbose("updateCollectionObject response: " + status);
-                               }
-                       }
-               } catch (Exception e) {
-                       // FIXME: NOT_FOUND?
-                       Response response = Response.status(Response.Status.NOT_FOUND)
-                                       .entity("Update failed ").type("text/plain").build();
-                       throw new WebApplicationException(response);
-               }
-
-               return theUpdate;
-       }
-
-       @DELETE
-       @Path("{csid}")
-       public void deleteCollectionObject(@PathParam("csid") String csid) {
-
-               verbose("deleteCollectionObject with csid=" + csid);
-               try {
-                       
-                       Document document = service.deleteCollectionObject(csid);
-                       Element root = document.getRootElement();
-                       for (Iterator i = root.elementIterator(); i.hasNext();) {
-                               Element element = (Element) i.next();
-                               if ("docRef".equals(element.getName())) {
-                                       String status = (String) element.getData();
-                                       verbose("deleteCollectionObjectt response: " + status);
-                               }
-                       }
-               } catch (Exception e) {
-                       // FIXME: NOT_FOUND?
-                       Response response = Response.status(Response.Status.NOT_FOUND)
-                                       .entity("Delete failed ").type("text/plain").build();
-                       throw new WebApplicationException(response);
-               }
-
-       }
-
-       private void verbose(String msg, CollectionObject co) {
-               try {
-                       verbose(msg);
-                       JAXBContext jc = JAXBContext.newInstance(CollectionObject.class);
-
-                       Marshaller m = jc.createMarshaller();
-                       m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
-                       m.marshal(co, System.out);
-               } catch (Exception e) {
-                       e.printStackTrace();
-               }
-       }
-
-       private void verbose(String msg) {
-               System.out.println("CollectionObjectResource. " + msg);
-       }
-
-}
diff --git a/services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/CollectionObjectResource.java b/services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/CollectionObjectResource.java
new file mode 100644 (file)
index 0000000..25daff7
--- /dev/null
@@ -0,0 +1,243 @@
+package org.collectionspace.services.collectionobject;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
+
+import org.collectionspace.services.collectionobject.CollectionObjectList.*;
+
+import org.collectionspace.services.collectionobject.nuxeo.CollectionObjectConstants;
+import org.collectionspace.services.collectionobject.nuxeo.CollectionObjectHandlerFactory;
+import org.collectionspace.services.common.NuxeoClientType;
+import org.collectionspace.services.common.ServiceMain;
+import org.collectionspace.services.common.repository.DocumentNotFoundException;
+import org.collectionspace.services.common.repository.DocumentHandler;
+import org.collectionspace.services.common.repository.RepositoryClient;
+import org.collectionspace.services.common.repository.RepositoryClientFactory;
+import org.jboss.resteasy.util.HttpResponseCodes;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Path("/collectionobjects")
+@Consumes("application/xml")
+@Produces("application/xml")
+public class CollectionObjectResource {
+
+    public final static String CO_SERVICE_NAME = "collectionobjects";
+    final Logger logger = LoggerFactory.getLogger(CollectionObjectResource.class);
+    //FIXME retrieve client type from configuration
+    final static NuxeoClientType CLIENT_TYPE = ServiceMain.getInstance().getNuxeoClientType();
+
+    public CollectionObjectResource() {
+        // do nothing
+    }
+
+    @POST
+    public Response createCollectionObject(
+            CollectionObject co) {
+
+        String csid = null;
+        try{
+            RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
+            RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
+            CollectionObjectHandlerFactory handlerFactory = CollectionObjectHandlerFactory.getInstance();
+            DocumentHandler handler = (DocumentHandler) handlerFactory.getHandler(CLIENT_TYPE.toString());
+            handler.setCommonObject(co);
+            csid = client.create(CO_SERVICE_NAME, CollectionObjectConstants.CO_NUXEO_DOCTYPE, handler);
+            co.setCsid(csid);
+            if(logger.isDebugEnabled()){
+                verbose("createCollectionObject: ", co);
+            }
+            UriBuilder path = UriBuilder.fromResource(CollectionObjectResource.class);
+            path.path("" + csid);
+            Response response = Response.created(path.build()).build();
+            return response;
+        }catch(Exception e){
+            if(logger.isDebugEnabled()){
+                logger.debug("Caught exception in createCollectionObject", e);
+            }
+            Response response = Response.status(
+                    Response.Status.INTERNAL_SERVER_ERROR).entity("Crate failed").type("text/plain").build();
+            throw new WebApplicationException(response);
+        }
+    }
+
+    @GET
+    @Path("{csid}")
+    public CollectionObject getCollectionObject(
+            @PathParam("csid") String csid) {
+        if(logger.isDebugEnabled()){
+            verbose("getCollectionObject with csid=" + csid);
+        }
+        if(csid == null || "".equals(csid)){
+            logger.error("getCollectionObject: missing csid!");
+            Response response = Response.status(Response.Status.BAD_REQUEST).entity(
+                    "get failed on CollectionObject csid=" + csid).type(
+                    "text/plain").build();
+            throw new WebApplicationException(response);
+        }
+        CollectionObject co = null;
+        try{
+            RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
+            RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
+            CollectionObjectHandlerFactory handlerFactory = CollectionObjectHandlerFactory.getInstance();
+            DocumentHandler handler = (DocumentHandler) handlerFactory.getHandler(CLIENT_TYPE.toString());
+            client.get(csid, handler);
+            co = (CollectionObject) handler.getCommonObject();
+        }catch(DocumentNotFoundException dnfe){
+            if(logger.isDebugEnabled()){
+                logger.debug("getCollectionObject", dnfe);
+            }
+            Response response = Response.status(Response.Status.NOT_FOUND).entity(
+                    "Get failed on CollectionObject csid=" + csid).type(
+                    "text/plain").build();
+            throw new WebApplicationException(response);
+        }catch(Exception e){
+            if(logger.isDebugEnabled()){
+                logger.debug("getCollectionObject", e);
+            }
+            Response response = Response.status(
+                    Response.Status.INTERNAL_SERVER_ERROR).entity("Get failed").type("text/plain").build();
+            throw new WebApplicationException(response);
+        }
+
+        if(co == null){
+            Response response = Response.status(Response.Status.NOT_FOUND).entity(
+                    "Get failed, the requested CollectionObject CSID:" + csid + ": was not found.").type(
+                    "text/plain").build();
+            throw new WebApplicationException(response);
+        }
+        if(logger.isDebugEnabled()){
+            verbose("getCollectionObject: ", co);
+        }
+        return co;
+    }
+
+    @GET
+    public CollectionObjectList getCollectionObjectList(@Context UriInfo ui) {
+        CollectionObjectList coList = new CollectionObjectList();
+        try{
+            RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
+            RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
+            CollectionObjectHandlerFactory handlerFactory = CollectionObjectHandlerFactory.getInstance();
+            DocumentHandler handler = (DocumentHandler) handlerFactory.getHandler(CLIENT_TYPE.toString());
+            client.getAll(CO_SERVICE_NAME, handler);
+            coList = (CollectionObjectList) handler.getCommonObjectList();
+        }catch(Exception e){
+            if(logger.isDebugEnabled()){
+                logger.debug("Caught exception in getCollectionObjectList", e);
+            }
+            Response response = Response.status(
+                    Response.Status.INTERNAL_SERVER_ERROR).entity("index failed").type("text/plain").build();
+            throw new WebApplicationException(response);
+        }
+        return coList;
+    }
+
+    @PUT
+    @Path("{csid}")
+    public CollectionObject updateCollectionObject(
+            @PathParam("csid") String csid,
+            CollectionObject theUpdate) {
+        if(logger.isDebugEnabled()){
+            verbose("updateCollectionObject with csid=" + csid);
+        }
+        if(csid == null || "".equals(csid)){
+            logger.error("updateCollectionObject: missing csid!");
+            Response response = Response.status(Response.Status.BAD_REQUEST).entity(
+                    "update failed on CollectionObject csid=" + csid).type(
+                    "text/plain").build();
+            throw new WebApplicationException(response);
+        }
+        if(logger.isDebugEnabled()){
+            verbose("updateCollectionObject with input: ", theUpdate);
+        }
+        try{
+            RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
+            RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
+            CollectionObjectHandlerFactory handlerFactory = CollectionObjectHandlerFactory.getInstance();
+            DocumentHandler handler = (DocumentHandler) handlerFactory.getHandler(CLIENT_TYPE.toString());
+            handler.setCommonObject(theUpdate);
+            client.update(csid, handler);
+        }catch(DocumentNotFoundException dnfe){
+            if(logger.isDebugEnabled()){
+                logger.debug("caugth exception in updateCollectionObject", dnfe);
+            }
+            Response response = Response.status(Response.Status.NOT_FOUND).entity(
+                    "Update failed on CollectionObject csid=" + csid).type(
+                    "text/plain").build();
+            throw new WebApplicationException(response);
+        }catch(Exception e){
+            Response response = Response.status(
+                    Response.Status.INTERNAL_SERVER_ERROR).entity("Update failed").type("text/plain").build();
+            throw new WebApplicationException(response);
+        }
+        return theUpdate;
+    }
+
+    @DELETE
+    @Path("{csid}")
+    public Response deleteCollectionObject(@PathParam("csid") String csid) {
+
+        if(logger.isDebugEnabled()){
+            verbose("deleteCollectionObject with csid=" + csid);
+        }
+        if(csid == null || "".equals(csid)){
+            logger.error("deleteCollectionObject: missing csid!");
+            Response response = Response.status(Response.Status.BAD_REQUEST).entity(
+                    "delete failed on CollectionObject csid=" + csid).type(
+                    "text/plain").build();
+            throw new WebApplicationException(response);
+        }
+        try{
+            RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
+            RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
+            client.delete(csid);
+            return Response.status(HttpResponseCodes.SC_OK).build();
+        }catch(DocumentNotFoundException dnfe){
+            if(logger.isDebugEnabled()){
+                logger.debug("caught exception in deleteCollectionObject", dnfe);
+            }
+            Response response = Response.status(Response.Status.NOT_FOUND).entity(
+                    "Delete failed on CollectionObject csid=" + csid).type(
+                    "text/plain").build();
+            throw new WebApplicationException(response);
+        }catch(Exception e){
+            Response response = Response.status(
+                    Response.Status.INTERNAL_SERVER_ERROR).entity("Delete failed").type("text/plain").build();
+            throw new WebApplicationException(response);
+        }
+
+    }
+
+    private void verbose(String msg, CollectionObject co) {
+        try{
+            verbose(msg);
+            JAXBContext jc = JAXBContext.newInstance(
+                    CollectionObject.class);
+
+            Marshaller m = jc.createMarshaller();
+            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+            m.marshal(co, System.out);
+        }catch(Exception e){
+            e.printStackTrace();
+        }
+
+    }
+
+    private void verbose(String msg) {
+        System.out.println("CollectionObjectResource. " + msg);
+    }
+}
diff --git a/services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/nuxeo/CollectionObjectConstants.java b/services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/nuxeo/CollectionObjectConstants.java
new file mode 100644 (file)
index 0000000..9911f42
--- /dev/null
@@ -0,0 +1,36 @@
+/**
+ *  This document is a part of the source code and related artifacts
+ *  for CollectionSpace, an open source collections management system
+ *  for museums and related institutions:
+
+ *  http://www.collectionspace.org
+ *  http://wiki.collectionspace.org
+
+ *  Copyright 2009 University of California at Berkeley
+
+ *  Licensed under the Educational Community License (ECL), Version 2.0.
+ *  You may not use this file except in compliance with this License.
+
+ *  You may obtain a copy of the ECL 2.0 License at
+
+ *  https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.collectionspace.services.collectionobject.nuxeo;
+
+/**
+ * CollectionObjectConstants processes CollectionObject document
+ *
+ */
+public class CollectionObjectConstants {
+
+    public final static String CO_NUXEO_DOCTYPE = "CollectionObject";
+    public final static String CO_NUXEO_SCHEMA_NAME = "collectionobject";
+    public final static String CO_NUXEO_DC_TITLE = "CollectionSpace-CollectionObject";
+    
+}
diff --git a/services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/nuxeo/CollectionObjectDocumentModelHandler.java b/services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/nuxeo/CollectionObjectDocumentModelHandler.java
new file mode 100644 (file)
index 0000000..80d6314
--- /dev/null
@@ -0,0 +1,290 @@
+/**
+ *  This document is a part of the source code and related artifacts
+ *  for CollectionSpace, an open source collections management system
+ *  for museums and related institutions:
+
+ *  http://www.collectionspace.org
+ *  http://wiki.collectionspace.org
+
+ *  Copyright 2009 University of California at Berkeley
+
+ *  Licensed under the Educational Community License (ECL), Version 2.0.
+ *  You may not use this file except in compliance with this License.
+
+ *  You may obtain a copy of the ECL 2.0 License at
+
+ *  https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.collectionspace.services.collectionobject.nuxeo;
+
+import java.util.Iterator;
+import java.util.List;
+import org.collectionspace.services.CollectionObjectJAXBSchema;
+import org.collectionspace.services.collectionobject.CollectionObject;
+import org.collectionspace.services.collectionobject.CollectionObjectList;
+import org.collectionspace.services.collectionobject.CollectionObjectList.CollectionObjectListItem;
+import org.collectionspace.services.common.repository.DocumentWrapper;
+import org.collectionspace.services.nuxeo.client.java.DocumentModelHandler;
+import org.nuxeo.ecm.core.api.DocumentModel;
+import org.nuxeo.ecm.core.api.DocumentModelList;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * CollectionObjectDocumentModelHandler
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ */
+public class CollectionObjectDocumentModelHandler
+        extends DocumentModelHandler<CollectionObject, CollectionObjectList> {
+
+    private final Logger logger = LoggerFactory.getLogger(CollectionObjectDocumentModelHandler.class);
+    /**
+     * collectionObject is used to stash JAXB object to use when handle is called
+     * for Action.CREATE, Action.UPDATE or Action.GET
+     */
+    private CollectionObject collectionObject;
+    /**
+     * collectionObjectList is stashed when handle is called
+     * for ACTION.GET_ALL
+     */
+    private CollectionObjectList collectionObjectList;
+
+    @Override
+    public void prepare(Action action) throws Exception {
+        //no specific action needed
+    }
+
+    @Override
+    public void handle(Action action, DocumentWrapper wrapDoc) throws Exception {
+        switch(action){
+            case CREATE:
+                handleCreate(wrapDoc);
+                break;
+            case UPDATE:
+                handleUpdate(wrapDoc);
+                break;
+            case GET:
+                handleGet(wrapDoc);
+                break;
+            case GET_ALL:
+                handleGetAll(wrapDoc);
+                break;
+        }
+    }
+
+    /**
+     * handleCreate processes create operation response
+     * @param wrapDoc
+     * @throws Exception
+     */
+    public void handleCreate(DocumentWrapper wrapDoc) throws Exception {
+        CollectionObject co = getCommonObject();
+        if(co == null){
+            String msg = "Error creating document: Missing input data";
+            logger.error(msg);
+            throw new IllegalStateException(msg);
+        }
+        //FIXME set other parts as well
+        fillCommonObject(co, wrapDoc);
+    }
+
+    /**
+     * handleUpdate processes update operation response
+     * @param wrapDoc
+     * @throws Exception
+     */
+    public void handleUpdate(DocumentWrapper wrapDoc) throws Exception {
+        CollectionObject co = getCommonObject();
+        if(co == null){
+            String msg = "Error updating document: Missing input data";
+            logger.error(msg);
+            throw new IllegalStateException(msg);
+        }
+        //FIXME set other parts as well
+        fillCommonObject(co, wrapDoc);
+    }
+
+    /**
+     * handleGet processes get operation response
+     * @param wrapDoc
+     * @throws Exception
+     */
+    public void handleGet(DocumentWrapper wrapDoc) throws Exception {
+        CollectionObject co = extractCommonObject(wrapDoc);
+        setCommonObject(co);
+
+        //FIXME retrive other parts as well
+    }
+
+    /**
+     * handleGetAll processes index operation response
+     * @param wrapDoc
+     * @throws Exception
+     */
+    public void handleGetAll(DocumentWrapper wrapDoc) throws Exception {
+        CollectionObjectList coList = extractCommonObjectList(wrapDoc);
+        //FIXME, this is unncessarily called on each call from client
+        setCommonObjectList(coList);
+    }
+
+    /**
+     * getCommonObject get associated CollectionObject
+     * @return
+     */
+    @Override
+    public CollectionObject getCommonObject() {
+        return collectionObject;
+    }
+
+    /**
+     * setCommonObject set associated collectionobject
+     * @param collectionObject
+     */
+    @Override
+    public void setCommonObject(CollectionObject collectionObject) {
+        this.collectionObject = collectionObject;
+    }
+
+    /**
+     * getCollectionObjectList get associated CollectionObject (for index/GET_ALL)
+     * @return
+     */
+    @Override
+    public CollectionObjectList getCommonObjectList() {
+        return collectionObjectList;
+    }
+
+    @Override
+    public void setCommonObjectList(CollectionObjectList collectionObjectList) {
+        this.collectionObjectList = collectionObjectList;
+    }
+
+    @Override
+    public CollectionObject extractCommonObject(DocumentWrapper wrapDoc)
+            throws Exception {
+        DocumentModel docModel = (DocumentModel) wrapDoc.getWrappedObject();
+        CollectionObject co = new CollectionObject();
+
+        //FIXME property get should be dynamically set using schema inspection
+        //so it does not require hard coding
+
+        // CollectionObject core values
+        co.setObjectNumber((String) docModel.getPropertyValue(
+                getQProperty(CollectionObjectJAXBSchema.OBJECT_NUMBER)));
+        co.setOtherNumber((String) docModel.getPropertyValue(
+                getQProperty(CollectionObjectJAXBSchema.OTHER_NUMBER)));
+        co.setBriefDescription((String) docModel.getPropertyValue(
+                getQProperty(CollectionObjectJAXBSchema.BRIEF_DESCRIPTION)));
+        co.setComments((String) docModel.getPropertyValue(
+                getQProperty(CollectionObjectJAXBSchema.COMMENTS)));
+        co.setDistFeatures((String) docModel.getPropertyValue(
+                getQProperty(CollectionObjectJAXBSchema.DIST_FEATURES)));
+        co.setObjectName((String) docModel.getPropertyValue(
+                getQProperty(CollectionObjectJAXBSchema.OBJECT_NAME)));
+        co.setResponsibleDept((String) docModel.getPropertyValue(
+                getQProperty(CollectionObjectJAXBSchema.RESPONSIBLE_DEPT)));
+        co.setTitle((String) docModel.getPropertyValue(
+                getQProperty(CollectionObjectJAXBSchema.TITLE)));
+
+        return co;
+    }
+
+    @Override
+    public void fillCommonObject(CollectionObject co, DocumentWrapper wrapDoc) throws Exception {
+        DocumentModel docModel = (DocumentModel) wrapDoc.getWrappedObject();
+        //FIXME property setter should be dynamically set using schema inspection
+        //so it does not require hard coding
+
+        // a default title for the Dublin Core schema
+        docModel.setPropertyValue("dublincore:title", CollectionObjectConstants.CO_NUXEO_DC_TITLE);
+
+        // CollectionObject core values
+        if(co.getObjectNumber() != null){
+            docModel.setPropertyValue(
+                    getQProperty(CollectionObjectJAXBSchema.OBJECT_NUMBER),
+                    co.getObjectNumber());
+        }
+        if(co.getOtherNumber() != null){
+            docModel.setPropertyValue(
+                    getQProperty(CollectionObjectJAXBSchema.OTHER_NUMBER),
+                    co.getOtherNumber());
+        }
+        if(co.getBriefDescription() != null){
+            docModel.setPropertyValue(
+                    getQProperty(CollectionObjectJAXBSchema.BRIEF_DESCRIPTION),
+                    co.getBriefDescription());
+        }
+        if(co.getComments() != null){
+            docModel.setPropertyValue(
+                    getQProperty(CollectionObjectJAXBSchema.COMMENTS),
+                    co.getComments());
+        }
+        if(co.getDistFeatures() != null){
+            docModel.setPropertyValue(
+                    getQProperty(CollectionObjectJAXBSchema.DIST_FEATURES),
+                    co.getDistFeatures());
+        }
+        if(co.getObjectName() != null){
+            docModel.setPropertyValue(
+                    getQProperty(CollectionObjectJAXBSchema.OBJECT_NAME),
+                    co.getObjectName());
+        }
+        if(co.getResponsibleDept() != null){
+            docModel.setPropertyValue(
+                    getQProperty(CollectionObjectJAXBSchema.RESPONSIBLE_DEPT),
+                    co.getResponsibleDept());
+        }
+        if(co.getTitle() != null){
+            docModel.setPropertyValue(
+                    getQProperty(CollectionObjectJAXBSchema.TITLE),
+                    co.getTitle());
+        }
+    }
+
+    @Override
+    public CollectionObjectList extractCommonObjectList(DocumentWrapper wrapDoc) throws Exception {
+        DocumentModelList docList = (DocumentModelList) wrapDoc.getWrappedObject();
+
+        CollectionObjectList coList = new CollectionObjectList();
+        List<CollectionObjectList.CollectionObjectListItem> list = coList.getCollectionObjectListItem();
+
+        //FIXME: iterating over a long list of documents is not a long term
+        //strategy...need to change to more efficient iterating in future
+        Iterator<DocumentModel> iter = docList.iterator();
+        while(iter.hasNext()){
+            DocumentModel docModel = iter.next();
+            CollectionObjectListItem coListItem = new CollectionObjectListItem();
+            coListItem.setObjectNumber((String) docModel.getPropertyValue(
+                    getQProperty(CollectionObjectJAXBSchema.OBJECT_NUMBER)));
+            //need fully qualified context for URI
+            coListItem.setUri("/collectionobjects/" + docModel.getId());
+            coListItem.setCsid(docModel.getId());
+            list.add(coListItem);
+        }
+
+        return coList;
+    }
+
+    @Override
+    public void fillCommonObjectList(CollectionObjectList obj, DocumentWrapper wrapDoc) throws Exception {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * getQProperty converts the given property to qualified schema property
+     * @param prop
+     * @return
+     */
+    private String getQProperty(String prop) {
+        return CollectionObjectConstants.CO_NUXEO_SCHEMA_NAME + ":" + prop;
+    }
+}
+
diff --git a/services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/nuxeo/CollectionObjectHandlerFactory.java b/services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/nuxeo/CollectionObjectHandlerFactory.java
new file mode 100644 (file)
index 0000000..bcaa606
--- /dev/null
@@ -0,0 +1,55 @@
+/**
+ *  This document is a part of the source code and related artifacts
+ *  for CollectionSpace, an open source collections management system
+ *  for museums and related institutions:
+
+ *  http://www.collectionspace.org
+ *  http://wiki.collectionspace.org
+
+ *  Copyright 2009 University of California at Berkeley
+
+ *  Licensed under the Educational Community License (ECL), Version 2.0.
+ *  You may not use this file except in compliance with this License.
+
+ *  You may obtain a copy of the ECL 2.0 License at
+
+ *  https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.collectionspace.services.collectionobject.nuxeo;
+
+import org.collectionspace.services.common.NuxeoClientType;
+import org.collectionspace.services.common.repository.DocumentHandler;
+
+/**
+ * CollectionObjectHandlerFactory creates handlers for collectionobject based
+ * on type of Nuxeo client used
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ */
+public class CollectionObjectHandlerFactory {
+
+    private static final CollectionObjectHandlerFactory self = new CollectionObjectHandlerFactory();
+
+    private CollectionObjectHandlerFactory() {
+    }
+
+    public static CollectionObjectHandlerFactory getInstance() {
+        return self;
+    }
+
+    public DocumentHandler getHandler(String clientType) {
+        if(NuxeoClientType.JAVA.toString().equals(clientType)){
+            return new CollectionObjectDocumentModelHandler();
+        } else if(NuxeoClientType.REST.toString().equals(clientType)) {
+            return new CollectionObjectRepresenationHandler();
+        }
+        throw new IllegalArgumentException("Not supported client=" + clientType);
+    }
+}
diff --git a/services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/nuxeo/CollectionObjectRepresenationHandler.java b/services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/nuxeo/CollectionObjectRepresenationHandler.java
new file mode 100644 (file)
index 0000000..dd58dfc
--- /dev/null
@@ -0,0 +1,319 @@
+/**
+ *  This document is a part of the source code and related artifacts
+ *  for CollectionSpace, an open source collections management system
+ *  for museums and related institutions:
+
+ *  http://www.collectionspace.org
+ *  http://wiki.collectionspace.org
+
+ *  Copyright 2009 University of California at Berkeley
+
+ *  Licensed under the Educational Community License (ECL), Version 2.0.
+ *  You may not use this file except in compliance with this License.
+
+ *  You may obtain a copy of the ECL 2.0 License at
+
+ *  https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.collectionspace.services.collectionobject.nuxeo;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import org.collectionspace.services.CollectionObjectJAXBSchema;
+import org.collectionspace.services.collectionobject.CollectionObject;
+import org.collectionspace.services.collectionobject.CollectionObjectList;
+import org.collectionspace.services.collectionobject.CollectionObjectList.CollectionObjectListItem;
+import org.collectionspace.services.collectionobject.CollectionObjectService;
+import org.collectionspace.services.common.repository.DocumentWrapper;
+import org.collectionspace.services.nuxeo.client.rest.RepresentationHandler;
+import org.dom4j.Document;
+import org.dom4j.Element;
+import org.nuxeo.ecm.core.api.DocumentModel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * CollectionObjectDocumentModelHandler
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ */
+public class CollectionObjectRepresenationHandler
+        extends RepresentationHandler<CollectionObject, CollectionObjectList>
+{
+
+    private final Logger logger = LoggerFactory.getLogger(CollectionObjectRepresenationHandler.class);
+    /**
+     * collectionObject is used to stash JAXB object to use when handle is called
+     * for Action.CREATE, Action.UPDATE or Action.GET
+     */
+    private CollectionObject collectionObject;
+    /**
+     * collectionObjectList is stashed when handle is called
+     * for ACTION.GET_ALL
+     */
+    private CollectionObjectList collectionObjectList;
+
+    @Override
+    public void prepare(Action action) throws Exception {
+        switch(action){
+            case CREATE:
+            case UPDATE:
+                prepare();
+        }
+    }
+
+    @Override
+    public void handle(Action action, DocumentWrapper wrapDoc)
+            throws Exception {
+        switch(action){
+            case CREATE:
+                handleCreate(wrapDoc);
+                break;
+            case UPDATE:
+                handleUpdate(wrapDoc);
+                break;
+            case GET:
+                handleGet(wrapDoc);
+                break;
+            case GET_ALL:
+                handleGetAll(wrapDoc);
+                break;
+        }
+    }
+
+    /**
+     * handleCreate processes create operation response
+     * @param wrapDoc
+     * @throws Exception
+     */
+    public void handleCreate(DocumentWrapper wrapDoc) throws Exception {
+        CollectionObject co = getCommonObject();
+        if(co == null){
+            String msg = "Error creating document: Missing input data";
+            logger.error(msg);
+            throw new IllegalStateException(msg);
+        }
+        //FIXME set other parts as well
+        fillCommonObject(co, wrapDoc);
+    }
+
+    /**
+     * handleUpdate processes update operation response
+     * @param wrapDoc
+     * @throws Exception
+     */
+    public void handleUpdate(DocumentWrapper wrapDoc) throws Exception {
+        CollectionObject co = getCommonObject();
+        if(co == null){
+            String msg = "Error updating document: Missing input data";
+            logger.error(msg);
+            throw new IllegalStateException(msg);
+        }
+        //FIXME set other parts as well
+        fillCommonObject(co, wrapDoc);
+    }
+
+    /**
+     * handleGet processes get operation response
+     * @param wrapDoc
+     * @throws Exception
+     */
+    public void handleGet(DocumentWrapper wrapDoc) throws Exception {
+        CollectionObject co = extractCommonObject(wrapDoc);
+        setCommonObject(co);
+        //FIXME retrive other parts as well
+    }
+
+    /**
+     * handleGetAll processes index operation response
+     * @param wrapDoc
+     * @throws Exception
+     */
+    public void handleGetAll(DocumentWrapper wrapDoc) throws Exception {
+        CollectionObjectList coList = extractCommonObjectList(wrapDoc);
+        setCommonObjectList(coList);
+    }
+
+    private void prepare() {
+        Map<String, String> queryParams = getQueryParams();
+        CollectionObject co = getCommonObject();
+        // todo: intelligent merge needed
+        if(co.getObjectNumber() != null){
+            queryParams.put(CollectionObjectConstants.CO_NUXEO_SCHEMA_NAME +
+                    ":" + CollectionObjectJAXBSchema.OBJECT_NUMBER, co.getObjectNumber());
+        }
+
+        if(co.getOtherNumber() != null){
+            queryParams.put(CollectionObjectConstants.CO_NUXEO_SCHEMA_NAME +
+                    ":" + CollectionObjectJAXBSchema.OTHER_NUMBER, co.getOtherNumber());
+        }
+
+        if(co.getBriefDescription() != null){
+            queryParams.put(CollectionObjectConstants.CO_NUXEO_SCHEMA_NAME +
+                    ":" + CollectionObjectJAXBSchema.BRIEF_DESCRIPTION, co.getBriefDescription());
+        }
+
+        if(co.getComments() != null){
+            queryParams.put(CollectionObjectConstants.CO_NUXEO_SCHEMA_NAME +
+                    ":" + CollectionObjectJAXBSchema.COMMENTS, co.getComments());
+        }
+
+        if(co.getDistFeatures() != null){
+            queryParams.put(CollectionObjectConstants.CO_NUXEO_SCHEMA_NAME +
+                    ":" + CollectionObjectJAXBSchema.DIST_FEATURES, co.getDistFeatures());
+        }
+
+        if(co.getObjectName() != null){
+            queryParams.put(CollectionObjectConstants.CO_NUXEO_SCHEMA_NAME +
+                    ":" + CollectionObjectJAXBSchema.OBJECT_NAME, co.getObjectName());
+        }
+
+        if(co.getResponsibleDept() != null){
+            queryParams.put(CollectionObjectConstants.CO_NUXEO_SCHEMA_NAME +
+                    ":" + CollectionObjectJAXBSchema.RESPONSIBLE_DEPT, co.getResponsibleDept());
+        }
+
+        if(co.getTitle() != null){
+            queryParams.put(CollectionObjectConstants.CO_NUXEO_SCHEMA_NAME +
+                    ":" + CollectionObjectJAXBSchema.TITLE, co.getTitle());
+        }
+    }
+
+    @Override
+    public CollectionObject extractCommonObject(DocumentWrapper wrapDoc)
+            throws Exception {
+        Document document = (Document) wrapDoc.getWrappedObject();
+        CollectionObject co = new CollectionObject();
+
+        //FIXME property get should be dynamically set using schema inspection
+        //so it does not require hard coding
+        Element root = document.getRootElement();
+
+        // TODO: recognize schema thru namespace uri
+        // Namespace ns = new Namespace("collectionobject",
+        // "http://collectionspace.org/collectionobject");
+
+        Iterator<Element> siter = root.elementIterator("schema");
+        while(siter.hasNext()){
+
+            Element schemaElement = siter.next();
+            if(logger.isDebugEnabled()){
+                logger.debug("getCommonObject() populating Common Object");
+            }
+            // TODO: recognize schema thru namespace uri
+            if(CollectionObjectConstants.CO_NUXEO_SCHEMA_NAME.equals(schemaElement.attribute("name").getValue())){
+                Element ele = schemaElement.element(CollectionObjectJAXBSchema.OBJECT_NUMBER);
+                if(ele != null){
+                    co.setObjectNumber((String) ele.getData());
+                }
+                ele = schemaElement.element(CollectionObjectJAXBSchema.OTHER_NUMBER);
+                if(ele != null){
+                    co.setOtherNumber((String) ele.getData());
+                }
+                ele = schemaElement.element(CollectionObjectJAXBSchema.BRIEF_DESCRIPTION);
+                if(ele != null){
+                    co.setBriefDescription((String) ele.getData());
+                }
+                ele = schemaElement.element(CollectionObjectJAXBSchema.COMMENTS);
+                if(ele != null){
+                    co.setComments((String) ele.getData());
+                }
+                ele = schemaElement.element(CollectionObjectJAXBSchema.DIST_FEATURES);
+                if(ele != null){
+                    co.setDistFeatures((String) ele.getData());
+                }
+                ele = schemaElement.element(CollectionObjectJAXBSchema.OBJECT_NAME);
+                if(ele != null){
+                    co.setObjectName((String) ele.getData());
+                }
+                ele = schemaElement.element(CollectionObjectJAXBSchema.RESPONSIBLE_DEPT);
+                if(ele != null){
+                    co.setResponsibleDept((String) ele.getData());
+                }
+                ele = schemaElement.element(CollectionObjectJAXBSchema.TITLE);
+                if(ele != null){
+                    co.setTitle((String) ele.getData());
+                }
+            }
+        }
+        return co;
+    }
+
+    @Override
+    public void fillCommonObject(CollectionObject co, DocumentWrapper wrapDoc)
+            throws Exception {
+        //Nuxeo REST takes create/update through queryParams, nothing to do here
+    }
+
+    @Override
+    public CollectionObjectList extractCommonObjectList(DocumentWrapper wrapDoc) throws Exception {
+        Document document = (Document) wrapDoc.getWrappedObject();
+        // debug
+        if(logger.isDebugEnabled()){
+            logger.debug(document.asXML());
+        }
+        CollectionObjectList coList = new CollectionObjectList();
+        List<CollectionObjectList.CollectionObjectListItem> list = coList.getCollectionObjectListItem();
+        Element root = document.getRootElement();
+        for(Iterator i = root.elementIterator(); i.hasNext();){
+
+            Element element = (Element) i.next();
+            if(logger.isDebugEnabled()){
+                logger.debug(element.asXML());
+            }
+            // set the CollectionObject list item entity elements
+            CollectionObjectListItem coListItem = new CollectionObjectListItem();
+            coListItem.setObjectNumber(element.attributeValue("title"));
+            String id = element.attributeValue("id");
+            coListItem.setCsid(id);
+            coListItem.setUri("/collectionobjects/" + id);
+
+            list.add(coListItem);
+        }
+        return coList;
+    }
+
+    @Override
+    public void fillCommonObjectList(CollectionObjectList obj, DocumentWrapper wrapDoc)
+            throws Exception {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public CollectionObject getCommonObject() {
+        return collectionObject;
+    }
+
+    @Override
+    public void setCommonObject(CollectionObject obj) {
+        this.collectionObject = obj;
+    }
+
+    @Override
+    public CollectionObjectList getCommonObjectList() {
+        return collectionObjectList;
+    }
+
+    @Override
+    public void setCommonObjectList(CollectionObjectList obj) {
+        this.collectionObjectList = obj;
+    }
+
+    /**
+     * getQProperty converts the given property to qualified schema property
+     * @param prop
+     * @return
+     */
+    private String getQProperty(String prop) {
+        return CollectionObjectConstants.CO_NUXEO_SCHEMA_NAME + ":" + prop;
+    }
+}
+
@@ -1,8 +1,10 @@
 /**\r
  * \r
  */\r
-package org.collectionspace.services;\r
+package org.collectionspace.services.collectionobject.nuxeo;\r
 \r
+import org.collectionspace.services.collectionobject.CollectionObjectService;\r
+import org.collectionspace.services.*;\r
 import java.io.ByteArrayInputStream;\r
 import java.io.IOException;\r
 import java.util.ArrayList;\r
@@ -11,11 +13,11 @@ import java.util.HashMap;
 import java.util.List;\r
 import java.util.Map;\r
 \r
-import org.collectionspace.services.nuxeo.NuxeoRESTClient;\r
+import org.collectionspace.services.nuxeo.client.rest.NuxeoRESTClient;\r
 import org.collectionspace.services.nuxeo.CollectionSpaceServiceNuxeoImpl;\r
 import org.collectionspace.services.collectionobject.CollectionObject;\r
 import org.collectionspace.services.CollectionObjectJAXBSchema;\r
-import org.collectionspace.services.nuxeo.NuxeoUtils;\r
+import org.collectionspace.services.nuxeo.util.NuxeoUtils;\r
 \r
 import org.dom4j.Document;\r
 import org.dom4j.DocumentException;\r
@@ -84,35 +86,7 @@ public class CollectionObjectServiceNuxeoImpl extends
                return document;\r
        }\r
        \r
-       /*\r
-        * Prototype method for calling the Nuxeo Java API\r
-        */\r
-       private Document getCollectionObjectViaJavaAPI(String csid)\r
-                       throws DocumentException, IOException {\r
-               Document result = null;\r
-               RepositoryInstance repoSession = null;\r
-               \r
-               try {\r
-                       repoSession = getRepositorySession();\r
-                       DocumentRef documentRef = new IdRef(csid);\r
-                       DocumentModel documentModel = repoSession.getDocument(documentRef);\r
-                       result = NuxeoUtils.getDocument(repoSession, documentModel);\r
-               } catch (Exception e) {\r
-                       if (logger.isDebugEnabled()) {\r
-                               e.printStackTrace();\r
-                       }\r
-               } finally {\r
-                       if (repoSession != null) {\r
-                               releaseRepositorySession(repoSession);\r
-                       }\r
-               }\r
-               \r
-               // Dump out the contents of the result to stdout\r
-               System.out.println(result.asXML());\r
-               \r
-               return result;\r
-       }\r
-\r
+       \r
        public Document getCollectionObjectList() throws DocumentException,\r
                        IOException {\r
                Document result = null;\r
index 614d01ad3015f070c61b487a3cdd17bcaf0ab85e..6085d4a8d1c88aa2f54e3f5b5c3e7b5b1e6600d1 100644 (file)
@@ -15,7 +15,9 @@
     <nuxeo-client-config>
         <!-- ip of network interface to which Nuxeo server is listening on -->
         <host>127.0.0.1</host>
-        <port>62474</port>
+        <port>62474</port> <!-- java -->
+        <!--port>8080</port--> <!-- rest -->
+        <client-type>java</client-type>
         <user>Administrator</user>
         <password>Administrator</password>
     </nuxeo-client-config>
         <workspace>
             <service-name>persons</service-name>
             <workspace-name>People</workspace-name>
+            <!-- use hard-coded workspace id for REST client -->
+            <!--workspace-id></workspace-id-->
         </workspace>
-                <workspace>
+        <workspace>
             <service-name>collectionobjects</service-name>
             <workspace-name>CollectionObjects</workspace-name>
+            <!-- use hard-coded workspace id for REST client -->
+            <!--workspace-id></workspace-id-->
         </workspace>
         <workspace>
             <service-name>intakes</service-name>
             <workspace-name>Intakes</workspace-name>
-        </workspace>        
+            <!-- use hard-coded workspace id for REST client -->
+            <!--workspace-id></workspace-id-->
+        </workspace>
     </nuxeo-workspace>
 
 </ns1:service-config>
index c55a2f71ec9d7e7680402bfc1a4adf5f510954ed..75c6efc4e892bca3deb156e881568dab68cf78fa 100644 (file)
@@ -10,7 +10,7 @@ import javax.xml.bind.JAXBContext;
 import javax.xml.bind.Unmarshaller;
 import org.collectionspace.services.common.ServiceConfig.NuxeoWorkspace;
 import org.collectionspace.services.common.ServiceConfig.NuxeoWorkspace.Workspace;
-import org.collectionspace.services.nuxeo.NuxeoConnector;
+import org.collectionspace.services.nuxeo.client.java.NuxeoConnector;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -30,6 +30,7 @@ public class ServiceMain {
     private Hashtable<String, String> serviceWorkspaces = new Hashtable<String, String>();
     private NuxeoConnector nuxeoConnector;
     private String serverRootDir = null;
+    private NuxeoClientType nuxeoClientType = null;
 
     private ServiceMain() {
     }
@@ -64,8 +65,10 @@ public class ServiceMain {
     private void initialize() throws Exception {
         setServerRootDir();
         serviceConfig = readConfig();
-        nuxeoConnector = NuxeoConnector.getInstance();
-        nuxeoConnector.initialize(serviceConfig.getNuxeoClientConfig());
+        if(getNuxeoClientType().equals(NuxeoClientType.JAVA)){
+            nuxeoConnector = NuxeoConnector.getInstance();
+            nuxeoConnector.initialize(serviceConfig.getNuxeoClientConfig());
+        }
     }
 
     /**
@@ -81,7 +84,7 @@ public class ServiceMain {
             instance = null;
         }catch(Exception e){
             e.printStackTrace();
-        //gobble it
+            //gobble it
         }
     }
 
@@ -102,20 +105,39 @@ public class ServiceMain {
         if(logger.isDebugEnabled()){
             logger.debug("readConfig() read config file " + configFile.getAbsolutePath());
         }
+        nuxeoClientType = sconfig.getNuxeoClientConfig().getClientType();
+        if(logger.isDebugEnabled()) {
+            logger.debug("using Nuxeo client=" + nuxeoClientType.toString());
+        }
         return sconfig;
     }
 
     synchronized public void getWorkspaceIds() throws Exception {
-        Hashtable<String, String> workspaceIds = nuxeoConnector.retrieveWorkspaceIds();
+        Hashtable<String, String> workspaceIds = new Hashtable<String, String>();
+
+        if(getNuxeoClientType().equals(NuxeoClientType.JAVA)){
+            workspaceIds = nuxeoConnector.retrieveWorkspaceIds();
+        }
         NuxeoWorkspace nuxeoWorkspace = serviceConfig.getNuxeoWorkspace();
         List<Workspace> workspaces = nuxeoWorkspace.getWorkspace();
+        String workspaceId = null;
         for(Workspace workspace : workspaces){
-            String workspaceId = workspaceIds.get(workspace.getWorkspaceName().toLowerCase());
-            if(workspaceId == null){
-                logger.error("failed to retrieve workspace id for " + workspace.getWorkspaceName());
-                //FIXME: should we throw an exception here?
-                continue;
+            if(getNuxeoClientType().equals(NuxeoClientType.JAVA)){
+                workspaceId = workspaceIds.get(workspace.getWorkspaceName().toLowerCase());
+                if(workspaceId == null){
+                    logger.warn("failed to retrieve workspace id for " + workspace.getWorkspaceName());
+                    //FIXME: should we throw an exception here?
+                    continue;
+                }
+            }else{
+                workspaceId = workspace.getWorkspaceId();
+                if(workspaceId == null || "".equals(workspaceId)){
+                    logger.error("could not find workspace id for " + workspace.getWorkspaceName());
+                    //FIXME: should we throw an exception here?
+                    continue;
+                }
             }
+
             serviceWorkspaces.put(workspace.getServiceName(), workspaceId);
             if(logger.isDebugEnabled()){
                 logger.debug("retrieved workspace id=" + workspaceId +
@@ -156,4 +178,11 @@ public class ServiceMain {
     public String getServerRootDir() {
         return serverRootDir;
     }
+
+    /**
+     * @return the nuxeoClientType
+     */
+    public NuxeoClientType getNuxeoClientType() {
+        return nuxeoClientType;
+    }
 }
diff --git a/services/common/src/main/java/org/collectionspace/services/common/repository/BadRequestException.java b/services/common/src/main/java/org/collectionspace/services/common/repository/BadRequestException.java
new file mode 100644 (file)
index 0000000..af31a43
--- /dev/null
@@ -0,0 +1,84 @@
+/**
+ *  This document is a part of the source code and related artifacts
+ *  for CollectionSpace, an open source collections management system
+ *  for museums and related institutions:
+
+ *  http://www.collectionspace.org
+ *  http://wiki.collectionspace.org
+
+ *  Copyright 2009 University of California at Berkeley
+
+ *  Licensed under the Educational Community License (ECL), Version 2.0.
+ *  You may not use this file except in compliance with this License.
+
+ *  You may obtain a copy of the ECL 2.0 License at
+
+ *  https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.collectionspace.services.common.repository;
+
+/**
+ * BadRequestException
+ * 
+ */
+public class BadRequestException extends Exception {
+
+    /**
+     * Creates a new instance of <code>BadRequestException</code> without detail message.
+     */
+    public BadRequestException() {
+    }
+
+
+    /**
+     * Constructs an instance of <code>BadRequestException</code> with the specified detail message.
+     * @param msg the detail message.
+     */
+    public BadRequestException(String msg) {
+        super(msg);
+    }
+
+
+    /**
+     * Constructs a new exception with the specified detail message and
+     * cause.  <p>Note that the detail message associated with
+     * <code>cause</code> is <i>not</i> automatically incorporated in
+     * this exception's detail message.
+     *
+     * @param  message the detail message (which is saved for later retrieval
+     *         by the {@link #getMessage()} method).
+     * @param  cause the cause (which is saved for later retrieval by the
+     *         {@link #getCause()} method).  (A <tt>null</tt> value is
+     *         permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     * @since  1.4
+     */
+    public BadRequestException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Constructs a new exception with the specified cause and a detail
+     * message of <tt>(cause==null ? null : cause.toString())</tt> (which
+     * typically contains the class and detail message of <tt>cause</tt>).
+     * This constructor is useful for exceptions that are little more than
+     * wrappers for other throwables (for example, {@link
+     * java.security.PrivilegedActionException}).
+     *
+     * @param  cause the cause (which is saved for later retrieval by the
+     *         {@link #getCause()} method).  (A <tt>null</tt> value is
+     *         permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     * @since  1.4
+     */
+    public BadRequestException(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/services/common/src/main/java/org/collectionspace/services/common/repository/DocumentException.java b/services/common/src/main/java/org/collectionspace/services/common/repository/DocumentException.java
new file mode 100644 (file)
index 0000000..39043b0
--- /dev/null
@@ -0,0 +1,106 @@
+/**
+ *  This document is a part of the source code and related artifacts
+ *  for CollectionSpace, an open source collections management system
+ *  for museums and related institutions:
+
+ *  http://www.collectionspace.org
+ *  http://wiki.collectionspace.org
+
+ *  Copyright 2009 University of California at Berkeley
+
+ *  Licensed under the Educational Community License (ECL), Version 2.0.
+ *  You may not use this file except in compliance with this License.
+
+ *  You may obtain a copy of the ECL 2.0 License at
+
+ *  https://source.collectionspace.org/collection-space/LICENSE.txt
+ */
+
+package org.collectionspace.services.common.repository;
+
+/**
+ * DocumentException
+ * Nuxeo document handling exception
+ */
+public class DocumentException extends Exception {
+
+    /**
+     * collectionspace specific error code
+     */
+    private int errorCode;
+
+    /**
+     * Creates a new instance of <code>DocumentException</code> without detail message.
+     */
+    public DocumentException() {
+    }
+
+    /**
+     * Constructs an instance of <code>DocumentException</code> with the specified detail message.
+     * @param msg the detail message.
+     */
+    public DocumentException(String msg) {
+        super(msg);
+    }
+
+
+    /**
+     * DocumentException with application specific code and message
+     * @param code
+     * @param msg
+     */
+    public DocumentException(int code, String msg) {
+        super(msg);
+        this.errorCode = code;
+    }
+    /**
+     * Constructs a new exception with the specified detail message and
+     * cause.  <p>Note that the detail message associated with
+     * <code>cause</code> is <i>not</i> automatically incorporated in
+     * this exception's detail message.
+     *
+     * @param  message the detail message (which is saved for later retrieval
+     *         by the {@link #getMessage()} method).
+     * @param  cause the cause (which is saved for later retrieval by the
+     *         {@link #getCause()} method).  (A <tt>null</tt> value is
+     *         permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     * @since  1.4
+     */
+    public DocumentException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Constructs a new exception with the specified cause and a detail
+     * message of <tt>(cause==null ? null : cause.toString())</tt> (which
+     * typically contains the class and detail message of <tt>cause</tt>).
+     * This constructor is useful for exceptions that are little more than
+     * wrappers for other throwables (for example, {@link
+     * java.security.PrivilegedActionException}).
+     *
+     * @param  cause the cause (which is saved for later retrieval by the
+     *         {@link #getCause()} method).  (A <tt>null</tt> value is
+     *         permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     * @since  1.4
+     */
+    public DocumentException(Throwable cause) {
+        super(cause);
+    }
+
+
+    /**
+     * @return the collectionspace errorCode
+     */
+    public int getErrorCode() {
+        return errorCode;
+    }
+
+    /**
+     * @param errorCode the errorCode to set
+     */
+    public void setErrorCode(int errorCode) {
+        this.errorCode = errorCode;
+    }
+}
diff --git a/services/common/src/main/java/org/collectionspace/services/common/repository/DocumentHandler.java b/services/common/src/main/java/org/collectionspace/services/common/repository/DocumentHandler.java
new file mode 100644 (file)
index 0000000..1d92db6
--- /dev/null
@@ -0,0 +1,141 @@
+/**
+ *  This document is a part of the source code and related artifacts
+ *  for CollectionSpace, an open source collections management system
+ *  for museums and related institutions:
+
+ *  http://www.collectionspace.org
+ *  http://wiki.collectionspace.org
+
+ *  Copyright 2009 University of California at Berkeley
+
+ *  Licensed under the Educational Community License (ECL), Version 2.0.
+ *  You may not use this file except in compliance with this License.
+
+ *  You may obtain a copy of the ECL 2.0 License at
+
+ *  https://source.collectionspace.org/collection-space/LICENSE.txt
+ */
+package org.collectionspace.services.common.repository;
+
+import org.collectionspace.services.common.repository.DocumentWrapper;
+import org.collectionspace.services.common.repository.DocumentException;
+import java.util.Map;
+import org.dom4j.Document;
+
+/**
+ *
+ * DocumentHandler provides document processing methods. It is an interface
+ * between Nuxeo repository client and CollectionSpace service resource. It provides
+ * methods to setup request via repository client and handle its response.
+ *
+ * Typical call sequence is:
+ * Create handler and repository client
+ * Call XXX operation on the repository client and pass the handler
+ * repository client calls prepare on the handler
+ * The repository client then calls handle on the handler
+ *
+ */
+public interface DocumentHandler<T, TL> {
+
+    public enum Action {
+
+        CREATE, GET, GET_ALL, UPDATE, DELETE
+    }
+
+    /**
+     * prepare is called by the Nuxeo client to prepare required parameters to set
+     * before invoking repository operation. this is mainly useful for create and 
+     * update kind of actions
+     * @param action
+     * @throws Exception
+     */
+    public void prepare(Action action) throws Exception;
+
+    /**
+     * handle is called by the Nuxeo client to hand over the document processing on create
+     * function to the CollectionSpace service
+     * @param action 
+     * @param doc wrapped Nuxeo doc
+     * @throws Exception
+     */
+    public void handle(Action action, DocumentWrapper docWrap) throws Exception;
+
+    /**
+     * extractCommonObject extracts common part of a CS document from given Nuxeo document.
+     * @param docWrap nuxeo document
+     * @return common part of CS object
+     * @throws Exception
+     */
+    public T extractCommonObject(DocumentWrapper docWrap) throws Exception;
+
+    /**
+     * fillCommonObject sets common part of CS object into given Nuxeo document
+     * @param obj input object
+     * @param docWrap target Nuxeo document
+     * @throws Exception
+     */
+    public void fillCommonObject(T obj, DocumentWrapper docWrap) throws Exception;
+
+        /**
+     * extractCommonObject extracts common part of a CS document from given Nuxeo document.
+     * @param docWrap nuxeo document
+     * @return common part of CS object
+     * @throws Exception
+     */
+    public TL extractCommonObjectList(DocumentWrapper docWrap) throws Exception;
+
+    /**
+     * fillCommonObject sets common part of CS object into given Nuxeo document
+     * @param obj input object
+     * @param docWrap target Nuxeo document
+     * @throws Exception
+     */
+    public void fillCommonObjectList(TL obj, DocumentWrapper docWrap) throws Exception;
+
+    /**
+     * getCommonObject provides the common part of a CS document.
+     * @return common part of CS document
+     */
+    public T getCommonObject();
+
+    /**
+     * setCommonObject sets common part of CS document as input for operation on
+     * Nuxeo repository
+     * @param obj input object
+     */
+    public void setCommonObject(T obj);
+
+    /**
+     * getCommonObjectList provides the default list object of a CS document.
+     * @return default list of CS document
+     */
+    public TL getCommonObjectList();
+
+    /**
+     * setCommonObjectList sets default list object for CS document as input for operation on
+     * Nuxeo repository
+     * @param default list of CS document
+     */
+    public void setCommonObjectList(TL obj);
+
+    /**
+     * getDocument get org.dom4j.Document from given DocumentModel
+     * @param Nuxeo document wrapper
+     * @return
+     * @throws DocumentException
+     */
+    public Document getDocument(DocumentWrapper docWrap) throws DocumentException;
+
+    /**
+     * getProperties
+     * @return
+     */
+    public Map<String, Object> getProperties();
+
+    /**
+     * setProperties provides means to the CollectionSpace service resource to
+     * set up parameters before invoking create request via the Nuxeo client.
+     * @param properties
+     */
+    public void setProperties(Map<String, Object> properties);
+}
diff --git a/services/common/src/main/java/org/collectionspace/services/common/repository/DocumentNotFoundException.java b/services/common/src/main/java/org/collectionspace/services/common/repository/DocumentNotFoundException.java
new file mode 100644 (file)
index 0000000..5cb6ac7
--- /dev/null
@@ -0,0 +1,78 @@
+/**
+ *  This document is a part of the source code and related artifacts
+ *  for CollectionSpace, an open source collections management system
+ *  for museums and related institutions:
+
+ *  http://www.collectionspace.org
+ *  http://wiki.collectionspace.org
+
+ *  Copyright 2009 University of California at Berkeley
+
+ *  Licensed under the Educational Community License (ECL), Version 2.0.
+ *  You may not use this file except in compliance with this License.
+
+ *  You may obtain a copy of the ECL 2.0 License at
+
+ *  https://source.collectionspace.org/collection-space/LICENSE.txt
+ */
+
+package org.collectionspace.services.common.repository;
+
+/**
+ * DocumentNotFoundException
+ * 
+ */
+public class DocumentNotFoundException extends DocumentException {
+
+    /**
+     * Creates a new instance of <code>DocumentNotFoundException</code> without detail message.
+     */
+    public DocumentNotFoundException() {
+    }
+
+
+    /**
+     * Constructs an instance of <code>DocumentNotFoundException</code> with the specified detail message.
+     * @param msg the detail message.
+     */
+    public DocumentNotFoundException(String msg) {
+        super(msg);
+    }
+
+
+    /**
+     * Constructs a new exception with the specified detail message and
+     * cause.  <p>Note that the detail message associated with
+     * <code>cause</code> is <i>not</i> automatically incorporated in
+     * this exception's detail message.
+     *
+     * @param  message the detail message (which is saved for later retrieval
+     *         by the {@link #getMessage()} method).
+     * @param  cause the cause (which is saved for later retrieval by the
+     *         {@link #getCause()} method).  (A <tt>null</tt> value is
+     *         permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     * @since  1.4
+     */
+    public DocumentNotFoundException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Constructs a new exception with the specified cause and a detail
+     * message of <tt>(cause==null ? null : cause.toString())</tt> (which
+     * typically contains the class and detail message of <tt>cause</tt>).
+     * This constructor is useful for exceptions that are little more than
+     * wrappers for other throwables (for example, {@link
+     * java.security.PrivilegedActionException}).
+     *
+     * @param  cause the cause (which is saved for later retrieval by the
+     *         {@link #getCause()} method).  (A <tt>null</tt> value is
+     *         permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     * @since  1.4
+     */
+    public DocumentNotFoundException(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/services/common/src/main/java/org/collectionspace/services/common/repository/DocumentWrapper.java b/services/common/src/main/java/org/collectionspace/services/common/repository/DocumentWrapper.java
new file mode 100644 (file)
index 0000000..43743ce
--- /dev/null
@@ -0,0 +1,40 @@
+/**
+ *  This document is a part of the source code and related artifacts
+ *  for CollectionSpace, an open source collections management system
+ *  for museums and related institutions:
+
+ *  http://www.collectionspace.org
+ *  http://wiki.collectionspace.org
+
+ *  Copyright 2009 University of California at Berkeley
+
+ *  Licensed under the Educational Community License (ECL), Version 2.0.
+ *  You may not use this file except in compliance with this License.
+
+ *  You may obtain a copy of the ECL 2.0 License at
+
+ *  https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.collectionspace.services.common.repository;
+
+/**
+ *
+ * DocumentWrapper wraps DocumentModel (java) or Representation (REST)
+ *
+ */
+public interface DocumentWrapper {
+
+    /**
+     * getWrappedObject
+     * @return wrapped object
+     */
+    public Object getWrappedObject();
+
+}
diff --git a/services/common/src/main/java/org/collectionspace/services/common/repository/RepositoryClient.java b/services/common/src/main/java/org/collectionspace/services/common/repository/RepositoryClient.java
new file mode 100644 (file)
index 0000000..a5a7e83
--- /dev/null
@@ -0,0 +1,88 @@
+/**
+ *  This document is a part of the source code and related artifacts
+ *  for CollectionSpace, an open source collections management system
+ *  for museums and related institutions:
+
+ *  http://www.collectionspace.org
+ *  http://wiki.collectionspace.org
+
+ *  Copyright 2009 University of California at Berkeley
+
+ *  Licensed under the Educational Community License (ECL), Version 2.0.
+ *  You may not use this file except in compliance with this License.
+
+ *  You may obtain a copy of the ECL 2.0 License at
+
+ *  https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.collectionspace.services.common.repository;
+
+
+/**
+ * RepositoryClient is a generic Document Repository client
+ *
+ * Typical call sequence is:
+ * Create handler and repository client
+ * Call XXX operation on the repository client and pass the handler
+ * repository client calls prepare on the handler
+ * The repository client then calls handle on the handler
+ * 
+ */
+public interface RepositoryClient {
+
+    /**
+     * create document in the Document repository
+     * @param serviceName entity service for which document is created. for example
+     * this is used to find mapping
+     * to a Nuxeo workspace using service-config.xml
+     * @param docType of the document created
+     * @param handler should be used by the caller to provide and transform the document
+     * @return id in repository of the newly created document
+     * @throws BadRequestException data input is bad
+     * @throws DocumentException
+     */
+    String create(String serviceName, String docType, DocumentHandler handler) throws BadRequestException, DocumentException;
+
+    /**
+     * delete a document from the Document repository
+     * @param id of the document
+     * @throws DocumentNotFoundException if document not found
+     * @throws DocumentException
+     */
+    void delete(String id) throws DocumentNotFoundException, DocumentException;
+
+    /**
+     * get document from the Document repository
+     * @param id of the document to retrieve
+     * @param handler should be used by the caller to provide and transform the document
+     * @throws DocumentNotFoundException if document not found
+     * @throws DocumentException
+     */
+    void get(String id, DocumentHandler handler) throws DocumentNotFoundException, DocumentException;
+
+    /**
+     * getAll get all documents for an entity entity service from the Document repository
+     * @param serviceName entity service for which documents are retrieved. this is used to find mapping
+     * to a Nuxeo workspace using service-config.xml
+     * @param handler should be used by the caller to provide and transform the document
+     * @throws DocumentNotFoundException if workspace not found
+     * @throws DocumentException
+     */
+    void getAll(String serviceName, DocumentHandler handler) throws DocumentNotFoundException, DocumentException;
+
+    /**
+     * update given document in the Document repository
+     * @param id of the document
+     * @param handler should be used by the caller to provide and transform the document
+     * @throws BadRequestException data input is bad
+     * @throws DocumentNotFoundException if document not found
+     * @throws DocumentException
+     */
+    void update(String id, DocumentHandler handler) throws BadRequestException, DocumentNotFoundException, DocumentException;
+}
diff --git a/services/common/src/main/java/org/collectionspace/services/common/repository/RepositoryClientFactory.java b/services/common/src/main/java/org/collectionspace/services/common/repository/RepositoryClientFactory.java
new file mode 100644 (file)
index 0000000..c145493
--- /dev/null
@@ -0,0 +1,66 @@
+/**
+ *  This document is a part of the source code and related artifacts
+ *  for CollectionSpace, an open source collections management system
+ *  for museums and related institutions:
+
+ *  http://www.collectionspace.org
+ *  http://wiki.collectionspace.org
+
+ *  Copyright 2009 University of California at Berkeley
+
+ *  Licensed under the Educational Community License (ECL), Version 2.0.
+ *  You may not use this file except in compliance with this License.
+
+ *  You may obtain a copy of the ECL 2.0 License at
+
+ *  https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.collectionspace.services.common.repository;
+
+import java.util.Hashtable;
+import org.collectionspace.services.common.NuxeoClientType;
+
+/**
+ * RepositoryClientFactory is a singleton factory that provides required Nuxeo client
+ * it does not create clients as the clients are singletons
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ */
+public class RepositoryClientFactory {
+
+    
+    private static final RepositoryClientFactory self = new RepositoryClientFactory();
+    private Hashtable<String, RepositoryClient> clients = new Hashtable<String, RepositoryClient>();
+
+    private RepositoryClientFactory() {
+        try{
+            ClassLoader cloader = Thread.currentThread().getContextClassLoader();
+
+            Class jclazz = cloader.loadClass("org.collectionspace.services.nuxeo.client.java.RepositoryJavaClient");
+            Object jclient = jclazz.newInstance();
+            clients.put(NuxeoClientType.JAVA.toString(), (RepositoryClient) jclient);
+
+            Class rclazz = cloader.loadClass("org.collectionspace.services.nuxeo.client.rest.RepositoryRESTClient");
+            Object rclient = rclazz.newInstance();
+            clients.put(NuxeoClientType.REST.toString(), (RepositoryClient) rclient);
+
+        }catch(Exception e){
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static RepositoryClientFactory getInstance() {
+        return self;
+    }
+
+    public RepositoryClient getClient(String clientType) {
+        return clients.get(clientType);
+    }
+}
index 9b2318b9c0d39c926d5df7602de19c9da6f88cf2..deb8112cef083079ed7261f1a1445a247946af42 100644 (file)
@@ -3,8 +3,7 @@
  */\r
 package org.collectionspace.services.nuxeo;\r
 \r
-import org.nuxeo.ecm.core.api.repository.RepositoryInstance;\r
-import org.nuxeo.ecm.core.client.NuxeoClient;\r
+import org.collectionspace.services.nuxeo.client.rest.NuxeoRESTClient;\r
 import org.slf4j.Logger;\r
 import org.slf4j.LoggerFactory;\r
 \r
@@ -29,21 +28,4 @@ public abstract class CollectionSpaceServiceNuxeoImpl {
         return nxClient;\r
     }\r
 \r
-    protected RepositoryInstance getRepositorySession() throws Exception {\r
-        //FIXME: is it possible to reuse repository session?\r
-        //Authentication failures happen while trying to reuse the session\r
-        NuxeoConnector nuxeoConnector = NuxeoConnector.getInstance();\r
-        return nuxeoConnector.getRepositorySession();\r
-    }\r
-\r
-    protected void releaseRepositorySession(RepositoryInstance repoSession) {\r
-        try{\r
-            //release session\r
-            NuxeoConnector nuxeoConnector = NuxeoConnector.getInstance();\r
-            nuxeoConnector.releaseRepositorySession(repoSession);\r
-        }catch(Exception e){\r
-            logger.error("Could not close the repository session", e);\r
-        //no need to throw this service specific exception\r
-        }\r
-    }\r
 }\r
diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/NuxeoCallback.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/NuxeoCallback.java
deleted file mode 100644 (file)
index 6954ae5..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-
-package org.collectionspace.services.nuxeo;
-
-
-import javax.security.auth.callback.Callback;
-
-/**
- * Copied from jbossx
- *
- * An implementation of Callback that simply obtains an Object to be used
- * as the authentication credential. Interpretation of the Object is up to
- * the LoginModules that validate the credential.
- *
- * @author  Scott.Stark@jboss.org
- */
-public class NuxeoCallback implements Callback {
-
-    private final String prompt;
-
-    private Object credential;
-
-    public NuxeoCallback() {
-        this("");
-    }
-
-    public NuxeoCallback(String prompt) {
-        this.prompt = prompt;
-    }
-
-    public String getPrompt() {
-        return prompt;
-    }
-
-    public Object getCredential() {
-        return credential;
-    }
-
-    public void setCredential(Object credential) {
-        this.credential = credential;
-    }
-
-    public void clearCredential() {
-        credential = null;
-    }
-
-}
diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/NuxeoCallbackHandler.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/NuxeoCallbackHandler.java
deleted file mode 100644 (file)
index 565b64a..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.collectionspace.services.nuxeo;
-
-/**
- *
- * @author sanjaydalal
- */
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-import javax.security.auth.callback.UnsupportedCallbackException;
-
-/**
- * Copied from jbossx.
- *
- * @author Scott.Stark@jboss.org
- */
-public class NuxeoCallbackHandler implements CallbackHandler {
-
-    private final String username;
-    private char[] password;
-    private final Object credential;
-
-    /**
-     * Initializes the UsernamePasswordHandler with the username and password to
-     * use.
-     *
-     * @param username the user name
-     * @param password the password for this user
-     */
-    public NuxeoCallbackHandler(String username, char[] password) {
-        this.username = username;
-        this.password = password;
-        credential = password;
-    }
-
-    public NuxeoCallbackHandler(String username, Object credential) {
-        this.username = username;
-        this.credential = credential;
-        if (credential instanceof char[]) {
-            password = (char[]) credential;
-        } else if (credential instanceof CharSequence) {
-            password = credential.toString().toCharArray();
-        }
-    }
-
-    /**
-     * Sets any NameCallback name property to the instance username, sets any
-     * PasswordCallback password property to the instance, and any password.
-     *
-     * @exception UnsupportedCallbackException,
-     *                thrown if any callback of type other than NameCallback or
-     *                PasswordCallback are seen.
-     */
-    public void handle(Callback[] callbacks)
-            throws UnsupportedCallbackException {
-        for (Callback c : callbacks) {
-            if (c instanceof NameCallback) {
-                NameCallback nc = (NameCallback) c;
-                nc.setName(username);
-            } else if (c instanceof PasswordCallback) {
-                PasswordCallback pc = (PasswordCallback) c;
-                if (password == null) {
-                    // We were given an opaque Object credential but a char[] is
-                    // requested?
-                    if (credential != null) {
-                        String tmp = credential.toString();
-                        password = tmp.toCharArray();
-                    }
-                }
-                pc.setPassword(password);
-            } else if (c instanceof NuxeoCallback) {
-                NuxeoCallback oc = (NuxeoCallback) c;
-                oc.setCredential(credential);
-            } else {
-                throw new UnsupportedCallbackException(c,
-                        "Unrecognized Callback");
-            }
-        }
-    }
-}
diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/NuxeoLoginConfiguration.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/NuxeoLoginConfiguration.java
deleted file mode 100644 (file)
index e008f47..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.collectionspace.services.nuxeo;
-
-/**
- *
- * @author sanjaydalal
- */
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.security.auth.login.AppConfigurationEntry;
-import javax.security.auth.login.Configuration;
-import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
-
-public class NuxeoLoginConfiguration extends Configuration {
-
-    private final Configuration parent;
-    public static final String LOGIN_DOMAIN = "nuxeo-client-login";
-
-    public NuxeoLoginConfiguration(Configuration parent) {
-        this.parent = parent;
-    }
-
-    @Override
-    public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
-
-        if (LOGIN_DOMAIN.equals(name)) {
-            AppConfigurationEntry[] entries = new AppConfigurationEntry[1];
-
-            Map<String, Object> options = new HashMap<String, Object>();
-
-            options.put("restore-login-identity", "True");
-            options.put("multi-threaded", "True");
-
-            entries[0] = new AppConfigurationEntry("org.jboss.security.ClientLoginModule", LoginModuleControlFlag.REQUIRED, options);
-
-
-            return entries;
-        } else {
-            return parent.getAppConfigurationEntry(name);
-        }
-    }
-
-    @Override
-    public void refresh() {
-        if (parent != null) {
-            parent.refresh();
-        }
-    }
-}
diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/NuxeoLoginContextFactory.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/NuxeoLoginContextFactory.java
deleted file mode 100644 (file)
index fd02d18..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-
-package org.collectionspace.services.nuxeo;
-
-/**
- *
- * @author sanjaydalal
- */
-
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.login.Configuration;
-import javax.security.auth.login.LoginContext;
-import javax.security.auth.login.LoginException;
-
-public class NuxeoLoginContextFactory {
-
-
-    private static boolean initDone=false;
-
-    private static void initLoginConfig()
-    {
-        if (initDone)
-            return;
-
-        Configuration parentConfig = null;
-        try {
-            parentConfig = Configuration.getConfiguration();
-        } catch (Exception e) {
-            // do nothing - this can happen if default configuration provider is not correctly configured
-            // for examnple FileConfig fails if no config file was defined
-        }
-        Configuration config = new NuxeoLoginConfiguration(parentConfig);
-        Configuration.setConfiguration(config);
-
-        initDone=true;
-
-    }
-
-
-    public static LoginContext getLoginContext(CallbackHandler handler) throws LoginException
-    {
-        initLoginConfig();
-        return  new LoginContext(NuxeoLoginConfiguration.LOGIN_DOMAIN, handler);
-    }
-}
diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/DocumentModelHandler.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/DocumentModelHandler.java
new file mode 100644 (file)
index 0000000..ada2139
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ *  This document is a part of the source code and related artifacts
+ *  for CollectionSpace, an open source collections management system
+ *  for museums and related institutions:
+
+ *  http://www.collectionspace.org
+ *  http://wiki.collectionspace.org
+
+ *  Copyright 2009 University of California at Berkeley
+
+ *  Licensed under the Educational Community License (ECL), Version 2.0.
+ *  You may not use this file except in compliance with this License.
+
+ *  You may obtain a copy of the ECL 2.0 License at
+
+ *  https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.collectionspace.services.nuxeo.client.java;
+
+import org.collectionspace.services.common.repository.DocumentHandler;
+import org.collectionspace.services.common.repository.DocumentWrapper;
+import org.collectionspace.services.common.repository.DocumentException;
+import java.util.HashMap;
+import java.util.Map;
+import org.collectionspace.services.nuxeo.client.*;
+import org.collectionspace.services.nuxeo.util.NuxeoUtils;
+import org.dom4j.Document;
+import org.nuxeo.ecm.core.api.DocumentModel;
+import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
+
+/**
+ * DocumentModelHandler is a base abstract Nuxeo document handler
+ * using Nuxeo Java Remote APIs for CollectionSpace services
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ */
+public abstract class DocumentModelHandler<T, TL>
+        implements DocumentHandler<T, TL> {
+
+    private Map<String, Object> properties = new HashMap<String, Object>();
+    private RepositoryInstance repositorySession;
+
+    @Override
+    public abstract void prepare(Action action) throws Exception;
+
+    @Override
+    public abstract void handle(Action action, DocumentWrapper wrap) throws Exception;
+
+    /**
+     * getRepositorySession returns Nuxeo Repository Session
+     * @return
+     */
+    public RepositoryInstance getRepositorySession() {
+        return repositorySession;
+    }
+
+    /**
+     * setRepositorySession sets repository session
+     * @param repoSession
+     */
+    public void setRepositorySession(RepositoryInstance repoSession) {
+        this.repositorySession = repoSession;
+    }
+
+    @Override
+    public abstract T extractCommonObject(DocumentWrapper wrapDoc) throws Exception;
+
+    @Override
+    public abstract void fillCommonObject(T obj, DocumentWrapper wrapDoc) throws Exception;
+
+    @Override
+    public abstract TL extractCommonObjectList(DocumentWrapper wrapDoc) throws Exception;
+
+    @Override
+    public abstract void fillCommonObjectList(TL obj, DocumentWrapper wrapDoc) throws Exception;
+
+    @Override
+    public abstract T getCommonObject();
+
+    @Override
+    public abstract void setCommonObject(T obj);
+
+    @Override
+    public abstract TL getCommonObjectList();
+
+    @Override
+    public abstract void setCommonObjectList(TL obj);
+
+    @Override
+    public Document getDocument(DocumentWrapper wrapDoc) throws DocumentException {
+        DocumentModel docModel = (DocumentModel) wrapDoc.getWrappedObject();
+        return NuxeoUtils.getDocument(getRepositorySession(), docModel);
+    }
+
+    /**
+     * @return the properties
+     */
+    @Override
+    public Map<String, Object> getProperties() {
+        return properties;
+    }
+
+    /**
+     * @param properties the properties to set
+     */
+    @Override
+    public void setProperties(Map<String, Object> properties) {
+        this.properties = properties;
+    }
+}
diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/DocumentModelListWrapper.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/DocumentModelListWrapper.java
new file mode 100644 (file)
index 0000000..9248c21
--- /dev/null
@@ -0,0 +1,49 @@
+/**
+ *  This document is a part of the source code and related artifacts
+ *  for CollectionSpace, an open source collections management system
+ *  for museums and related institutions:
+
+ *  http://www.collectionspace.org
+ *  http://wiki.collectionspace.org
+
+ *  Copyright 2009 University of California at Berkeley
+
+ *  Licensed under the Educational Community License (ECL), Version 2.0.
+ *  You may not use this file except in compliance with this License.
+
+ *  You may obtain a copy of the ECL 2.0 License at
+
+ *  https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.collectionspace.services.nuxeo.client.java;
+
+import org.collectionspace.services.common.repository.DocumentWrapper;
+import org.nuxeo.ecm.core.api.DocumentModelList;
+
+/**
+* DocumentModelListWrapper wraps Nuxeo DocumentModel
+*
+* $LastChangedRevision: $
+* $LastChangedDate: $
+*/
+public class DocumentModelListWrapper implements DocumentWrapper {
+
+    private DocumentModelList docModelList;
+
+    public DocumentModelListWrapper(DocumentModelList docModelList) {
+        this.docModelList = docModelList;
+    }
+    
+    @Override
+    public Object getWrappedObject() {
+        return docModelList;
+    }
+
+}
diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/DocumentModelWrapper.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/DocumentModelWrapper.java
new file mode 100644 (file)
index 0000000..75d9938
--- /dev/null
@@ -0,0 +1,49 @@
+/**
+ *  This document is a part of the source code and related artifacts
+ *  for CollectionSpace, an open source collections management system
+ *  for museums and related institutions:
+
+ *  http://www.collectionspace.org
+ *  http://wiki.collectionspace.org
+
+ *  Copyright 2009 University of California at Berkeley
+
+ *  Licensed under the Educational Community License (ECL), Version 2.0.
+ *  You may not use this file except in compliance with this License.
+
+ *  You may obtain a copy of the ECL 2.0 License at
+
+ *  https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.collectionspace.services.nuxeo.client.java;
+
+import org.collectionspace.services.common.repository.DocumentWrapper;
+import org.nuxeo.ecm.core.api.DocumentModel;
+
+/**
+* DocumentModelWrapper wraps Nuxeo DocumentModel
+*
+* $LastChangedRevision: $
+* $LastChangedDate: $
+*/
+public class DocumentModelWrapper implements DocumentWrapper {
+
+    private DocumentModel docModel;
+
+    public DocumentModelWrapper(DocumentModel docModel) {
+        this.docModel = docModel;
+    }
+    
+    @Override
+    public Object getWrappedObject() {
+        return docModel;
+    }
+
+}
similarity index 89%
rename from services/common/src/main/java/org/collectionspace/services/nuxeo/NuxeoConnector.java
rename to services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoConnector.java
index ff61a8c729ef81be3450ea9bc24ec55ae144b8c3..491a105e5840353dee580de90cdb2ab66e2844f7 100644 (file)
@@ -1,7 +1,27 @@
 /**
- * Copyright 2009 University of California at Berkeley
+ *  This document is a part of the source code and related artifacts
+ *  for CollectionSpace, an open source collections management system
+ *  for museums and related institutions:
+
+ *  http://www.collectionspace.org
+ *  http://wiki.collectionspace.org
+
+ *  Copyright 2009 University of California at Berkeley
+
+ *  Licensed under the Educational Community License (ECL), Version 2.0.
+ *  You may not use this file except in compliance with this License.
+
+ *  You may obtain a copy of the ECL 2.0 License at
+
+ *  https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
  */
-package org.collectionspace.services.nuxeo;
+package org.collectionspace.services.nuxeo.client.java;
 
 import java.io.File;
 import java.util.Collection;
@@ -63,7 +83,7 @@ public class NuxeoConnector {
                         initialized = true;
                     }catch(Exception e){
                         if(logger.isDebugEnabled()){
-                            e.printStackTrace();
+                            logger.debug("Caught exception while initializing", e);
                         }
                     }
                 }
@@ -134,7 +154,7 @@ public class NuxeoConnector {
 //                return client;
 //            }else{
             //authentication failure error comes when reusing the client
-            //fore connect for now
+            //force connect for now
             client.forceConnect(nuxeoClientConfig.getHost(), nuxeoClientConfig.getPort());
             if(logger.isDebugEnabled()){
                 logger.debug("getClient(): connection successful port=" +
diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryJavaClient.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryJavaClient.java
new file mode 100644 (file)
index 0000000..3831c45
--- /dev/null
@@ -0,0 +1,310 @@
+/**
+ *  This document is a part of the source code and related artifacts
+ *  for CollectionSpace, an open source collections management system
+ *  for museums and related institutions:
+
+ *  http://www.collectionspace.org
+ *  http://wiki.collectionspace.org
+
+ *  Copyright 2009 University of California at Berkeley
+
+ *  Licensed under the Educational Community License (ECL), Version 2.0.
+ *  You may not use this file except in compliance with this License.
+
+ *  You may obtain a copy of the ECL 2.0 License at
+
+ *  https://source.collectionspace.org/collection-space/LICENSE.txt
+ */
+package org.collectionspace.services.nuxeo.client.java;
+
+import org.collectionspace.services.common.repository.RepositoryClient;
+import org.collectionspace.services.common.ServiceMain;
+import org.collectionspace.services.common.repository.BadRequestException;
+import org.collectionspace.services.common.repository.DocumentNotFoundException;
+import org.collectionspace.services.common.repository.DocumentHandler;
+import org.collectionspace.services.common.repository.DocumentException;
+import org.collectionspace.services.common.repository.DocumentHandler.Action;
+import org.nuxeo.common.utils.IdUtils;
+import org.nuxeo.ecm.core.api.ClientException;
+import org.nuxeo.ecm.core.api.DocumentModel;
+import org.nuxeo.ecm.core.api.DocumentModelList;
+import org.nuxeo.ecm.core.api.DocumentRef;
+import org.nuxeo.ecm.core.api.IdRef;
+import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
+import org.nuxeo.ecm.core.client.NuxeoClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * RepositoryJavaClient is used to perform CRUD operations on documents
+ * in Nuxeo repository using Remote Java APIs. It uses @see DocumentHandler
+ * as IOHandler with the client.
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ */
+public class RepositoryJavaClient implements RepositoryClient {
+
+    private final Logger logger = LoggerFactory.getLogger(RepositoryJavaClient.class);
+
+    public RepositoryJavaClient() {
+    }
+
+    /**
+     * create document in the Nuxeo repository
+     * @param serviceName entity service for which document is created. this is used to find mapping
+     * to a Nuxeo workspace using service-config.xml
+     * @param docType of the document created
+     * @param handler should be used by the caller to provide and transform the document
+     * @return id in repository of the newly created document
+     * @throws DocumentException
+     */
+    @Override
+    public String create(String serviceName, String docType, DocumentHandler handler) throws BadRequestException, DocumentException {
+
+        if(serviceName == null){
+            throw new IllegalArgumentException("RemoteRepositoryClient.create: serviceName is missing");
+        }
+        if(docType == null){
+            throw new IllegalArgumentException("RemoteRepositoryClient.create: docType is missing");
+        }
+        if(handler == null){
+            throw new IllegalArgumentException("RemoteRepositoryClient.create: handler is missing");
+        }
+        ServiceMain smain = ServiceMain.getInstance();
+        String nuxeoWspaceId = smain.getWorkspaceId(serviceName);
+        if(nuxeoWspaceId == null){
+            throw new DocumentNotFoundException("Unable to find workspace for service " + serviceName +
+                    " check if the mapping exists in service-config.xml or " +
+                    " the the mapped workspace exists in the Nuxeo repository");
+        }
+        RepositoryInstance repoSession = null;
+        try{
+            handler.prepare(Action.CREATE);
+            repoSession = getRepositorySession();
+
+            DocumentRef nuxeoWspace = new IdRef(nuxeoWspaceId);
+            DocumentModel wspaceDoc = repoSession.getDocument(nuxeoWspace);
+            String wspacePath = wspaceDoc.getPathAsString();
+            String id = IdUtils.generateId("New " + docType);
+            //create document model
+            DocumentModel doc = repoSession.createDocumentModel(wspacePath, id, docType);
+            ((DocumentModelHandler) handler).setRepositorySession(repoSession);
+            DocumentModelWrapper wrapDoc = new DocumentModelWrapper(doc);
+            handler.handle(Action.CREATE, wrapDoc);
+            //create document with documentmodel
+            doc = repoSession.createDocument(doc);
+            repoSession.save();
+            return doc.getId();
+        }catch(Exception e){
+            if(logger.isDebugEnabled()){
+                logger.debug("Caught exception ", e);
+            }
+            throw new DocumentException(e);
+        }finally{
+            if(repoSession != null){
+                releaseRepositorySession(repoSession);
+            }
+        }
+
+    }
+
+    /**
+     * get document from the Nuxeo repository
+     * @param id of the document to retrieve
+     * @param handler should be used by the caller to provide and transform the document
+     * @throws DocumentException
+     */
+    @Override
+    public void get(String id, DocumentHandler handler) throws DocumentNotFoundException, DocumentException {
+
+        if(handler == null){
+            throw new IllegalArgumentException("RemoteRepositoryClient.get: handler is missing");
+        }
+        RepositoryInstance repoSession = null;
+
+        try{
+            handler.prepare(Action.GET);
+            repoSession = getRepositorySession();
+            DocumentRef docRef = new IdRef(id);
+            DocumentModel doc = null;
+            try{
+                doc = repoSession.getDocument(docRef);
+            }catch(ClientException ce){
+                String msg = "could not find document with id=" + id;
+                logger.error(msg, ce);
+                throw new DocumentNotFoundException(msg, ce);
+            }
+            ((DocumentModelHandler) handler).setRepositorySession(repoSession);
+            DocumentModelWrapper wrapDoc = new DocumentModelWrapper(doc);
+            handler.handle(Action.GET, wrapDoc);
+                    }catch(IllegalArgumentException iae) {
+            throw iae;
+        }catch(DocumentException de){
+            throw de;
+        }catch(Exception e){
+            if(logger.isDebugEnabled()){
+                logger.debug("Caught exception ", e);
+            }
+            throw new DocumentException(e);
+        }finally{
+            if(repoSession != null){
+                releaseRepositorySession(repoSession);
+            }
+        }
+    }
+
+    /**
+     * getAll get all documents for an entity entity service from the Nuxeo repository
+     * @param serviceName entity service for which documents are retrieved. this is used to find mapping
+     * to a Nuxeo workspace using service-config.xml
+     * @param handler should be used by the caller to provide and transform the document
+     * @throws DocumentException
+     */
+    @Override
+    public void getAll(String serviceName, DocumentHandler handler) throws DocumentNotFoundException, DocumentException {
+        if(serviceName == null){
+            throw new IllegalArgumentException("RemoteRepositoryClient.getAll: serviceName is missing");
+        }
+        if(handler == null){
+            throw new IllegalArgumentException("RemoteRepositoryClient.getAll: handler is missing");
+        }
+        ServiceMain smain = ServiceMain.getInstance();
+        String nuxeoWspaceId = smain.getWorkspaceId(serviceName);
+        if(nuxeoWspaceId == null){
+            throw new DocumentNotFoundException("Unable to find workspace for service " + serviceName +
+                    " check if the mapping exists in service-config.xml or " +
+                    " the the mapped workspace exists in the Nuxeo repository");
+        }
+        RepositoryInstance repoSession = null;
+
+        try{
+            handler.prepare(Action.GET_ALL);
+            repoSession = getRepositorySession();
+            DocumentRef wsDocRef = new IdRef(nuxeoWspaceId);
+            DocumentModelList docList = repoSession.getChildren(wsDocRef);
+
+            ((DocumentModelHandler) handler).setRepositorySession(repoSession);
+            DocumentModelListWrapper wrapDoc = new DocumentModelListWrapper(docList);
+            handler.handle(Action.GET_ALL, wrapDoc);
+            
+        }catch(DocumentException de){
+            throw de;
+        }catch(Exception e){
+            if(logger.isDebugEnabled()){
+                logger.debug("Caught exception ", e);
+            }
+            throw new DocumentException(e);
+        }finally{
+            if(repoSession != null){
+                releaseRepositorySession(repoSession);
+            }
+        }
+    }
+
+    /**
+     * update given document in the Nuxeo repository
+     * @param id of the document
+     * @param handler should be used by the caller to provide and transform the document
+     * @throws DocumentException
+     */
+    @Override
+    public void update(String id, DocumentHandler handler) throws BadRequestException, DocumentNotFoundException, DocumentException {
+        if(id == null){
+            throw new BadRequestException("RemoteRepositoryClient.update: id is missing");
+        }
+        if(handler == null){
+            throw new IllegalArgumentException("RemoteRepositoryClient.update: handler is missing");
+        }
+        RepositoryInstance repoSession = null;
+        try{
+            handler.prepare(Action.UPDATE);
+            repoSession = getRepositorySession();
+            DocumentRef docRef = new IdRef(id);
+            DocumentModel doc = null;
+            try{
+                doc = repoSession.getDocument(docRef);
+            }catch(ClientException ce){
+                String msg = "Could not find document to update with id=" + id;
+                logger.error(msg, ce);
+                throw new DocumentNotFoundException(msg, ce);
+            }
+            ((DocumentModelHandler) handler).setRepositorySession(repoSession);
+            DocumentModelWrapper wrapDoc = new DocumentModelWrapper(doc);
+            handler.handle(Action.UPDATE, wrapDoc);
+            repoSession.saveDocument(doc);
+            repoSession.save();
+        }catch(DocumentException de){
+            throw de;
+        }catch(Exception e){
+            if(logger.isDebugEnabled()){
+                logger.debug("Caught exception ", e);
+            }
+            throw new DocumentException(e);
+        }finally{
+            if(repoSession != null){
+                releaseRepositorySession(repoSession);
+            }
+        }
+    }
+
+    /**
+     * delete a document from the Nuxeo repository
+     * @param id of the document
+     * @throws DocumentException
+     */
+    @Override
+    public void delete(String id) throws DocumentNotFoundException, DocumentException {
+
+        if(logger.isDebugEnabled()){
+            logger.debug("deleting document with id=" + id);
+        }
+        RepositoryInstance repoSession = null;
+        try{
+            repoSession = getRepositorySession();
+            DocumentRef docRef = new IdRef(id);
+            try{
+                repoSession.removeDocument(docRef);
+            }catch(ClientException ce){
+                String msg = "could not find document to delete with id=" + id;
+                logger.error(msg, ce);
+                throw new DocumentNotFoundException(msg, ce);
+            }
+            repoSession.save();
+        }catch(DocumentException de){
+            throw de;
+        }catch(Exception e){
+            if(logger.isDebugEnabled()){
+                logger.debug("Caught exception ", e);
+            }
+            throw new DocumentException(e);
+        }finally{
+            if(repoSession != null){
+                releaseRepositorySession(repoSession);
+            }
+        }
+    }
+
+    private RepositoryInstance getRepositorySession() throws Exception {
+        //FIXME: is it possible to reuse repository session?
+        //Authentication failures happen while trying to reuse the session
+        NuxeoClient client = NuxeoConnector.getInstance().getClient();
+        RepositoryInstance repoSession = client.openRepository();
+        if(logger.isDebugEnabled()){
+            logger.debug("getRepository() repository root: " +
+                    repoSession.getRootDocument());
+        }
+        return repoSession;
+    }
+
+    private void releaseRepositorySession(RepositoryInstance repoSession) {
+        try{
+            NuxeoClient client = NuxeoConnector.getInstance().getClient();
+            //release session
+            client.releaseRepository(repoSession);
+        }catch(Exception e){
+            logger.error("Could not close the repository session", e);
+            //no need to throw this service specific exception
+        }
+    }
+}
similarity index 76%
rename from services/common/src/main/java/org/collectionspace/services/nuxeo/NuxeoRESTClient.java
rename to services/common/src/main/java/org/collectionspace/services/nuxeo/client/rest/NuxeoRESTClient.java
index f8785852cb70d6904a7ab065e0e7f7bd9d3a5d61..e4e42e875bb086bc65d080e7d37015fc41c580ef 100644 (file)
@@ -16,7 +16,7 @@
  *
  * $Id: JOOoConvertPluginImpl.java 18651 2007-05-13 20:28:53Z sfermigier $
  */
-package org.collectionspace.services.nuxeo;
+package org.collectionspace.services.nuxeo.client.rest;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -68,13 +68,13 @@ public class NuxeoRESTClient {
         sb.append(protocol);
         sb.append("://");
         sb.append(serverIP);
-        if (serverPort != null && !serverIP.equals("80")) {
+        if(serverPort != null && !serverIP.equals("80")){
             sb.append(':');
             sb.append(serverPort);
         }
-        sb.append(servletPath);
         sb.append('/');
-        baseURL = sb.toString();
+        sb.append(servletPath);
+        this.baseURL = sb.toString();
     }
 
     public void setBasicAuthentication(String userName, String password) {
@@ -99,8 +99,8 @@ public class NuxeoRESTClient {
         String path = "";
         StringBuffer pathBuffer = new StringBuffer();
 
-        if (pathParams != null) {
-            for (String p : pathParams) {
+        if(pathParams != null){
+            for(String p : pathParams){
                 pathBuffer.append(p);
                 pathBuffer.append('/');
             }
@@ -114,10 +114,10 @@ public class NuxeoRESTClient {
             Map<String, String> queryParams, InputStream istream) {
         StringBuffer urlBuffer = new StringBuffer();
 
-        if (subPath.startsWith("/")) {
+        if(subPath.startsWith("/")){
             subPath = subPath.substring(1);
         }
-        if (subPath.endsWith("/")) {
+        if(subPath.endsWith("/")){
             subPath = subPath.substring(0, subPath.length() - 1);
         }
 
@@ -127,16 +127,16 @@ public class NuxeoRESTClient {
         urlBuffer.append('/');
         urlBuffer.append(subPath);
 
-        if (queryParams != null) {
+        if(queryParams != null){
             urlBuffer.append('?');
-            
+
             String qpValue = null;
-            for (String qpName : queryParams.keySet()) {
+            for(String qpName : queryParams.keySet()){
                 urlBuffer.append(qpName);
                 urlBuffer.append('=');
                 qpValue = queryParams.get(qpName);
-                if (qpValue != null) {
-                       urlBuffer.append(qpValue.replaceAll(" ", "%20"));
+                if(qpValue != null){
+                    urlBuffer.append(qpValue.replaceAll(" ", "%20"));
                 }
                 urlBuffer.append('&');
             }
@@ -156,7 +156,7 @@ public class NuxeoRESTClient {
             public void write(OutputStream outputStream) throws IOException {
                 byte[] buffer = new byte[1024 * 64];
                 int read;
-                while ((read = in.read(buffer)) != -1) {
+                while((read = in.read(buffer)) != -1){
                     outputStream.write(buffer, 0, read);
                 }
 
@@ -171,8 +171,8 @@ public class NuxeoRESTClient {
         String path = "";
         StringBuffer pathBuffer = new StringBuffer();
 
-        if (pathParams != null) {
-            for (String p : pathParams) {
+        if(pathParams != null){
+            for(String p : pathParams){
                 pathBuffer.append(p);
                 pathBuffer.append('/');
             }
@@ -186,10 +186,10 @@ public class NuxeoRESTClient {
             Map<String, String> queryParams) {
         StringBuffer urlBuffer = new StringBuffer();
 
-        if (subPath.startsWith("/")) {
+        if(subPath.startsWith("/")){
             subPath = subPath.substring(1);
         }
-        if (subPath.endsWith("/")) {
+        if(subPath.endsWith("/")){
             subPath = subPath.substring(0, subPath.length() - 1);
         }
 
@@ -199,9 +199,9 @@ public class NuxeoRESTClient {
         urlBuffer.append('/');
         urlBuffer.append(subPath);
 
-        if (queryParams != null) {
+        if(queryParams != null){
             urlBuffer.append('?');
-            for (String qpName : queryParams.keySet()) {
+            for(String qpName : queryParams.keySet()){
                 urlBuffer.append(qpName);
                 urlBuffer.append('=');
                 urlBuffer.append(queryParams.get(qpName).replaceAll(" ", "%20"));
@@ -220,19 +220,19 @@ public class NuxeoRESTClient {
 
     protected void setupAuth(Request request) {
 
-        if (authType == AUTH_TYPE_BASIC) {
+        if(authType == AUTH_TYPE_BASIC){
             ChallengeScheme scheme = ChallengeScheme.HTTP_BASIC;
             ChallengeResponse authentication = new ChallengeResponse(scheme,
                     userName, password);
             request.setChallengeResponse(authentication);
 
-        } else if (authType == AUTH_TYPE_SECRET) {
+        }else if(authType == AUTH_TYPE_SECRET){
             Series<Parameter> additionnalHeaders = new Form();
 
             Map<String, String> securityHeaders = PortalSSOAuthenticationProvider.getHeaders(
                     secretToken, userName);
 
-            for (String hn : securityHeaders.keySet()) {
+            for(String hn : securityHeaders.keySet()){
                 additionnalHeaders.add(hn, securityHeaders.get(hn));
             }
 
@@ -242,20 +242,20 @@ public class NuxeoRESTClient {
     }
 
     protected void setupCookies(Request request) {
-        if (cookies != null) {
+        if(cookies != null){
             request.getCookies().clear();
-            for (Cookie cookie : cookies) {
+            for(Cookie cookie : cookies){
                 request.getCookies().add(cookie);
             }
         }
 
     }
 
-    protected Client getRestClient() {
-        if (restClient == null) {
-            if (baseURL.startsWith("https")) {
+    Client getRestClient() {
+        if(restClient == null){
+            if(baseURL.startsWith("https")){
                 restClient = new Client(Protocol.HTTPS);
-            } else {
+            }else{
                 restClient = new Client(Protocol.HTTP);
             }
         }
@@ -310,4 +310,56 @@ public class NuxeoRESTClient {
     public void setUserName(String userName) {
         this.userName = userName;
     }
+
+    /**
+     * buildUrl build URL from given path and query parameters
+     * @param pathParams
+     * @param queryParams
+     * @return
+     */
+    String buildUrl(List<String> pathParams,
+            Map<String, String> queryParams) {
+        String subPath = "";
+        StringBuffer pathBuffer = new StringBuffer();
+
+        if(pathParams != null){
+            for(String p : pathParams){
+                pathBuffer.append(p);
+                pathBuffer.append('/');
+            }
+            subPath = pathBuffer.toString();
+        }
+
+        StringBuffer urlBuffer = new StringBuffer();
+
+        if(subPath.startsWith("/")){
+            subPath = subPath.substring(1);
+        }
+        if(subPath.endsWith("/")){
+            subPath = subPath.substring(0, subPath.length() - 1);
+        }
+
+        urlBuffer.append(baseURL);
+        urlBuffer.append('/');
+        urlBuffer.append(restPrefix);
+        urlBuffer.append('/');
+        urlBuffer.append(subPath);
+
+        if(queryParams != null){
+            urlBuffer.append('?');
+
+            String qpValue = null;
+            for(String qpName : queryParams.keySet()){
+                urlBuffer.append(qpName);
+                urlBuffer.append('=');
+                qpValue = queryParams.get(qpName);
+                if(qpValue != null){
+                    urlBuffer.append(qpValue.replaceAll(" ", "%20"));
+                }
+                urlBuffer.append('&');
+            }
+        }
+
+        return urlBuffer.toString();
+    }
 }
similarity index 97%
rename from services/common/src/main/java/org/collectionspace/services/nuxeo/PortalSSOAuthenticationProvider.java
rename to services/common/src/main/java/org/collectionspace/services/nuxeo/client/rest/PortalSSOAuthenticationProvider.java
index 0bd2e5189ab17fa8395b828c6c4f00c4f74ac5b7..144c1ac2338aa300ce3208a3fccbb6785f662f35 100644 (file)
@@ -17,7 +17,7 @@
  * $Id: JOOoConvertPluginImpl.java 18651 2007-05-13 20:28:53Z sfermigier $
  */
 
-package org.collectionspace.services.nuxeo;
+package org.collectionspace.services.nuxeo.client.rest;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.util.Date;
diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/rest/RepositoryRESTClient.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/rest/RepositoryRESTClient.java
new file mode 100644 (file)
index 0000000..ec75521
--- /dev/null
@@ -0,0 +1,397 @@
+/**
+ *  This document is a part of the source code and related artifacts
+ *  for CollectionSpace, an open source collections management system
+ *  for museums and related institutions:
+
+ *  http://www.collectionspace.org
+ *  http://wiki.collectionspace.org
+
+ *  Copyright 2009 University of California at Berkeley
+
+ *  Licensed under the Educational Community License (ECL), Version 2.0.
+ *  You may not use this file except in compliance with this License.
+
+ *  You may obtain a copy of the ECL 2.0 License at
+
+ *  https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.collectionspace.services.nuxeo.client.rest;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import org.collectionspace.services.common.repository.DocumentException;
+import org.collectionspace.services.common.repository.DocumentHandler;
+import org.collectionspace.services.common.repository.RepositoryClient;
+
+import org.restlet.data.Request;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.Map;
+
+import org.collectionspace.services.common.ServiceConfig;
+import org.collectionspace.services.common.ServiceConfig.NuxeoClientConfig;
+import org.collectionspace.services.common.ServiceMain;
+import org.collectionspace.services.common.repository.BadRequestException;
+import org.collectionspace.services.common.repository.DocumentNotFoundException;
+import org.collectionspace.services.common.repository.DocumentHandler.Action;
+import org.dom4j.Document;
+import org.dom4j.Element;
+import org.dom4j.io.SAXReader;
+import org.dom4j.tree.DefaultDocument;
+import org.restlet.data.MediaType;
+import org.restlet.data.Method;
+import org.restlet.data.Response;
+import org.restlet.data.Status;
+import org.restlet.resource.OutputRepresentation;
+import org.restlet.resource.Representation;
+
+/**
+ * RepositoryRESTClient is used to perform CRUD operations on documents
+ * in Nuxeo repository using Nuxeo RESTful APIs. It uses @see DocumentHandler
+ * as IOHandler with the client.
+ *
+ * v2 NuxeoClient
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ */
+public class RepositoryRESTClient implements RepositoryClient {
+
+    private final Logger logger = LoggerFactory.getLogger(RepositoryRESTClient.class);
+    private NuxeoRESTClient nuxeoRestClient;
+
+    public RepositoryRESTClient() {
+    }
+
+    @Override
+    public String create(String serviceName, String docType, DocumentHandler handler) throws BadRequestException, DocumentException {
+        if(serviceName == null){
+            throw new IllegalArgumentException("RepositoryRESTClient.create: serviceName is missing");
+        }
+        if(docType == null){
+            throw new IllegalArgumentException("RepositoryRESTClient.create: docType is missing");
+        }
+        if(handler == null){
+            throw new IllegalArgumentException("RepositoryRESTClient.create: handler is missing");
+        }
+        ServiceMain smain = ServiceMain.getInstance();
+        String nuxeoWspaceId = smain.getWorkspaceId(serviceName);
+        if(nuxeoWspaceId == null){
+            throw new DocumentNotFoundException("Unable to find workspace for service " + serviceName +
+                    " check if the mapping exists in service-config.xml or " +
+                    " the the mapped workspace exists in the Nuxeo repository");
+        }
+        try{
+            RepresentationHandler repHandler = (RepresentationHandler) handler;
+            repHandler.prepare(Action.CREATE);
+            List<String> pathParams = new ArrayList<String>();
+            pathParams.add("default");
+            pathParams.add(nuxeoWspaceId);
+            pathParams.add("createDocument");
+            if(repHandler.getPathParams().size() > 0){
+                pathParams.addAll(repHandler.getPathParams());
+            }
+            Map<String, String> queryParams = new HashMap<String, String>();
+            queryParams.put("docType", docType);
+            // a default title for the Dublin Core schema
+            queryParams.put("dublincore:title", "CollectionSpace-" + docType);
+            if(repHandler.getQueryParams().size() > 0){
+                queryParams.putAll(repHandler.getQueryParams());
+            }
+
+            String completeURL = getNuxeoRestClient().buildUrl(pathParams, queryParams);
+            if(logger.isDebugEnabled()){
+                logger.debug("create using url=" + completeURL);
+            }
+            Request request = buildRequest(Method.POST, completeURL);
+
+            //write out create stream, this is not needed as queryParams
+            //contain the document
+            final InputStream in = new ByteArrayInputStream(new byte[0]);
+            request.setEntity(new OutputRepresentation(
+                    MediaType.MULTIPART_FORM_DATA) {
+
+                @Override
+                public void write(OutputStream outputStream) throws IOException {
+                    byte[] buffer = new byte[1024 * 64];
+                    int read;
+                    while((read = in.read(buffer)) != -1){
+                        outputStream.write(buffer, 0, read);
+                    }
+                }
+            });
+            //following call to handler.handle is not needed as queryparams
+            //contains the real data
+            RepresentationWrapper wrapDoc = new RepresentationWrapper(new DefaultDocument());
+            repHandler.handle(Action.CREATE, wrapDoc);
+            //read response
+            //Nuxeo does not set 201 SUCCESS_CREATED on successful creation
+            Document document = executeRequest(request, completeURL, Status.SUCCESS_OK);
+            //handle is not needed on create as queryparams have all data
+            return extractId(document);
+
+        }catch(Exception e){
+            if(logger.isDebugEnabled()){
+                logger.debug("Caught exception ", e);
+            }
+            throw new DocumentException(e);
+        }finally{
+        }
+    }
+
+    @Override
+    public void get(String id, DocumentHandler handler) throws DocumentNotFoundException, DocumentException {
+
+        if(handler == null){
+            throw new IllegalArgumentException("RepositoryRESTClient.get: handler is missing");
+        }
+
+        try{
+            RepresentationHandler repHandler = (RepresentationHandler) handler;
+            repHandler.prepare(Action.GET);
+            ArrayList pathParams = new ArrayList();
+            pathParams.add("default");
+            pathParams.add(id);
+            pathParams.add("export");
+            if(repHandler.getPathParams().size() > 0){
+                pathParams.addAll(repHandler.getPathParams());
+            }
+            HashMap<String, String> queryParams = new HashMap<String, String>();
+            queryParams.put("format", "XML");
+            if(repHandler.getQueryParams().size() > 0){
+                queryParams.putAll(repHandler.getQueryParams());
+            }
+            String completeURL = getNuxeoRestClient().buildUrl(pathParams, queryParams);
+            if(logger.isDebugEnabled()){
+                logger.debug("get using url=" + completeURL);
+            }
+            Request request = buildRequest(Method.GET, completeURL);
+            Document document = executeRequest(request, completeURL, Status.SUCCESS_OK);
+            RepresentationWrapper wrapDoc = new RepresentationWrapper(document);
+            repHandler.handle(Action.GET, wrapDoc);
+        }catch(Exception e){
+            if(logger.isDebugEnabled()){
+                logger.debug("Caught exception ", e);
+            }
+            throw new DocumentException(e);
+        }finally{
+        }
+    }
+
+    @Override
+    public void getAll(String serviceName, DocumentHandler handler) throws DocumentNotFoundException, DocumentException {
+        if(serviceName == null){
+            throw new IllegalArgumentException("RepositoryRESTClient.getAll: serviceName is missing");
+        }
+        if(handler == null){
+            throw new IllegalArgumentException("RepositoryRESTClient.getAll: handler is missing");
+        }
+        ServiceMain smain = ServiceMain.getInstance();
+        String nuxeoWspaceId = smain.getWorkspaceId(serviceName);
+        if(nuxeoWspaceId == null){
+            throw new DocumentNotFoundException("Unable to find workspace for service " + serviceName +
+                    " check if the mapping exists in service-config.xml or " +
+                    " the the mapped workspace exists in the Nuxeo repository");
+        }
+        try{
+            RepresentationHandler repHandler = (RepresentationHandler) handler;
+            repHandler.prepare(Action.GET_ALL);
+            ArrayList pathParams = new ArrayList();
+            pathParams.add("default");
+            pathParams.add(nuxeoWspaceId);
+            pathParams.add("browse");
+            if(repHandler.getPathParams().size() > 0){
+                pathParams.addAll(repHandler.getPathParams());
+            }
+            String completeURL = getNuxeoRestClient().buildUrl(pathParams, repHandler.getQueryParams());
+            if(logger.isDebugEnabled()){
+                logger.debug("getAll using url=" + completeURL);
+            }
+            Request request = buildRequest(Method.GET, completeURL);
+            Document document = executeRequest(request, completeURL, Status.SUCCESS_OK);
+            RepresentationWrapper wrapDoc = new RepresentationWrapper(document);
+            repHandler.handle(Action.GET_ALL, wrapDoc);
+        }catch(Exception e){
+            if(logger.isDebugEnabled()){
+                logger.debug("Caught exception ", e);
+            }
+            throw new DocumentException(e);
+        }finally{
+        }
+    }
+
+    @Override
+    public void update(String id, DocumentHandler handler) throws BadRequestException, DocumentNotFoundException, DocumentException {
+        if(handler == null){
+            throw new IllegalArgumentException("RepositoryRESTClient.update: handler is missing");
+        }
+
+        try{
+            RepresentationHandler repHandler = (RepresentationHandler) handler;
+            repHandler.prepare(Action.UPDATE);
+            List<String> pathParams = new ArrayList<String>();
+            pathParams.add("default");
+            pathParams.add(id);
+            pathParams.add("updateDocumentRestlet");
+            if(repHandler.getPathParams().size() > 0){
+                pathParams.addAll(repHandler.getPathParams());
+            }
+            String completeURL = getNuxeoRestClient().buildUrl(pathParams, repHandler.getQueryParams());
+            if(logger.isDebugEnabled()){
+                logger.debug("update using url=" + completeURL);
+            }
+            //repHandler.handle is not needed as queryParams contain all the data
+            RepresentationWrapper wrapDoc = new RepresentationWrapper(new DefaultDocument());
+            repHandler.handle(Action.UPDATE, wrapDoc);
+            Request request = buildRequest(Method.PUT, completeURL);
+            Document document = executeRequest(request, completeURL, Status.SUCCESS_OK);
+
+        }catch(Exception e){
+            if(logger.isDebugEnabled()){
+                logger.debug("Caught exception ", e);
+            }
+            throw new DocumentException(e);
+        }finally{
+        }
+    }
+
+    @Override
+    public void delete(String id) throws DocumentNotFoundException, DocumentException {
+
+        if(logger.isDebugEnabled()){
+            logger.debug("deleting document with id=" + id);
+        }
+
+        try{
+            List<String> pathParams = new ArrayList<String>();
+            pathParams.add("default");
+            pathParams.add(id);
+            pathParams.add("deleteDocumentRestlet");
+
+            Map<String, String> queryParams = new HashMap<String, String>();
+            String completeURL = getNuxeoRestClient().buildUrl(pathParams, queryParams);
+            if(logger.isDebugEnabled()){
+                logger.debug("delete using url=" + completeURL);
+            }
+            Request request = buildRequest(Method.DELETE, completeURL);
+            Document document = executeRequest(request, completeURL, Status.SUCCESS_OK);
+            //FIXME error handling?
+            //            Document document = service.deleteCollectionObject(csid);
+//            Element root = document.getRootElement();
+//            for(Iterator i = root.elementIterator(); i.hasNext();){
+//                Element element = (Element) i.next();
+//                if("docRef".equals(element.getName())){
+//                    String status = (String) element.getData();
+//                    verbose("deleteCollectionObjectt response: " + status);
+//                }
+//            }
+
+        }catch(Exception e){
+            if(logger.isDebugEnabled()){
+                logger.debug("Caught exception ", e);
+            }
+            throw new DocumentException(e);
+        }finally{
+        }
+    }
+
+    /**
+     * buildRequest build HTTP request given parameters
+     * @param method
+     * @param completeURL
+     * @return
+     */
+    private Request buildRequest(Method method, String completeURL) {
+        Request request = new Request(method, completeURL);
+        getNuxeoRestClient().setupAuth(request);
+        getNuxeoRestClient().setupCookies(request);
+        return request;
+    }
+
+    /**
+     * executeRequest execute given HTTP request
+     * @param request
+     * @param completeURL
+     * @return
+     * @throws Exception
+     */
+    private Document executeRequest(Request request, String completeURL, Status expected) throws Exception {
+        //execute
+        Response res = getNuxeoRestClient().getRestClient().handle(request);
+        Status status = res.getStatus();
+        if(status.getCode() != expected.getCode()){
+            logger.error("failed to execute request=" + request.getMethod() +
+                    " with error status=" + status +
+                    " url=" + completeURL +
+                    " response=" + res.toString());
+            throw new DocumentException(status.getCode(), status.getDescription());
+        }
+        Representation rep = res.getEntity();
+
+        //read response
+        return retrieveResponse(rep);
+    }
+
+    /**
+     * retrieveResponse retrieves DOM document from Restlet Represeantion
+     * @param request
+     * @return
+     * @throws Exception
+     */
+    private Document retrieveResponse(Representation rep) throws Exception {
+        SAXReader reader = new SAXReader();
+        Document document = reader.read(rep.getStream());
+        return document;
+    }
+
+    /**
+     * extractId extract document id from response
+     * @param document
+     * @return
+     */
+    private String extractId(Document document) {
+        String csid = null;
+        Element root = document.getRootElement();
+        for(Iterator i = root.elementIterator(); i.hasNext();){
+            Element element = (Element) i.next();
+            if("docRef".equals(element.getName())){
+                csid = (String) element.getData();
+                break;
+            }
+        }
+        return csid;
+    }
+
+    private NuxeoRESTClient getNuxeoRestClient() {
+        if(nuxeoRestClient == null){
+            ServiceConfig sconfig = ServiceMain.getInstance().getServiceConfig();
+            NuxeoClientConfig nxConfig = sconfig.getNuxeoClientConfig();
+            String protocol = "http";
+            if(nxConfig.getProtocol() != null && !"".equals(nxConfig.getProtocol())){
+                protocol = nxConfig.getProtocol();
+            }
+            NuxeoRESTClient tempClient = new NuxeoRESTClient(protocol,
+                    nxConfig.getHost(), "" + nxConfig.getPort());
+
+            tempClient.setBasicAuthentication(nxConfig.getUser(), nxConfig.getPassword());
+
+            nuxeoRestClient = tempClient;
+
+        }
+        return nuxeoRestClient;
+    }
+}
diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/rest/RepresentationHandler.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/rest/RepresentationHandler.java
new file mode 100644 (file)
index 0000000..91828ea
--- /dev/null
@@ -0,0 +1,161 @@
+/**
+ *  This document is a part of the source code and related artifacts
+ *  for CollectionSpace, an open source collections management system
+ *  for museums and related institutions:
+
+ *  http://www.collectionspace.org
+ *  http://wiki.collectionspace.org
+
+ *  Copyright 2009 University of California at Berkeley
+
+ *  Licensed under the Educational Community License (ECL), Version 2.0.
+ *  You may not use this file except in compliance with this License.
+
+ *  You may obtain a copy of the ECL 2.0 License at
+
+ *  https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.collectionspace.services.nuxeo.client.rest;
+
+import org.collectionspace.services.common.repository.DocumentHandler;
+import org.collectionspace.services.common.repository.DocumentWrapper;
+import org.collectionspace.services.common.repository.DocumentException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.collectionspace.services.nuxeo.client.*;
+import org.dom4j.Document;
+
+/**
+ * RepresentationHandler is a base abstract Nuxeo document handler
+ * using Nuxeo RESTful APIs for CollectionSpace services
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ */
+public abstract class RepresentationHandler<T, TL>
+        implements DocumentHandler<T, TL> {
+
+    private Map<String, Object> properties = new HashMap<String, Object>();
+    private List<String> pathParams = new ArrayList<String>();
+    private Map<String, String> queryParams = new HashMap<String, String>();
+    private Document document;
+    private InputStream inputStream = null;
+
+    @Override
+    public abstract void prepare(Action action) throws Exception;
+
+    @Override
+    public abstract void handle(Action action, DocumentWrapper wrapDoc) throws Exception;
+
+    @Override
+    public abstract T extractCommonObject(DocumentWrapper wrapDoc) throws Exception;
+
+    @Override
+    public abstract void fillCommonObject(T obj, DocumentWrapper wrapDoc) throws Exception;
+
+    @Override
+    public abstract TL extractCommonObjectList(DocumentWrapper wrapDoc) throws Exception;
+
+    @Override
+    public abstract void fillCommonObjectList(TL obj, DocumentWrapper wrapDoc) throws Exception;
+
+    @Override
+    public abstract T getCommonObject();
+
+    @Override
+    public abstract void setCommonObject(T obj);
+
+    @Override
+    public abstract TL getCommonObjectList();
+
+    @Override
+    public abstract void setCommonObjectList(TL obj);
+
+    @Override
+    public Document getDocument(DocumentWrapper wrapDoc) throws DocumentException {
+        throw new UnsupportedOperationException("DocumentHandler.getDocument(wrapDoc)");
+    }
+
+    /**
+     * @return the pathParams
+     */
+    public List<String> getPathParams() {
+        return pathParams;
+    }
+
+    /**
+     * @param pathParams the pathParams to set
+     */
+    public void setPathParams(List<String> pathParams) {
+        this.pathParams = pathParams;
+    }
+
+    /**
+     * @return the queryParams
+     */
+    public Map<String, String> getQueryParams() {
+        return queryParams;
+    }
+
+    /**
+     * @param queryParams the queryParams to set
+     */
+    public void setQueryParams(Map<String, String> queryParams) {
+        this.queryParams = queryParams;
+    }
+
+    /**
+     * getInputStream to retrieve input stream by client for posting a document
+     * @return the inputStream
+     */
+    public InputStream getInputStream() {
+        return inputStream;
+    }
+
+    /**
+     * setInputStream to set input stream to read for posting document
+     * @param inputStream the inputStream to set
+     */
+    public void setInputStream(InputStream inputStream) {
+        this.inputStream = inputStream;
+    }
+
+    /**
+     * @return the document
+     */
+    public Document getDocument() {
+        return document;
+    }
+
+    /**
+     * @param document the document to set
+     */
+    public void setDocument(Document document) {
+        this.document = document;
+    }
+
+    /**
+     * @return the properties
+     */
+    @Override
+    public Map<String, Object> getProperties() {
+        return properties;
+    }
+
+    /**
+     * @param properties the properties to set
+     */
+    @Override
+    public void setProperties(Map<String, Object> properties) {
+        this.properties = properties;
+    }
+}
diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/rest/RepresentationWrapper.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/rest/RepresentationWrapper.java
new file mode 100644 (file)
index 0000000..60227dc
--- /dev/null
@@ -0,0 +1,47 @@
+/**
+ *  This document is a part of the source code and related artifacts
+ *  for CollectionSpace, an open source collections management system
+ *  for museums and related institutions:
+
+ *  http://www.collectionspace.org
+ *  http://wiki.collectionspace.org
+
+ *  Copyright 2009 University of California at Berkeley
+
+ *  Licensed under the Educational Community License (ECL), Version 2.0.
+ *  You may not use this file except in compliance with this License.
+
+ *  You may obtain a copy of the ECL 2.0 License at
+
+ *  https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.collectionspace.services.nuxeo.client.rest;
+
+import org.collectionspace.services.common.repository.DocumentWrapper;
+import org.dom4j.Document;
+
+/**
+ * RepresentationWrapper wraps RESTful representation (Restlet)
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ */
+public class RepresentationWrapper implements DocumentWrapper {
+
+    private Document document;
+
+    public RepresentationWrapper(Document doc) {
+        document = doc;
+    }
+
+    @Override
+    public Object getWrappedObject() {
+        return document;
+    }
+}
similarity index 59%
rename from services/common/src/main/java/org/collectionspace/services/nuxeo/NuxeoUtils.java
rename to services/common/src/main/java/org/collectionspace/services/nuxeo/util/NuxeoUtils.java
index 059f2656c8804666e23faecf8029c515aa1fa65d..cc4cf47331301f44a56fc0fcaefa6728c2ffe6e1 100644 (file)
@@ -1,12 +1,26 @@
 /**
- * Copyright 2009 University of California at Berkeley
+ *  This document is a part of the source code and related artifacts
+ *  for CollectionSpace, an open source collections management system
+ *  for museums and related institutions:
+
+ *  http://www.collectionspace.org
+ *  http://wiki.collectionspace.org
+
+ *  Copyright 2009 University of California at Berkeley
+
+ *  Licensed under the Educational Community License (ECL), Version 2.0.
+ *  You may not use this file except in compliance with this License.
+
+ *  You may obtain a copy of the ECL 2.0 License at
+
+ *  https://source.collectionspace.org/collection-space/LICENSE.txt
  */
-package org.collectionspace.services.nuxeo;
+package org.collectionspace.services.nuxeo.util;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import javax.ws.rs.WebApplicationException;
+import org.collectionspace.services.common.repository.DocumentException;
 import org.dom4j.Document;
 import org.dom4j.io.SAXReader;
 import org.nuxeo.ecm.core.api.DocumentModel;
@@ -22,14 +36,20 @@ import org.slf4j.LoggerFactory;
 
 /**
  * Various utilities related to Nuxeo 
- * @author 
  */
 public class NuxeoUtils {
 
     private static Logger logger = LoggerFactory.getLogger(NuxeoUtils.class);
 
-    public static Document getDocument(RepositoryInstance repoSession, DocumentModel helloDoc)
-            throws Exception {
+    /**
+     * getDocument retrieve org.dom4j.Document from Nuxeo DocumentModel
+     * @param repoSession
+     * @param nuxeoDoc
+     * @return
+     * @throws DocumentException
+     */
+    public static Document getDocument(RepositoryInstance repoSession, DocumentModel nuxeoDoc)
+            throws DocumentException {
         Document doc = null;
         DocumentWriter writer = null;
         DocumentReader reader = null;
@@ -38,7 +58,7 @@ public class NuxeoUtils {
         try{
             baos = new ByteArrayOutputStream();
             //nuxeo io.impl begin
-            reader = new SingleDocumentReader(repoSession, helloDoc);
+            reader = new SingleDocumentReader(repoSession, nuxeoDoc);
             writer = new XMLDocumentWriter(baos);
             DocumentPipe pipe = new DocumentPipeImpl();
             //nuxeo io.impl end
@@ -48,6 +68,11 @@ public class NuxeoUtils {
             bais = new ByteArrayInputStream(baos.toByteArray());
             SAXReader saxReader = new SAXReader();
             doc = saxReader.read(bais);
+        }catch(Exception e){
+            if(logger.isDebugEnabled()){
+                logger.debug("Caught exception while processing document ", e);
+            }
+            throw new DocumentException(e);
         }finally{
             if(reader != null){
                 reader.close();
@@ -63,8 +88,9 @@ public class NuxeoUtils {
                     baos.close();
                 }
             }catch(IOException ioe){
-                logger.error("Failed to close io streams with {}", ioe);
-                throw new WebApplicationException();
+                String msg = "Failed to close io streams";
+                logger.error(msg + " {}", ioe);
+                throw new DocumentException(ioe);
             }
         }
         return doc;
index 0dd79cfaadb6798446f813a1df67064a03aa65ff..78e85ba0ffe1905c938d387a9e9515728ccd48df 100644 (file)
                         <xs:sequence>
                             <xs:element name="host" type="xs:string" minOccurs="1"  maxOccurs="1" />
                             <xs:element name="port" type="xs:int" minOccurs="1"  maxOccurs="1" />
+                            <!-- protocol (http/https) is only applicable for rest client -->
+                            <xs:element name="protocol" type="xs:string" minOccurs="0"  maxOccurs="1" />
+                                           <!-- default client is java -->
+                            <xs:element name="client-type" type="NuxeoClientType" minOccurs="0"  maxOccurs="1" />
+
                             <xs:element name="user" type="xs:string" minOccurs="1"  maxOccurs="1" />
                 <!-- password should not be in cleartext -->
                             <xs:element name="password" type="xs:string" minOccurs="1"  maxOccurs="1" />
+             
                         </xs:sequence>
                     </xs:complexType>
                 </xs:element>
                                 <xs:complexType>
                                     <xs:sequence>
                                         <xs:element name="service-name" type="xs:string" minOccurs="1"  maxOccurs="1" />
+                                        <!-- workspace name is required for Nuxeo Java client -->
                                         <xs:element name="workspace-name" type="xs:string" minOccurs="1"  maxOccurs="1" />
+                                        <!-- workspace ids are required only for Nuxeo REST client -->
+                                        <xs:element name="workspace-id" type="xs:string" minOccurs="1"  maxOccurs="1" />
                                     </xs:sequence>
                                 </xs:complexType>
                             </xs:element>
         </xs:complexType>
     </xs:element>
 
+    <!-- enumeration defining the type nuxeo client -->
+    <xs:simpleType name="NuxeoClientType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="java" />
+            <xs:enumeration value="rest" />
+        </xs:restriction>
+    </xs:simpleType>
+
 
 </xs:schema>
 
index 4bc1f43c3afe905f0e42f0c9876efdf3393e562f..d882fb66b0e11214ccf08912b48b2815a6e7698c 100644 (file)
@@ -11,7 +11,7 @@ import java.util.HashMap;
 import java.util.List;\r
 import java.util.Map;\r
 \r
-import org.collectionspace.services.nuxeo.NuxeoRESTClient;\r
+import org.collectionspace.services.nuxeo.client.rest.NuxeoRESTClient;\r
 import org.collectionspace.services.nuxeo.CollectionSpaceServiceNuxeoImpl;\r
 import org.collectionspace.services.intake.Intake;\r
 import org.collectionspace.services.IntakeJAXBSchema;\r