]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-81,43,371,394,395
authorSanjay Dalal <sanjay.dalal@berkeley.edu>
Wed, 23 Sep 2009 18:03:36 +0000 (18:03 +0000)
committerSanjay Dalal <sanjay.dalal@berkeley.edu>
Wed, 23 Sep 2009 18:03:36 +0000 (18:03 +0000)
CSPACE-81,394 schema extension supported between consumer and service using multipart messaging, between service and repository using nuxeo repository. metadata-driven using service binding. collectionobject schema extended for testing for natural history domain
CSPACE-43 use of JAXB is minimized to consumer side and restricted to just common part on the service side
CSPACE-371 nuxeo binding is externalized into tenant binding.
CSPACE-395 multi tenancy first cut. example binding for movingimages.us.

M    services/authentication/client/src/test/java/org/collectionspace/services/authentication/client/AuthenticationServiceTest.java
M    services/sdk/sample/src/main/java/org/collectionspace/services/sdk/sample/Sample.java
D    services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/CollectionObjectService.java
M    services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/CollectionObjectResource.java
M    services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/nuxeo/CollectionObjectRepresenationHandler.java
M    services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/nuxeo/CollectionObjectDocumentModelHandler.java
D    services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/nuxeo/CollectionObjectServiceNuxeoImpl.java
M    services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/nuxeo/CollectionObjectHandlerFactory.java
M    services/collectionobject/service/pom.xml
D    services/collectionobject/jaxb/src/main/resources/collectionobject.xsd
A  + services/collectionobject/jaxb/src/main/resources/collectionobjects-common.xsd
A    services/collectionobject/jaxb/src/main/resources/collectionobjects-naturalhistory.xsd
M    services/collectionobject/jaxb/pom.xml
D    services/collectionobject/3rdparty/nuxeo-platform-cs-collectionobject/src/main/resources/schemas/collectionobject.xsd
A  + services/collectionobject/3rdparty/nuxeo-platform-cs-collectionobject/src/main/resources/schemas/collectionobjects-common.xsd
A    services/collectionobject/3rdparty/nuxeo-platform-cs-collectionobject/src/main/resources/schemas/collectionobjects-naturalhistory.xsd
M    services/collectionobject/3rdparty/nuxeo-platform-cs-collectionobject/src/main/resources/OSGI-INF/core-types-contrib.xml
A    services/collectionobject/3rdparty/pom.xml~
A    services/collectionobject/client/received.xml~
A    services/collectionobject/client/received.xml
A    services/collectionobject/client/sent.xml~
M    services/collectionobject/client/src/test/java/org/collectionspace/services/client/test/CollectionObjectServiceTest.java
M    services/collectionobject/client/src/main/java/org/collectionspace/services/client/CollectionObjectClient.java
M    services/collectionobject/client/src/main/java/org/collectionspace/services/client/CollectionObjectProxy.java
A    services/collectionobject/client/sent.xml
M    services/collectionobject/client/pom.xml
A    services/collectionobject/client/test.xml
M    services/JaxRsServiceProvider/src/main/java/org/collectionspace/services/jaxrs/CollectionSpaceJaxRsApplication.java
M    services/JaxRsServiceProvider/src/main/webapp/WEB-INF/web.xml
M    services/JaxRsServiceProvider/pom.xml
A    services/common/profiles.xml
A    services/common/src/main/java/org/collectionspace/services/common/repository/DocumentUtils.java
A    services/common/src/main/java/org/collectionspace/services/common/repository/AbstractDocumentHandler.java
M    services/common/src/main/java/org/collectionspace/services/common/repository/RepositoryClientFactory.java
M    services/common/src/main/java/org/collectionspace/services/common/repository/DocumentHandler.java
M    services/common/src/main/java/org/collectionspace/services/common/repository/DocumentException.java
M    services/common/src/main/java/org/collectionspace/services/common/repository/RepositoryClient.java
M    services/common/src/main/java/org/collectionspace/services/common/CollectionSpaceResource.java
A  + services/common/src/main/java/org/collectionspace/services/common/CollectionSpaceServiceContextListener.java
A  + services/common/src/main/java/org/collectionspace/services/common/AbstractCollectionSpaceResource.java
A    services/common/src/main/java/org/collectionspace/services/common/context
A    services/common/src/main/java/org/collectionspace/services/common/context/ServiceContext.java
A    services/common/src/main/java/org/collectionspace/services/common/context/ServiceContextImpl.java
M    services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java
A    services/common/src/main/java/org/collectionspace/services/common/config
A    services/common/src/main/java/org/collectionspace/services/common/config/ConfigReader.java
A    services/common/src/main/java/org/collectionspace/services/common/config/AbstractConfigReader.java
A    services/common/src/main/java/org/collectionspace/services/common/config/ServicesConfigReader.java
A    services/common/src/main/java/org/collectionspace/services/common/config/TenantBindingConfigReader.java
D    services/common/src/main/java/org/collectionspace/services/common/ServiceContextListener.java
M    services/common/src/main/java/org/collectionspace/services/common/CollectionSpaceHandlerFactory.java
A    services/common/src/main/java/org/collectionspace/services/svn-commit.tmp~
M    services/common/src/main/java/org/collectionspace/services/nuxeo/util/NuxeoUtils.java
M    services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryJavaClient.java
M    services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoConnector.java
M    services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/DocumentModelHandler.java
M    services/common/src/main/java/org/collectionspace/services/nuxeo/client/rest/RepresentationHandler.java
M    services/common/src/main/java/org/collectionspace/services/nuxeo/client/rest/RepositoryRESTClient.java
M    services/common/src/main/config/service-config.xml
A    services/common/src/main/config/tenant-bindings.xml
A    services/common/src/main/svn-commit.tmp~
M    services/common/src/main/resources/service-config.xsd
A    services/common/src/main/resources/types.xsd
A    services/common/src/main/resources/tenant.xsd
A    services/common/src/main/resources/service.xsd
M    services/common/pom.xml
M    services/common/build.xml
_M   services/acquisition/service
M    services/acquisition/service/src/main/java/org/collectionspace/services/acquisition/AcquisitionResource.java
D    services/acquisition/service/src/main/java/org/collectionspace/services/acquisition/AcquisitionService.java
M    services/acquisition/service/src/main/java/org/collectionspace/services/acquisition/nuxeo/AcquisitionDocumentModelHandler.java
M    services/acquisition/service/src/main/java/org/collectionspace/services/acquisition/nuxeo/AcquisitionHandlerFactory.java
_M   services/acquisition/jaxb
D    services/acquisition/jaxb/src/main/resources/acquisition.xsd
A  + services/acquisition/jaxb/src/main/resources/acquisitions-common.xsd
_M   services/acquisition/3rdparty/nuxeo-platform-cs-acquisition
D    services/acquisition/3rdparty/nuxeo-platform-cs-acquisition/src/main/resources/schemas/acquisition.xsd
A  + services/acquisition/3rdparty/nuxeo-platform-cs-acquisition/src/main/resources/schemas/acquisitions-common.xsd
M    services/acquisition/3rdparty/nuxeo-platform-cs-acquisition/src/main/resources/OSGI-INF/core-types-contrib.xml
_M   services/acquisition/client
M    services/acquisition/client/src/test/java/org/collectionspace/services/client/test/AcquisitionServiceTest.java
M    services/acquisition/client/src/main/java/org/collectionspace/services/client/AcquisitionClient.java
M    services/acquisition/client/src/main/java/org/collectionspace/services/client/AcquisitionProxy.java
M    services/pom.xml
M    services/id/service/pom.xml
M    services/id/jaxb/pom.xml
_M   services/query/service
_M   services/IntegrationTests
A    services/intake/service/profiles.xml
M    services/intake/service/src/main/java/org/collectionspace/services/intake/IntakeResource.java
D    services/intake/service/src/main/java/org/collectionspace/services/intake/IntakeService.java
D    services/intake/service/src/main/java/org/collectionspace/services/intake/IntakeServiceNuxeoImpl.java
M    services/intake/service/src/main/java/org/collectionspace/services/intake/nuxeo/IntakeHandlerFactory.java
M    services/intake/service/src/main/java/org/collectionspace/services/intake/nuxeo/IntakeRepresenationHandler.java
M    services/intake/service/src/main/java/org/collectionspace/services/intake/nuxeo/IntakeDocumentModelHandler.java
A  + services/intake/jaxb/src/main/resources/intakes-common.xsd
D    services/intake/jaxb/src/main/resources/intake.xsd
M    services/intake/jaxb/pom.xml
A  + services/intake/3rdparty/nuxeo-platform-cs-intake/src/main/resources/schemas/intakes-common.xsd
D    services/intake/3rdparty/nuxeo-platform-cs-intake/src/main/resources/schemas/intake.xsd
M    services/intake/3rdparty/nuxeo-platform-cs-intake/src/main/resources/OSGI-INF/core-types-contrib.xml
M    services/intake/client/src/test/java/org/collectionspace/services/client/test/IntakeServiceTest.java
M    services/intake/client/src/main/java/org/collectionspace/services/client/IntakeClient.java
M    services/intake/client/src/main/java/org/collectionspace/services/client/IntakeProxy.java
M    services/relation/service/src/main/java/org/collectionspace/services/relation/NewRelationResource.java
M    services/client/src/main/java/org/collectionspace/services/client/test/ServiceTest.java
M    services/client/src/main/java/org/collectionspace/services/client/test/AbstractServiceTest.java

92 files changed:
services/JaxRsServiceProvider/pom.xml
services/JaxRsServiceProvider/src/main/java/org/collectionspace/services/jaxrs/CollectionSpaceJaxRsApplication.java
services/JaxRsServiceProvider/src/main/webapp/WEB-INF/web.xml
services/acquisition/3rdparty/nuxeo-platform-cs-acquisition/src/main/resources/OSGI-INF/core-types-contrib.xml
services/acquisition/3rdparty/nuxeo-platform-cs-acquisition/src/main/resources/schemas/acquisitions-common.xsd [moved from services/acquisition/3rdparty/nuxeo-platform-cs-acquisition/src/main/resources/schemas/acquisition.xsd with 100% similarity]
services/acquisition/client/src/main/java/org/collectionspace/services/client/AcquisitionClient.java
services/acquisition/client/src/main/java/org/collectionspace/services/client/AcquisitionProxy.java
services/acquisition/client/src/test/java/org/collectionspace/services/client/test/AcquisitionServiceTest.java
services/acquisition/jaxb/src/main/resources/acquisitions-common.xsd [moved from services/acquisition/jaxb/src/main/resources/acquisition.xsd with 85% similarity]
services/acquisition/service/src/main/java/org/collectionspace/services/acquisition/AcquisitionResource.java
services/acquisition/service/src/main/java/org/collectionspace/services/acquisition/AcquisitionService.java [deleted file]
services/acquisition/service/src/main/java/org/collectionspace/services/acquisition/nuxeo/AcquisitionDocumentModelHandler.java
services/acquisition/service/src/main/java/org/collectionspace/services/acquisition/nuxeo/AcquisitionHandlerFactory.java
services/authentication/client/src/test/java/org/collectionspace/services/authentication/client/AuthenticationServiceTest.java
services/client/src/main/java/org/collectionspace/services/client/test/AbstractServiceTest.java
services/client/src/main/java/org/collectionspace/services/client/test/ServiceTest.java
services/collectionobject/3rdparty/nuxeo-platform-cs-collectionobject/src/main/resources/OSGI-INF/core-types-contrib.xml
services/collectionobject/3rdparty/nuxeo-platform-cs-collectionobject/src/main/resources/schemas/collectionobjects-common.xsd [moved from services/collectionobject/3rdparty/nuxeo-platform-cs-collectionobject/src/main/resources/schemas/collectionobject.xsd with 100% similarity]
services/collectionobject/3rdparty/nuxeo-platform-cs-collectionobject/src/main/resources/schemas/collectionobjects-naturalhistory.xsd [new file with mode: 0644]
services/collectionobject/3rdparty/pom.xml~ [new file with mode: 0644]
services/collectionobject/client/pom.xml
services/collectionobject/client/received.xml [new file with mode: 0644]
services/collectionobject/client/received.xml~ [new file with mode: 0644]
services/collectionobject/client/sent.xml [new file with mode: 0644]
services/collectionobject/client/sent.xml~ [new file with mode: 0644]
services/collectionobject/client/src/main/java/org/collectionspace/services/client/CollectionObjectClient.java
services/collectionobject/client/src/main/java/org/collectionspace/services/client/CollectionObjectProxy.java
services/collectionobject/client/src/test/java/org/collectionspace/services/client/test/CollectionObjectServiceTest.java
services/collectionobject/client/test.xml [new file with mode: 0644]
services/collectionobject/jaxb/pom.xml
services/collectionobject/jaxb/src/main/resources/collectionobjects-common.xsd [moved from services/collectionobject/jaxb/src/main/resources/collectionobject.xsd with 57% similarity]
services/collectionobject/jaxb/src/main/resources/collectionobjects-naturalhistory.xsd [new file with mode: 0644]
services/collectionobject/service/pom.xml
services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/CollectionObjectResource.java
services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/CollectionObjectService.java [deleted file]
services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/nuxeo/CollectionObjectDocumentModelHandler.java
services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/nuxeo/CollectionObjectHandlerFactory.java
services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/nuxeo/CollectionObjectRepresenationHandler.java
services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/nuxeo/CollectionObjectServiceNuxeoImpl.java [deleted file]
services/common/build.xml
services/common/pom.xml
services/common/profiles.xml [new file with mode: 0644]
services/common/src/main/config/service-config.xml
services/common/src/main/config/tenant-bindings.xml [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/common/AbstractCollectionSpaceResource.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/common/CollectionSpaceHandlerFactory.java
services/common/src/main/java/org/collectionspace/services/common/CollectionSpaceResource.java
services/common/src/main/java/org/collectionspace/services/common/CollectionSpaceServiceContextListener.java [moved from services/common/src/main/java/org/collectionspace/services/common/ServiceContextListener.java with 58% similarity]
services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java
services/common/src/main/java/org/collectionspace/services/common/config/AbstractConfigReader.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/common/config/ConfigReader.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/common/config/ServicesConfigReader.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/common/config/TenantBindingConfigReader.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/common/context/ServiceContext.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/common/context/ServiceContextImpl.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/common/repository/AbstractDocumentHandler.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/common/repository/DocumentException.java
services/common/src/main/java/org/collectionspace/services/common/repository/DocumentHandler.java
services/common/src/main/java/org/collectionspace/services/common/repository/DocumentUtils.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/common/repository/RepositoryClient.java
services/common/src/main/java/org/collectionspace/services/common/repository/RepositoryClientFactory.java
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/DocumentModelHandler.java
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoConnector.java
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryJavaClient.java
services/common/src/main/java/org/collectionspace/services/nuxeo/client/rest/RepositoryRESTClient.java
services/common/src/main/java/org/collectionspace/services/nuxeo/client/rest/RepresentationHandler.java
services/common/src/main/java/org/collectionspace/services/nuxeo/util/NuxeoUtils.java
services/common/src/main/java/org/collectionspace/services/svn-commit.tmp~ [new file with mode: 0644]
services/common/src/main/resources/service-config.xsd
services/common/src/main/resources/service.xsd [new file with mode: 0644]
services/common/src/main/resources/tenant.xsd [new file with mode: 0644]
services/common/src/main/resources/types.xsd [new file with mode: 0644]
services/common/src/main/svn-commit.tmp~ [new file with mode: 0644]
services/id/jaxb/pom.xml
services/id/service/pom.xml
services/intake/3rdparty/nuxeo-platform-cs-intake/src/main/resources/OSGI-INF/core-types-contrib.xml
services/intake/3rdparty/nuxeo-platform-cs-intake/src/main/resources/schemas/intakes-common.xsd [moved from services/intake/3rdparty/nuxeo-platform-cs-intake/src/main/resources/schemas/intake.xsd with 100% similarity]
services/intake/client/src/main/java/org/collectionspace/services/client/IntakeClient.java
services/intake/client/src/main/java/org/collectionspace/services/client/IntakeProxy.java
services/intake/client/src/test/java/org/collectionspace/services/client/test/IntakeServiceTest.java
services/intake/jaxb/pom.xml
services/intake/jaxb/src/main/resources/intakes-common.xsd [moved from services/intake/jaxb/src/main/resources/intake.xsd with 95% similarity]
services/intake/service/profiles.xml [new file with mode: 0644]
services/intake/service/src/main/java/org/collectionspace/services/intake/IntakeResource.java
services/intake/service/src/main/java/org/collectionspace/services/intake/IntakeService.java [deleted file]
services/intake/service/src/main/java/org/collectionspace/services/intake/IntakeServiceNuxeoImpl.java [deleted file]
services/intake/service/src/main/java/org/collectionspace/services/intake/nuxeo/IntakeDocumentModelHandler.java
services/intake/service/src/main/java/org/collectionspace/services/intake/nuxeo/IntakeHandlerFactory.java
services/intake/service/src/main/java/org/collectionspace/services/intake/nuxeo/IntakeRepresenationHandler.java
services/pom.xml
services/relation/service/src/main/java/org/collectionspace/services/relation/NewRelationResource.java
services/sdk/sample/src/main/java/org/collectionspace/services/sdk/sample/Sample.java

index c86a2584d7fe3db9845cf827ba39732a02fde3dc..a5137dd1847364b73266549e476d31d796bdf466 100644 (file)
@@ -42,7 +42,7 @@
             <artifactId>org.collectionspace.services.acquisition.service</artifactId>\r
             <version>1.0</version>\r
         </dependency>\r
-        <dependency>\r
+        <!--dependency>\r
             <groupId>org.collectionspace.services</groupId>\r
             <artifactId>org.collectionspace.services.relation.service</artifactId>\r
             <version>1.0</version>\r
@@ -51,7 +51,7 @@
             <groupId>org.collectionspace.services</groupId>\r
             <artifactId>org.collectionspace.services.query.service</artifactId>\r
             <version>1.0</version>\r
-        </dependency>\r
+        </dependency-->\r
         <dependency>\r
             <groupId>commons-io</groupId>\r
             <artifactId>commons-io</artifactId>\r
         <dependency>\r
             <groupId>org.jboss.resteasy</groupId>\r
             <artifactId>resteasy-jaxb-provider</artifactId>\r
-            <version>1.0.2.GA</version>\r
+            <version>1.1.GA</version>\r
         </dependency>\r
         <dependency>\r
             <groupId>org.jboss.resteasy</groupId>\r
             <artifactId>resteasy-multipart-provider</artifactId>\r
-            <version>1.0.2.GA</version>\r
+            <version>1.1.GA</version>\r
         </dependency>\r
         <dependency>\r
             <groupId>junit</groupId>\r
index 7f77d8e3ff4e41f611fa61d887f290329a10ad3f..ad54486436ea80ab92bb72308f7b7699ce3726a1 100644 (file)
@@ -3,10 +3,10 @@ package org.collectionspace.services.jaxrs;
 import org.collectionspace.services.collectionobject.CollectionObjectResource;
 import org.collectionspace.services.id.IDResource;
 import org.collectionspace.services.intake.IntakeResource;
-//import org.collectionspace.services.relation.RelationResource;
-import org.collectionspace.services.relation.NewRelationResource;
+////import org.collectionspace.services.relation.RelationResource;
+//import org.collectionspace.services.relation.NewRelationResource;
 import org.collectionspace.services.acquisition.AcquisitionResource;
-import org.collectionspace.services.query.QueryResource;
+//import org.collectionspace.services.query.QueryResource;
 
 import javax.ws.rs.core.Application;
 import java.util.HashSet;
@@ -24,8 +24,8 @@ public class CollectionSpaceJaxRsApplication extends Application {
         singletons.add(new IntakeResource());
         singletons.add(new AcquisitionResource());
 //        singletons.add(new RelationResource());
-        singletons.add(new NewRelationResource());
-        singletons.add(new QueryResource());
+        //singletons.add(new NewRelationResource());
+//        singletons.add(new QueryResource());
 //        singletons.add(new DomainIdentifierResource());
 //        singletons.add(new PingResource());
     }
index 812508a236fd17535bdeb4d34707801147baec49..6d52948b73677c25a88411811d7f713450ecc0f9 100644 (file)
@@ -30,7 +30,7 @@
 
     <listener>
         <listener-class>
-            org.collectionspace.services.common.ServiceContextListener
+            org.collectionspace.services.common.CollectionSpaceServiceContextListener
         </listener-class>
     </listener>
 
index 3554f7d58fd3d251aabf802e5f221b6c797fd7b9..4a8a87cc78c9754678fab0e393fd26ca840751b7 100644 (file)
@@ -1,13 +1,13 @@
 <?xml version="1.0"?>
 <component name="org.collectionspace.acquisition.coreTypes">
   <extension target="org.nuxeo.ecm.core.schema.TypeService" point="schema">
-    <schema name="acquisition" prefix="acquisition" src="schemas/acquisition.xsd"/>
+    <schema name="acquisitions-common" prefix="acquisitions-common" src="schemas/acquisitions-common.xsd"/>
   </extension>
   <extension target="org.nuxeo.ecm.core.schema.TypeService" point="doctype">
     <doctype name="Acquisition" extends="Document">
       <schema name="common"/>
       <schema name="dublincore"/>
-      <schema name="acquisition"/>
+      <schema name="acquisitions-common"/>
     </doctype>
   </extension>
 </component>
index e4092c6860536b054c0f0d800b90051ac42e24e8..06390f9720c08b7feb4d089c0b899f0cb2c22920 100644 (file)
@@ -2,12 +2,12 @@ package org.collectionspace.services.client;
 
 import javax.ws.rs.core.Response;
 
-import org.collectionspace.services.acquisition.Acquisition;
-import org.collectionspace.services.acquisition.AcquisitionList;
-
+import org.collectionspace.services.acquisition.AcquisitionsCommonList;
 import org.jboss.resteasy.client.ProxyFactory;
 import org.jboss.resteasy.plugins.providers.RegisterBuiltin;
 import org.jboss.resteasy.client.ClientResponse;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
 import org.jboss.resteasy.spi.ResteasyProviderFactory;
 
 /**
@@ -51,7 +51,7 @@ public class AcquisitionClient extends BaseServiceClient {
      * @return
      * @see org.collectionspace.hello.client.IntakeProxy#getIntake()
      */
-    public ClientResponse<AcquisitionList> readList() {
+    public ClientResponse<AcquisitionsCommonList> readList() {
         return acquisitionProxy.readList();
     }
 
@@ -60,7 +60,7 @@ public class AcquisitionClient extends BaseServiceClient {
      * @return
      * @see org.collectionspace.hello.client.IntakeProxy#getIntake(java.lang.String)
      */
-    public ClientResponse<Acquisition> read(String csid) {
+    public ClientResponse<MultipartInput> read(String csid) {
         return acquisitionProxy.read(csid);
     }
 
@@ -69,8 +69,8 @@ public class AcquisitionClient extends BaseServiceClient {
      * @return
      * @see org.collectionspace.hello.client.IntakeProxy#createIntake(org.collectionspace.hello.Intake)
      */
-    public ClientResponse<Response> create(Acquisition intake) {
-        return acquisitionProxy.create(intake);
+    public ClientResponse<Response> create(MultipartOutput multipart) {
+        return acquisitionProxy.create(multipart);
     }
 
     /**
@@ -79,8 +79,8 @@ public class AcquisitionClient extends BaseServiceClient {
      * @return
      * @see org.collectionspace.hello.client.IntakeProxy#updateIntake(java.lang.Long, org.collectionspace.hello.Intake)
      */
-    public ClientResponse<Acquisition> update(String csid, Acquisition intake) {
-        return acquisitionProxy.update(csid, intake);
+    public ClientResponse<MultipartInput> update(String csid, MultipartOutput multipart) {
+        return acquisitionProxy.update(csid, multipart);
     }
 
     /**
index b74f11241343df511aa997e399353c755a373a59..0a7c02e45aabb2f03b5ed3cb3373cfb01b020b56 100644 (file)
@@ -10,37 +10,39 @@ import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.Response;
 
-import org.collectionspace.services.acquisition.Acquisition;
-import org.collectionspace.services.acquisition.AcquisitionList;
+import org.collectionspace.services.acquisition.AcquisitionsCommonList;
 import org.jboss.resteasy.client.ClientResponse;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
 
 /**
  * @version $Revision:$
  */
 @Path("/acquisitions/")
-@Produces({"application/xml"})
-@Consumes({"application/xml"})
+@Produces({"multipart/mixed"})
+@Consumes({"multipart/mixed"})
 public interface AcquisitionProxy {
 
     @GET
-    ClientResponse<AcquisitionList> readList();
+    @Produces({"application/xml"})
+    ClientResponse<AcquisitionsCommonList> readList();
 
     //(C)reate
     @POST
-    ClientResponse<Response> create(Acquisition co);
+    ClientResponse<Response> create(MultipartOutput multipart);
 
     //(R)ead
     @GET
     @Path("/{csid}")
-    ClientResponse<Acquisition> read(@PathParam("csid") String csid);
+    ClientResponse<MultipartInput> read(@PathParam("csid") String csid);
 
     //(U)pdate
     @PUT
     @Path("/{csid}")
-    ClientResponse<Acquisition> update(@PathParam("csid") String csid, Acquisition co);
+    ClientResponse<MultipartInput> update(@PathParam("csid") String csid, MultipartOutput multipart);
 
     //(D)elete
     @DELETE
     @Path("/{csid}")
     ClientResponse<Response> delete(@PathParam("csid") String csid);
-}
\ No newline at end of file
+}
index 6db1f4eb5f9165e98515c7f4f133632c86e2451e..c34959d9338653bdc9b49fd27952082bf823b8a8 100644 (file)
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
- package org.collectionspace.services.client.test;
+package org.collectionspace.services.client.test;
 
 import java.util.List;
+import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
 
 import org.collectionspace.services.client.AcquisitionClient;
-import org.collectionspace.services.client.test.ServiceRequestType;
-import org.collectionspace.services.acquisition.Acquisition;
-import org.collectionspace.services.acquisition.AcquisitionList;
 
+import org.collectionspace.services.acquisition.AcquisitionsCommon;
+import org.collectionspace.services.acquisition.AcquisitionsCommonList;
 import org.jboss.resteasy.client.ClientResponse;
 
+import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
+import org.jboss.resteasy.plugins.providers.multipart.OutputPart;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
@@ -51,13 +52,10 @@ public class AcquisitionServiceTest extends AbstractServiceTest {
     final String SERVICE_PATH_COMPONENT = "acquisitions";
     private String knownResourceId = null;
 
-
     // ---------------------------------------------------------------
     // CRUD tests : CREATE tests
     // ---------------------------------------------------------------
-
     // Success outcomes
-    
     @Override
     @Test
     public void create() {
@@ -69,8 +67,10 @@ public class AcquisitionServiceTest extends AbstractServiceTest {
 
         // Submit the request to the service and store the response.
         String identifier = createIdentifier();
-        Acquisition acquisition = createAcquisitionInstance(identifier);
-        ClientResponse<Response> res = client.create(acquisition);
+
+        MultipartOutput multipart = createAcquisitionInstance(identifier);
+        ClientResponse<Response> res = client.create(multipart);
+
         int statusCode = res.getStatus();
 
         // Check the status code of the response: does it match
@@ -81,12 +81,13 @@ public class AcquisitionServiceTest extends AbstractServiceTest {
         // Does it exactly match the expected status code?
         verbose("create: status = " + statusCode);
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
 
         // Store the ID returned from this create operation for
         // additional tests below.
         knownResourceId = extractId(res);
+        verbose("create: knownResourceId=" + knownResourceId);
     }
 
     @Override
@@ -98,294 +99,309 @@ public class AcquisitionServiceTest extends AbstractServiceTest {
     }
 
     // Failure outcomes
-    
     // Placeholders until the three tests below can be uncommented.
     // See Issue CSPACE-401.
-    public void createWithEmptyEntityBody() {}
-    public void createWithMalformedXml() {}
-    public void createWithWrongXmlSchema() {}
+    public void createWithEmptyEntityBody() {
+    }
 
-/*
+    public void createWithMalformedXml() {
+    }
+
+    public void createWithWrongXmlSchema() {
+    }
+
+    /*
     @Override
     @Test(dependsOnMethods = {"create", "testSubmitRequest"})
     public void createWithMalformedXml() {
     
-        // Perform setup.
-        setupCreateWithMalformedXml();
-
-        // Submit the request to the service and store the response.
-        String method = REQUEST_TYPE.httpMethodName();
-        String url = getServiceRootURL();
-        final String entity = MALFORMED_XML_DATA; // Constant from base class.
-        int statusCode = submitRequest(method, url, entity);
-        
-        // Check the status code of the response: does it match
-        // the expected response(s)?
-        verbose("createWithMalformedXml url=" + url + " status=" + statusCode);
-        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
-        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+    // Perform setup.
+    setupCreateWithMalformedXml();
+
+    // Submit the request to the service and store the response.
+    String method = REQUEST_TYPE.httpMethodName();
+    String url = getServiceRootURL();
+    final String entity = MALFORMED_XML_DATA; // Constant from base class.
+    int statusCode = submitRequest(method, url, entity);
+
+    // Check the status code of the response: does it match
+    // the expected response(s)?
+    verbose("createWithMalformedXml url=" + url + " status=" + statusCode);
+    Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+    invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+    Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
     }
 
     @Override
     @Test(dependsOnMethods = {"create", "testSubmitRequest"})
     public void createWithWrongXmlSchema() {
     
-        // Perform setup.
-        setupCreateWithWrongXmlSchema();
-     
-        // Submit the request to the service and store the response.
-        String method = REQUEST_TYPE.httpMethodName();
-        String url = getServiceRootURL();
-        final String entity = WRONG_XML_SCHEMA_DATA;
-        int statusCode = submitRequest(method, url, entity);
-        
-        // Check the status code of the response: does it match
-        // the expected response(s)?
-        verbose("createWithWrongSchema url=" + url + " status=" + statusCode);
-        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
-        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+    // Perform setup.
+    setupCreateWithWrongXmlSchema();
+
+    // Submit the request to the service and store the response.
+    String method = REQUEST_TYPE.httpMethodName();
+    String url = getServiceRootURL();
+    final String entity = WRONG_XML_SCHEMA_DATA;
+    int statusCode = submitRequest(method, url, entity);
+
+    // Check the status code of the response: does it match
+    // the expected response(s)?
+    verbose("createWithWrongSchema url=" + url + " status=" + statusCode);
+    Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+    invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+    Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
     }
-*/
-
+     */
     // ---------------------------------------------------------------
     // CRUD tests : READ tests
     // ---------------------------------------------------------------
-
     // Success outcomes
-
     @Override
     @Test(dependsOnMethods = {"create"})
     public void read() {
-    
+
         // Perform setup.
         setupRead();
 
         // Submit the request to the service and store the response.
-        ClientResponse<Acquisition> res = client.read(knownResourceId);
+        ClientResponse<MultipartInput> res = client.read(knownResourceId);
         int statusCode = res.getStatus();
-            
+
         // Check the status code of the response: does it match
         // the expected response(s)?
         verbose("read: status = " + statusCode);
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+        //FIXME: remove the following try catch once Aron fixes signatures
+        try{
+            MultipartInput input = (MultipartInput) res.getEntity();
+            AcquisitionsCommon acquistionObject = (AcquisitionsCommon) extractPart(input,
+                    getCommonPartName(), AcquisitionsCommon.class);
+            Assert.assertNotNull(acquistionObject);
+        }catch(Exception e){
+            throw new RuntimeException(e);
+        }
     }
 
     // Failure outcomes
-
     @Override
     @Test(dependsOnMethods = {"read"})
     public void readNonExistent() {
 
         // Perform setup.
         setupReadNonExistent();
-        
+
         // Submit the request to the service and store the response.
-        ClientResponse<Acquisition> res = client.read(NON_EXISTENT_ID);
+        ClientResponse<MultipartInput> res = client.read(NON_EXISTENT_ID);
         int statusCode = res.getStatus();
 
         // Check the status code of the response: does it match
         // the expected response(s)?
         verbose("readNonExistent: status = " + res.getStatus());
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
     }
 
-
     // ---------------------------------------------------------------
     // CRUD tests : READ_LIST tests
     // ---------------------------------------------------------------
-
     // Success outcomes
-
     @Override
-    @Test(dependsOnMethods = {"createList"})
+    @Test(dependsOnMethods = {"createList", "read"})
     public void readList() {
-    
+
         // Perform setup.
         setupReadList();
 
         // Submit the request to the service and store the response.
-        ClientResponse<AcquisitionList> res = client.readList();
-        AcquisitionList list = res.getEntity();
+        ClientResponse<AcquisitionsCommonList> res = client.readList();
+        AcquisitionsCommonList list = res.getEntity();
         int statusCode = res.getStatus();
 
         // Check the status code of the response: does it match
         // the expected response(s)?
         verbose("readList: status = " + res.getStatus());
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
 
         // Optionally output additional data about list members for debugging.
         boolean iterateThroughList = false;
-        if (iterateThroughList && logger.isDebugEnabled()) {
-            List<AcquisitionList.AcquisitionListItem> items =
-                list.getAcquisitionListItem();
+        if(iterateThroughList && logger.isDebugEnabled()){
+            List<AcquisitionsCommonList.AcquisitionListItem> items =
+                    list.getAcquisitionListItem();
             int i = 0;
-            for(AcquisitionList.AcquisitionListItem item : items){
+            for(AcquisitionsCommonList.AcquisitionListItem item : items){
                 verbose("readList: list-item[" + i + "] csid=" +
-                    item.getCsid());
+                        item.getCsid());
                 verbose("readList: list-item[" + i + "] objectNumber=" +
-                    item.getAccessiondate());
+                        item.getAccessiondate());
                 verbose("readList: list-item[" + i + "] URI=" +
-                    item.getUri());
+                        item.getUri());
                 i++;
             }
         }
-        
+
     }
 
     // Failure outcomes
-    
     // None at present.
-
-
     // ---------------------------------------------------------------
     // CRUD tests : UPDATE tests
     // ---------------------------------------------------------------
-
     // Success outcomes
-
     @Override
-    @Test(dependsOnMethods = {"create"})
+    @Test(dependsOnMethods = {"read"})
     public void update() {
-    
+
         // Perform setup.
         setupUpdate();
-
-        // Retrieve an existing resource that we can update.
-        ClientResponse<Acquisition> res = client.read(knownResourceId);
-        verbose("read: status = " + res.getStatus());
-        Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
-        Acquisition acquisition = res.getEntity();
-        verbose("Got object to update with ID: " + knownResourceId,
-                acquisition, Acquisition.class);
-
-        // Update the content of this resource.
-        acquisition.setAccessiondate("updated-" + acquisition.getAccessiondate());
-//        acquisition.setEntryDate("updated-" + acquisition.getEntryDate());
-    
-        // Submit the request to the service and store the response.
-        res = client.update(knownResourceId, acquisition);
-        int statusCode = res.getStatus();
-        Acquisition updatedObject = res.getEntity();
-
-        // Check the status code of the response: does it match
-        // the expected response(s)?
-        verbose("update: status = " + res.getStatus());
-        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
-        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
-        
-        // Check the contents of the response: does it match
-        // what was submitted?
-        verbose("update: ", updatedObject, Acquisition.class);
-        Assert.assertEquals(updatedObject.getAccessiondate(), 
-            acquisition.getAccessiondate(), 
-            "Data in updated object did not match submitted data.");
+        try{ //ideally, just remove try-catch and let the exception bubble up
+            // Retrieve an existing resource that we can update.
+            ClientResponse<MultipartInput> res =
+                    client.read(knownResourceId);
+            verbose("update: read status = " + res.getStatus());
+            Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
+
+            verbose("got object to update with ID: " + knownResourceId);
+            MultipartInput input = (MultipartInput) res.getEntity();
+            AcquisitionsCommon acquisition = (AcquisitionsCommon) extractPart(input,
+                    getCommonPartName(), AcquisitionsCommon.class);
+            Assert.assertNotNull(acquisition);
+
+            // Update the content of this resource.
+            acquisition.setAccessiondate("updated-" + acquisition.getAccessiondate());
+            verbose("updated object", acquisition, AcquisitionsCommon.class);
+            // Submit the request to the service and store the response.
+            MultipartOutput output = new MultipartOutput();
+            OutputPart commonPart = output.addPart(acquisition, MediaType.APPLICATION_XML_TYPE);
+            commonPart.getHeaders().add("label", getCommonPartName());
+
+            res = client.update(knownResourceId, output);
+            int statusCode = res.getStatus();
+            // Check the status code of the response: does it match the expected response(s)?
+            verbose("update: status = " + res.getStatus());
+            Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+                    invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+            Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+
+
+            input = (MultipartInput) res.getEntity();
+            AcquisitionsCommon updatedAcquisition =
+                    (AcquisitionsCommon) extractPart(input,
+                    getCommonPartName(), AcquisitionsCommon.class);
+            Assert.assertNotNull(updatedAcquisition);
+
+            Assert.assertEquals(updatedAcquisition.getAccessiondate(),
+                    acquisition.getAccessiondate(),
+                    "Data in updated object did not match submitted data.");
+        }catch(Exception e){
+            e.printStackTrace();
+        }
     }
 
     // Failure outcomes
-
     // Placeholders until the three tests below can be uncommented.
     // See Issue CSPACE-401.
-    public void updateWithEmptyEntityBody() {}
-    public void updateWithMalformedXml() {}
-    public void updateWithWrongXmlSchema() {}
+    public void updateWithEmptyEntityBody() {
+    }
 
-/*
+    public void updateWithMalformedXml() {
+    }
+
+    public void updateWithWrongXmlSchema() {
+    }
+
+    /*
     @Override
     @Test(dependsOnMethods = {"create", "update", "testSubmitRequest"})
     public void updateWithEmptyEntityBody() {
     
-        // Perform setup.
-        setupUpdateWithEmptyEntityBody();
-
-        // Submit the request to the service and store the response.
-        String method = REQUEST_TYPE.httpMethodName();
-        String url = getResourceURL(knownResourceId);
-        String mediaType = MediaType.APPLICATION_XML;
-        final String entity = "";
-        int statusCode = submitRequest(method, url, mediaType, entity);
-        
-        // Check the status code of the response: does it match
-        // the expected response(s)?
-        verbose("updateWithEmptyEntityBody url=" + url + " status=" + statusCode);
-        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
-        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+    // Perform setup.
+    setupUpdateWithEmptyEntityBody();
+
+    // Submit the request to the service and store the response.
+    String method = REQUEST_TYPE.httpMethodName();
+    String url = getResourceURL(knownResourceId);
+    String mediaType = MediaType.APPLICATION_XML;
+    final String entity = "";
+    int statusCode = submitRequest(method, url, mediaType, entity);
+
+    // Check the status code of the response: does it match
+    // the expected response(s)?
+    verbose("updateWithEmptyEntityBody url=" + url + " status=" + statusCode);
+    Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+    invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+    Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
     }
 
     @Override
     @Test(dependsOnMethods = {"create", "testSubmitRequest"})
     public void createWithEmptyEntityBody() {
     
-        // Perform setup.
-        setupCreateWithEmptyEntityBody();
-
-        // Submit the request to the service and store the response.
-        String method = REQUEST_TYPE.httpMethodName();
-        String url = getServiceRootURL();
-        String mediaType = MediaType.APPLICATION_XML;
-        final String entity = "";
-        int statusCode = submitRequest(method, url, mediaType, entity);
-        
-        // Check the status code of the response: does it match
-        // the expected response(s)?
-        verbose("createWithEmptyEntityBody url=" + url + " status=" + statusCode);
-        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
-        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+    // Perform setup.
+    setupCreateWithEmptyEntityBody();
+
+    // Submit the request to the service and store the response.
+    String method = REQUEST_TYPE.httpMethodName();
+    String url = getServiceRootURL();
+    String mediaType = MediaType.APPLICATION_XML;
+    final String entity = "";
+    int statusCode = submitRequest(method, url, mediaType, entity);
+
+    // Check the status code of the response: does it match
+    // the expected response(s)?
+    verbose("createWithEmptyEntityBody url=" + url + " status=" + statusCode);
+    Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+    invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+    Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
     }
 
     @Override
     @Test(dependsOnMethods = {"create", "update", "testSubmitRequest"})
     public void updateWithMalformedXml() {
 
-        // Perform setup.
-        setupUpdateWithMalformedXml();
-
-        // Submit the request to the service and store the response.
-        String method = REQUEST_TYPE.httpMethodName();
-        String url = getResourceURL(knownResourceId);
-        final String entity = MALFORMED_XML_DATA;
-        int statusCode = submitRequest(method, url, entity);
-        
-        // Check the status code of the response: does it match
-        // the expected response(s)?
-        verbose("updateWithMalformedXml: url=" + url + " status=" + statusCode);
-        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
-        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+    // Perform setup.
+    setupUpdateWithMalformedXml();
+
+    // Submit the request to the service and store the response.
+    String method = REQUEST_TYPE.httpMethodName();
+    String url = getResourceURL(knownResourceId);
+    final String entity = MALFORMED_XML_DATA;
+    int statusCode = submitRequest(method, url, entity);
+
+    // Check the status code of the response: does it match
+    // the expected response(s)?
+    verbose("updateWithMalformedXml: url=" + url + " status=" + statusCode);
+    Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+    invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+    Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
     }
 
     @Override
     @Test(dependsOnMethods = {"create", "update", "testSubmitRequest"})
     public void updateWithWrongXmlSchema() {
     
-        // Perform setup.
-        setupUpdateWithWrongXmlSchema();
-        
-        // Submit the request to the service and store the response.
-        String method = REQUEST_TYPE.httpMethodName();
-        String url = getResourceURL(knownResourceId);
-        final String entity = WRONG_XML_SCHEMA_DATA;
-        int statusCode = submitRequest(method, url, entity);
-        
-        // Check the status code of the response: does it match
-        // the expected response(s)?
-        verbose("updateWithWrongSchema: url=" + url + " status=" + statusCode);
-        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
-        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+    // Perform setup.
+    setupUpdateWithWrongXmlSchema();
+
+    // Submit the request to the service and store the response.
+    String method = REQUEST_TYPE.httpMethodName();
+    String url = getResourceURL(knownResourceId);
+    final String entity = WRONG_XML_SCHEMA_DATA;
+    int statusCode = submitRequest(method, url, entity);
+
+    // Check the status code of the response: does it match
+    // the expected response(s)?
+    verbose("updateWithWrongSchema: url=" + url + " status=" + statusCode);
+    Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+    invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+    Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
     }
-*/
-
+     */
     @Override
     @Test(dependsOnMethods = {"update", "testSubmitRequest"})
     public void updateNonExistent() {
@@ -396,28 +412,25 @@ public class AcquisitionServiceTest extends AbstractServiceTest {
         // Submit the request to the service and store the response.
         // Note: The ID used in this 'create' call may be arbitrary.
         // The only relevant ID may be the one used in update(), below.
-        Acquisition acquisition = createAcquisitionInstance(NON_EXISTENT_ID);
-        ClientResponse<Acquisition> res =
-          client.update(NON_EXISTENT_ID, acquisition);
+        MultipartOutput multipart = createAcquisitionInstance(NON_EXISTENT_ID);
+        ClientResponse<MultipartInput> res =
+                client.update(NON_EXISTENT_ID, multipart);
         int statusCode = res.getStatus();
 
         // Check the status code of the response: does it match
         // the expected response(s)?
         verbose("updateNonExistent: status = " + res.getStatus());
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
     }
 
     // ---------------------------------------------------------------
     // CRUD tests : DELETE tests
     // ---------------------------------------------------------------
-
     // Success outcomes
-
     @Override
-    @Test(dependsOnMethods = 
-        {"create", "read", "update"})
+    @Test(dependsOnMethods = {"create", "read", "update"})
     public void delete() {
 
         // Perform setup.
@@ -431,12 +444,11 @@ public class AcquisitionServiceTest extends AbstractServiceTest {
         // the expected response(s)?
         verbose("delete: status = " + res.getStatus());
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
     }
 
     // Failure outcomes
-
     @Override
     @Test(dependsOnMethods = {"delete"})
     public void deleteNonExistent() {
@@ -452,15 +464,13 @@ public class AcquisitionServiceTest extends AbstractServiceTest {
         // the expected response(s)?
         verbose("deleteNonExistent: status = " + res.getStatus());
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
     }
 
-
     // ---------------------------------------------------------------
     // Utility tests : tests of code used in tests above
     // ---------------------------------------------------------------
-
     /**
      * Tests the code for manually submitting data that is used by several
      * of the methods above.
@@ -475,36 +485,31 @@ public class AcquisitionServiceTest extends AbstractServiceTest {
         String method = ServiceRequestType.READ.httpMethodName();
         String url = getResourceURL(knownResourceId);
         int statusCode = submitRequest(method, url);
-        
+
         // Check the status code of the response: does it match
         // the expected response(s)?
         verbose("testSubmitRequest: url=" + url + " status=" + statusCode);
         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
 
-    }          
+    }
 
     // ---------------------------------------------------------------
     // Utility methods used by tests above
     // ---------------------------------------------------------------
-
     @Override
     public String getServicePathComponent() {
         return SERVICE_PATH_COMPONENT;
     }
-    
-    private Acquisition createAcquisitionInstance(String identifier) {
-        Acquisition acquisition =
-            createAcquisitionInstance(
-                "entryNumber-" + identifier,
-                "entryDate-" + identifier);
-        return acquisition;
-    }
-    
-    private Acquisition createAcquisitionInstance(String entryNumber, String entryDate) {
-        Acquisition acquisition = new Acquisition();
-//        acquisition.setEntryNumber(entryNumber);
-        acquisition.setAccessiondate(entryDate);
-        return acquisition;
-    }
 
+
+    private MultipartOutput createAcquisitionInstance(String identifier) {
+        AcquisitionsCommon acquisition = new AcquisitionsCommon();
+        acquisition.setAccessiondate("accessionDate-"  + identifier);
+        MultipartOutput multipart = new MultipartOutput();
+        OutputPart commonPart = multipart.addPart(acquisition, MediaType.APPLICATION_XML_TYPE);
+        commonPart.getHeaders().add("label", getCommonPartName());
+
+        verbose("to be created, collectionobject common ", acquisition, AcquisitionsCommon.class);
+        return multipart;
+    }
 }
similarity index 85%
rename from services/acquisition/jaxb/src/main/resources/acquisition.xsd
rename to services/acquisition/jaxb/src/main/resources/acquisitions-common.xsd
index 59466e746dfa6206ad47b3437c08226deed33d19..46f45f47464f3bfe9d0b04aee69f994b6630c55e 100644 (file)
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <xs:schema 
   xmlns:xs="http://www.w3.org/2001/XMLSchema"
-  xmlns:ns="http://collectionspace.org/acquisition"
-  xmlns="http://collectionspace.org/acquisition"
-  targetNamespace="http://services.collectionspace.org/acquisition"
+  xmlns:ns="http://collectionspace.org/services/acquisition"
+  xmlns="http://collectionspace.org/services/acquisition"
+  targetNamespace="http://collectionspace.org/services/acquisition"
   version="0.1"
 >
 
@@ -12,7 +12,7 @@
     <!-- See http://wiki.collectionspace.org/display/collectionspace/Acquisition+Schema -->    
     
     <!-- acquisition  -->
-    <xs:element name="acquisition">
+    <xs:element name="acquisitions-common">
         <xs:complexType>
             <xs:sequence>
                 <xs:element name="csid" type="xs:string" />
@@ -23,7 +23,7 @@
     </xs:element>
     
     <!-- acquisition records, as in nuxeo repository -->
-    <xs:element name="acquisition-list">
+    <xs:element name="acquisitions-common-list">
         <xs:complexType>
             <xs:sequence>
                 <xs:element name="acquisition-list-item" maxOccurs="unbounded">
index ff4a5c44d2ef2cff09750fa07321ced85d1e7ab8..41ca543bdbe1a12268ed26c459dd0c065f965bc7 100644 (file)
@@ -36,53 +36,57 @@ 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.acquisition.AcquisitionList.*;
-
-import org.collectionspace.services.acquisition.nuxeo.AcquisitionConstants;
 import org.collectionspace.services.acquisition.nuxeo.AcquisitionHandlerFactory;
-import org.collectionspace.services.common.NuxeoClientType;
-import org.collectionspace.services.common.ServiceMain;
+import org.collectionspace.services.common.AbstractCollectionSpaceResource;
+import org.collectionspace.services.common.context.ServiceContext;
 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.plugins.providers.multipart.MultipartInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
 import org.jboss.resteasy.util.HttpResponseCodes;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @Path("/acquisitions")
-@Consumes("application/xml")
-@Produces("application/xml")
-public class AcquisitionResource {
+@Consumes("multipart/mixed")
+@Produces("multipart/mixed")
+public class AcquisitionResource
+        extends AbstractCollectionSpaceResource {
 
-    public final static String ACQUISITION_SERVICE_NAME = "acquisitions";
+    final private String serviceName = "acquisitions";
     final Logger logger = LoggerFactory.getLogger(AcquisitionResource.class);
-    //FIXME retrieve client type from configuration
-    final static NuxeoClientType CLIENT_TYPE = ServiceMain.getInstance().getNuxeoClientType();
+
+    @Override
+    public String getServiceName() {
+        return serviceName;
+    }
+
+    @Override
+    public DocumentHandler createDocumentHandler(ServiceContext ctx) throws Exception {
+        DocumentHandler docHandler = AcquisitionHandlerFactory.getInstance().getHandler(
+                ctx.getRepositoryClientType().toString());
+        docHandler.setServiceContext(ctx);
+        if(ctx.getInput() != null){
+            Object obj = ctx.getInputPart(ctx.getCommonPartLabel(), AcquisitionsCommon.class);
+            if(obj != null){
+                docHandler.setCommonPart((AcquisitionsCommon) obj);
+            }
+        }
+        return docHandler;
+    }
 
     public AcquisitionResource() {
         // do nothing
     }
 
     @POST
-    public Response createAcquisition(
-            Acquisition acquisitionObject) {
+    public Response createAcquisition(MultipartInput input) {
 
-        String csid = null;
         try{
-            RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
-            RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
-            AcquisitionHandlerFactory handlerFactory = AcquisitionHandlerFactory.getInstance();
-            DocumentHandler handler = (DocumentHandler) handlerFactory.getHandler(CLIENT_TYPE.toString());
-            handler.setCommonObject(acquisitionObject);
-            csid = client.create(ACQUISITION_SERVICE_NAME, handler);
-            acquisitionObject.setCsid(csid);
-            if(logger.isDebugEnabled()){
-                verbose("createAcquisition: ", acquisitionObject);
-            }
+            ServiceContext ctx = createServiceContext(input);
+            DocumentHandler handler = createDocumentHandler(ctx);
+            String csid = getRepositoryClient(ctx).create(ctx, handler);
             UriBuilder path = UriBuilder.fromResource(AcquisitionResource.class);
             path.path("" + csid);
             Response response = Response.created(path.build()).build();
@@ -99,10 +103,10 @@ public class AcquisitionResource {
 
     @GET
     @Path("{csid}")
-    public Acquisition getAcquisition(
+    public MultipartOutput getAcquisition(
             @PathParam("csid") String csid) {
         if(logger.isDebugEnabled()){
-            verbose("getAcquisition with csid=" + csid);
+            logger.debug("getAcquisition with csid=" + csid);
         }
         if(csid == null || "".equals(csid)){
             logger.error("getAcquisition: missing csid!");
@@ -111,14 +115,12 @@ public class AcquisitionResource {
                     "text/plain").build();
             throw new WebApplicationException(response);
         }
-        Acquisition acquisitionObject = null;
+        MultipartOutput result = null;
         try{
-            RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
-            RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
-            AcquisitionHandlerFactory handlerFactory = AcquisitionHandlerFactory.getInstance();
-            DocumentHandler handler = (DocumentHandler) handlerFactory.getHandler(CLIENT_TYPE.toString());
-            client.get(csid, handler);
-            acquisitionObject = (Acquisition) handler.getCommonObject();
+            ServiceContext ctx = createServiceContext(null);
+            DocumentHandler handler = createDocumentHandler(ctx);
+            getRepositoryClient(ctx).get(ctx, csid, handler);
+            result = ctx.getOutput();
         }catch(DocumentNotFoundException dnfe){
             if(logger.isDebugEnabled()){
                 logger.debug("getAcquisition", dnfe);
@@ -136,28 +138,24 @@ public class AcquisitionResource {
             throw new WebApplicationException(response);
         }
 
-        if(acquisitionObject == null){
+        if(result == null){
             Response response = Response.status(Response.Status.NOT_FOUND).entity(
                     "Get failed, the requested Acquisition CSID:" + csid + ": was not found.").type(
                     "text/plain").build();
             throw new WebApplicationException(response);
         }
-        if(logger.isDebugEnabled()){
-            verbose("getAcquisition: ", acquisitionObject);
-        }
-        return acquisitionObject;
+        return result;
     }
 
     @GET
-    public AcquisitionList getAcquisitionList(@Context UriInfo ui) {
-        AcquisitionList acquisitionObjectList = new AcquisitionList();
+    @Produces("application/xml")
+    public AcquisitionsCommonList getAcquisitionList(@Context UriInfo ui) {
+        AcquisitionsCommonList acquisitionObjectList = new AcquisitionsCommonList();
         try{
-            RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
-            RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
-            AcquisitionHandlerFactory handlerFactory = AcquisitionHandlerFactory.getInstance();
-            DocumentHandler handler = (DocumentHandler) handlerFactory.getHandler(CLIENT_TYPE.toString());
-            client.getAll(ACQUISITION_SERVICE_NAME, handler);
-            acquisitionObjectList = (AcquisitionList) handler.getCommonObjectList();
+            ServiceContext ctx = createServiceContext(null);
+            DocumentHandler handler = createDocumentHandler(ctx);
+            getRepositoryClient(ctx).getAll(ctx, handler);
+            acquisitionObjectList = (AcquisitionsCommonList) handler.getCommonPartList();
         }catch(Exception e){
             if(logger.isDebugEnabled()){
                 logger.debug("Caught exception in getAcquisitionList", e);
@@ -171,11 +169,11 @@ public class AcquisitionResource {
 
     @PUT
     @Path("{csid}")
-    public Acquisition updateAcquisition(
+    public MultipartOutput updateAcquisition(
             @PathParam("csid") String csid,
-            Acquisition theUpdate) {
+            MultipartInput theUpdate) {
         if(logger.isDebugEnabled()){
-            verbose("updateAcquisition with csid=" + csid);
+            logger.debug("updateAcquisition with csid=" + csid);
         }
         if(csid == null || "".equals(csid)){
             logger.error("updateAcquisition: missing csid!");
@@ -185,15 +183,14 @@ public class AcquisitionResource {
             throw new WebApplicationException(response);
         }
         if(logger.isDebugEnabled()){
-            verbose("updateAcquisition with input: ", theUpdate);
+            logger.debug("updateAcquisition with input: ", theUpdate);
         }
+        MultipartOutput result = null;
         try{
-            RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
-            RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
-            AcquisitionHandlerFactory handlerFactory = AcquisitionHandlerFactory.getInstance();
-            DocumentHandler handler = (DocumentHandler) handlerFactory.getHandler(CLIENT_TYPE.toString());
-            handler.setCommonObject(theUpdate);
-            client.update(csid, handler);
+            ServiceContext ctx = createServiceContext(theUpdate);
+            DocumentHandler handler = createDocumentHandler(ctx);
+            getRepositoryClient(ctx).update(ctx, csid, handler);
+            result = ctx.getOutput();
         }catch(DocumentNotFoundException dnfe){
             if(logger.isDebugEnabled()){
                 logger.debug("caugth exception in updateAcquisition", dnfe);
@@ -207,7 +204,7 @@ public class AcquisitionResource {
                     Response.Status.INTERNAL_SERVER_ERROR).entity("Update failed").type("text/plain").build();
             throw new WebApplicationException(response);
         }
-        return theUpdate;
+        return result;
     }
 
     @DELETE
@@ -215,7 +212,7 @@ public class AcquisitionResource {
     public Response deleteAcquisition(@PathParam("csid") String csid) {
 
         if(logger.isDebugEnabled()){
-            verbose("deleteAcquisition with csid=" + csid);
+            logger.debug("deleteAcquisition with csid=" + csid);
         }
         if(csid == null || "".equals(csid)){
             logger.error("deleteAcquisition: missing csid!");
@@ -225,9 +222,8 @@ public class AcquisitionResource {
             throw new WebApplicationException(response);
         }
         try{
-            RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
-            RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
-            client.delete(csid);
+            ServiceContext ctx = createServiceContext(null);
+            getRepositoryClient(ctx).delete(ctx, csid);
             return Response.status(HttpResponseCodes.SC_OK).build();
         }catch(DocumentNotFoundException dnfe){
             if(logger.isDebugEnabled()){
@@ -245,22 +241,4 @@ public class AcquisitionResource {
 
     }
 
-    private void verbose(String msg, Acquisition acquisitionObject) {
-        try{
-            verbose(msg);
-            JAXBContext jc = JAXBContext.newInstance(
-                    Acquisition.class);
-
-            Marshaller m = jc.createMarshaller();
-            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
-            m.marshal(acquisitionObject, System.out);
-        }catch(Exception e){
-            e.printStackTrace();
-        }
-
-    }
-
-    private void verbose(String msg) {
-        System.out.println("AcquisitionResource. " + msg);
-    }
 }
diff --git a/services/acquisition/service/src/main/java/org/collectionspace/services/acquisition/AcquisitionService.java b/services/acquisition/service/src/main/java/org/collectionspace/services/acquisition/AcquisitionService.java
deleted file mode 100644 (file)
index 68009d3..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/**\r
- * \r
- */\r
-package org.collectionspace.services.acquisition;\r
-\r
-import java.io.IOException;\r
-import org.dom4j.Document;\r
-import org.dom4j.DocumentException;\r
-\r
-import org.collectionspace.services.acquisition.Acquisition;\r
-\r
-/**\r
- * @author remillet\r
- * \r
- */\r
-public interface AcquisitionService {\r
-\r
-       public final static String ACQUISITION_SCHEMA_NAME = "acquisition";\r
-\r
-       // Create\r
-       Document postAcquisition(Acquisition co)\r
-                       throws DocumentException, IOException;\r
-\r
-       // Read single object\r
-       Document getAcquisition(String csid) throws DocumentException,\r
-                       IOException;\r
-\r
-       // Read a list of objects\r
-       Document getAcquisitionList() throws DocumentException, IOException;\r
-\r
-       // Update\r
-       Document putAcquisition(String csid, Acquisition theUpdate)\r
-                       throws DocumentException, IOException;\r
-\r
-       // Delete\r
-       Document deleteAcquisition(String csid) throws DocumentException,\r
-                       IOException;\r
-}\r
index 1570184da218ad700da029ef8365c02e99f652ea..33d3cc4d9d99d4bc628110b46a3f2bf2257a6afa 100644 (file)
@@ -28,11 +28,10 @@ import java.util.List;
 
 import org.collectionspace.services.AcquisitionJAXBSchema;
 import org.collectionspace.services.common.repository.DocumentWrapper;
-import org.collectionspace.services.acquisition.Acquisition;
-import org.collectionspace.services.acquisition.AcquisitionList;
-import org.collectionspace.services.acquisition.AcquisitionList.AcquisitionListItem;
+import org.collectionspace.services.acquisition.AcquisitionsCommon;
+import org.collectionspace.services.acquisition.AcquisitionsCommonList;
+import org.collectionspace.services.acquisition.AcquisitionsCommonList.AcquisitionListItem;
 import org.collectionspace.services.nuxeo.client.java.DocumentModelHandler;
-import org.collectionspace.services.acquisition.nuxeo.AcquisitionConstants;
 
 import org.nuxeo.ecm.core.api.DocumentModel;
 import org.nuxeo.ecm.core.api.DocumentModelList;
@@ -46,19 +45,19 @@ import org.slf4j.LoggerFactory;
  * $LastChangedDate: $
  */
 public class AcquisitionDocumentModelHandler
-        extends DocumentModelHandler<Acquisition, AcquisitionList> {
+        extends DocumentModelHandler<AcquisitionsCommon, AcquisitionsCommonList> {
 
     private final Logger logger = LoggerFactory.getLogger(AcquisitionDocumentModelHandler.class);
     /**
      * acquisition is used to stash JAXB object to use when handle is called
      * for Action.CREATE, Action.UPDATE or Action.GET
      */
-    private Acquisition acquisition;
+    private AcquisitionsCommon acquisition;
     /**
      * acquisitionList is stashed when handle is called
      * for ACTION.GET_ALL
      */
-    private AcquisitionList acquisitionList;
+    private AcquisitionsCommonList acquisitionList;
 
     @Override
     public void prepare(Action action) throws Exception {
@@ -66,20 +65,20 @@ public class AcquisitionDocumentModelHandler
     }
 
     /**
-     * getCommonObject get associated acquisition
+     * getCommonPart get associated acquisition
      * @return
      */
     @Override
-    public Acquisition getCommonObject() {
+    public AcquisitionsCommon getCommonPart() {
         return acquisition;
     }
 
     /**
-     * setCommonObject set associated acquisition
+     * setCommonPart set associated acquisition
      * @param acquisition
      */
     @Override
-    public void setCommonObject(Acquisition acquisition) {
+    public void setCommonPart(AcquisitionsCommon acquisition) {
         this.acquisition = acquisition;
     }
 
@@ -88,53 +87,32 @@ public class AcquisitionDocumentModelHandler
      * @return
      */
     @Override
-    public AcquisitionList getCommonObjectList() {
+    public AcquisitionsCommonList getCommonPartList() {
         return acquisitionList;
     }
 
     @Override
-    public void setCommonObjectList(AcquisitionList acquisitionList) {
+    public void setCommonPartList(AcquisitionsCommonList acquisitionList) {
         this.acquisitionList = acquisitionList;
     }
 
     @Override
-    public Acquisition extractCommonObject(DocumentWrapper wrapDoc)
+    public AcquisitionsCommon extractCommonPart(DocumentWrapper wrapDoc)
             throws Exception {
-        DocumentModel docModel = (DocumentModel) wrapDoc.getWrappedObject();
-        Acquisition acquisitionObject = new Acquisition();
-
-        //FIXME property get should be dynamically set using schema inspection
-        //so it does not require hard coding
-
-        // acquisition core values
-        acquisitionObject.setAccessiondate((String)docModel.getPropertyValue(
-                getQProperty(AcquisitionJAXBSchema.ACCESSIONDATE)));
-
-        return acquisitionObject;
+        throw new UnsupportedOperationException();
     }
 
     @Override
-    public void fillCommonObject(Acquisition acquisitionObject, 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", AcquisitionConstants.NUXEO_DC_TITLE);
-
-        // acquisition core values
-        if(acquisitionObject.getAccessiondate() != null){
-            docModel.setPropertyValue(getQProperty(
-                    AcquisitionJAXBSchema.ACCESSIONDATE), acquisitionObject.getAccessiondate());
-        }
+    public void fillCommonPart(AcquisitionsCommon acquisitionObject, DocumentWrapper wrapDoc) throws Exception {
+        throw new UnsupportedOperationException();
     }
 
     @Override
-    public AcquisitionList extractCommonObjectList(DocumentWrapper wrapDoc) throws Exception {
+    public AcquisitionsCommonList extractCommonPartList(DocumentWrapper wrapDoc) throws Exception {
         DocumentModelList docList = (DocumentModelList) wrapDoc.getWrappedObject();
 
-        AcquisitionList coList = new AcquisitionList();
-        List<AcquisitionList.AcquisitionListItem> list = coList.getAcquisitionListItem();
+        AcquisitionsCommonList coList = new AcquisitionsCommonList();
+        List<AcquisitionsCommonList.AcquisitionListItem> list = coList.getAcquisitionListItem();
 
         //FIXME: iterating over a long list of documents is not a long term
         //strategy...need to change to more efficient iterating in future
@@ -142,11 +120,11 @@ public class AcquisitionDocumentModelHandler
         while(iter.hasNext()){
             DocumentModel docModel = iter.next();
             AcquisitionListItem listItem = new AcquisitionListItem();
-            listItem.setAccessiondate((String)docModel.getPropertyValue(
-                    getQProperty(AcquisitionJAXBSchema.ACCESSIONDATE)));
+            listItem.setAccessiondate((String) docModel.getProperty(getServiceContext().getCommonPartLabel(),
+                    AcquisitionJAXBSchema.ACCESSIONDATE));
             //need fully qualified context for URI
             String id = docModel.getId();
-            listItem.setUri("/acquisitions/" + id);
+            listItem.setUri(getServiceContextPath() + id);
             listItem.setCsid(id);
             list.add(listItem);
         }
@@ -155,23 +133,35 @@ public class AcquisitionDocumentModelHandler
     }
 
     @Override
-    public void fillCommonObjectList(AcquisitionList obj, DocumentWrapper wrapDoc) throws Exception {
-        throw new UnsupportedOperationException();
+    public void fillAllParts(DocumentWrapper wrapDoc) throws Exception {
+
+        super.fillAllParts(wrapDoc);
+        fillDublinCoreObject(wrapDoc); //dublincore might not be needed in future
     }
 
+    private void fillDublinCoreObject(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", AcquisitionConstants.NUXEO_DC_TITLE);
+    }
+
+
     /* (non-Javadoc)
      * @see org.collectionspace.services.nuxeo.client.java.DocumentModelHandler#getDocumentType()
      */
     public String getDocumentType() {
-       return AcquisitionConstants.NUXEO_DOCTYPE;
+        return AcquisitionConstants.NUXEO_DOCTYPE;
     }
-    
+
     /**
      * getQProperty converts the given property to qualified schema property
      * @param prop
      * @return
      */
-    private String getQProperty(String prop) {
+    @Override
+    public String getQProperty(String prop) {
         return AcquisitionConstants.NUXEO_SCHEMA_NAME + ":" + prop;
     }
 }
index ecb198567a696b623db3ebc8758c74f7d979cc83..1638373367330d845448ff9607f00b87e019920a 100644 (file)
@@ -23,7 +23,7 @@
  */
 package org.collectionspace.services.acquisition.nuxeo;
 
-import org.collectionspace.services.common.NuxeoClientType;
+import org.collectionspace.services.common.ClientType;
 import org.collectionspace.services.common.repository.DocumentHandler;
 
 /**
@@ -45,7 +45,7 @@ public class AcquisitionHandlerFactory {
     }
 
     public DocumentHandler getHandler(String clientType) {
-        if(NuxeoClientType.JAVA.toString().equals(clientType)){
+        if(ClientType.JAVA.toString().equals(clientType)){
             return new AcquisitionDocumentModelHandler();
         }
         
index adcca32d127275a4f71d7e50b545b090d34a016d..9561cd40a36b5480c413f2d31cc8dbc07fddfd6a 100644 (file)
  */
 package org.collectionspace.services.authentication.client;
 
-import java.util.ArrayList;
-import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.Marshaller;
 import org.jboss.resteasy.client.ClientResponse;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import org.collectionspace.services.collectionobject.CollectionObject;
+import org.collectionspace.services.collectionobject.CollectionobjectsCommon;
 import org.collectionspace.services.client.CollectionObjectClient;
 import org.collectionspace.services.client.CollectionSpaceClient;
+import org.collectionspace.services.client.test.AbstractServiceTest;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
+import org.jboss.resteasy.plugins.providers.multipart.OutputPart;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -43,15 +43,29 @@ import org.slf4j.LoggerFactory;
  * $LastChangedRevision: 434 $
  * $LastChangedDate: 2009-07-28 14:34:15 -0700 (Tue, 28 Jul 2009) $
  */
-public class AuthenticationServiceTest {
+public class AuthenticationServiceTest extends AbstractServiceTest {
 
-    private String knownCollectionObjectId = null;
+    final String SERVICE_PATH_COMPONENT = "collectionobjects";
+    private String knownResourceId = null;
     final Logger logger = LoggerFactory.getLogger(AuthenticationServiceTest.class);
 
+    @Override
+    public String getServicePathComponent() {
+        // @TODO Determine if it is possible to obtain this
+        // value programmatically.
+        //
+        // We set this in an annotation in the CollectionObjectProxy
+        // interface, for instance.  We also set service-specific
+        // constants in each service module, which might also
+        // return this value.
+        return SERVICE_PATH_COMPONENT;
+    }
+
     @Test
-    public void auth_createCollectionObject() {
+    @Override
+    public void create() {
         String identifier = this.createIdentifier();
-        CollectionObject collectionObject = createCollectionObject(identifier);
+        MultipartOutput multipart = createCollectionObjectInstance(identifier);
         CollectionObjectClient collectionObjectClient = new CollectionObjectClient();
         if(!collectionObjectClient.isServerSecure()){
             logger.warn("set -Dcspace.server.secure=true to run security tests");
@@ -64,22 +78,22 @@ public class AuthenticationServiceTest {
             collectionObjectClient.setupHttpClient();
             collectionObjectClient.setProxy();
         }catch(Exception e){
-            logger.error("auth_createCollectionObject: caught " + e.getMessage());
+            logger.error("create: caught " + e.getMessage());
             return;
         }
-        ClientResponse<Response> res = collectionObjectClient.create(collectionObject);
-        verbose("auth_createCollectionObject: status = " + res.getStatus());
+        ClientResponse<Response> res = collectionObjectClient.create(multipart);
+        verbose("create: status = " + res.getStatus());
         Assert.assertEquals(res.getStatus(), Response.Status.CREATED.getStatusCode(),
                 "expected " + Response.Status.CREATED.getStatusCode());
 
         // Store the ID returned from this create operation for additional tests below.
-        knownCollectionObjectId = extractId(res);
+        knownResourceId = extractId(res);
     }
 
-    @Test(dependsOnMethods = {"auth_createCollectionObject"})
-    public void auth_createCollectionObjectWithoutUser() {
+    @Test(dependsOnMethods = {"create"})
+    public void createWithoutUser() {
         String identifier = this.createIdentifier();
-        CollectionObject collectionObject = createCollectionObject(identifier);
+        MultipartOutput multipart = createCollectionObjectInstance(identifier);
         CollectionObjectClient collectionObjectClient = new CollectionObjectClient();
         if(!collectionObjectClient.isServerSecure()){
             logger.warn("set -Dcspace.server.secure=true to run security tests");
@@ -92,19 +106,19 @@ public class AuthenticationServiceTest {
             collectionObjectClient.setupHttpClient();
             collectionObjectClient.setProxy();
         }catch(Exception e){
-            logger.error("auth_createCollectionObjectWithoutUser: caught " + e.getMessage());
+            logger.error("createWithoutUser: caught " + e.getMessage());
             return;
         }
-        ClientResponse<Response> res = collectionObjectClient.create(collectionObject);
-        verbose("auth_createCollectionObjectWithoutUser: status = " + res.getStatus());
+        ClientResponse<Response> res = collectionObjectClient.create(multipart);
+        verbose("createWithoutUser: status = " + res.getStatus());
         Assert.assertEquals(res.getStatus(), Response.Status.UNAUTHORIZED.getStatusCode(),
                 "expected " + Response.Status.UNAUTHORIZED.getStatusCode());
     }
 
-    @Test(dependsOnMethods = {"auth_createCollectionObjectWithoutUser"})
-    public void auth_createCollectionObjectWithoutPassword() {
+    @Test(dependsOnMethods = {"createWithoutUser"})
+    public void createWithoutPassword() {
         String identifier = this.createIdentifier();
-        CollectionObject collectionObject = createCollectionObject(identifier);
+        MultipartOutput multipart = createCollectionObjectInstance(identifier);
         CollectionObjectClient collectionObjectClient = new CollectionObjectClient();
         if(!collectionObjectClient.isServerSecure()){
             logger.warn("set -Dcspace.server.secure=true to run security tests");
@@ -117,19 +131,19 @@ public class AuthenticationServiceTest {
             collectionObjectClient.setupHttpClient();
             collectionObjectClient.setProxy();
         }catch(Exception e){
-            logger.error("auth_createCollectionObjectWithoutPassword: caught " + e.getMessage());
+            logger.error("createWithoutPassword: caught " + e.getMessage());
             return;
         }
-        ClientResponse<Response> res = collectionObjectClient.create(collectionObject);
-        verbose("auth_createCollectionObjectWithoutPassword: status = " + res.getStatus());
+        ClientResponse<Response> res = collectionObjectClient.create(multipart);
+        verbose("createWithoutPassword: status = " + res.getStatus());
         Assert.assertEquals(res.getStatus(), Response.Status.UNAUTHORIZED.getStatusCode(),
                 "expected " + Response.Status.UNAUTHORIZED.getStatusCode());
     }
 
-    @Test(dependsOnMethods = {"auth_createCollectionObjectWithoutPassword"})
-    public void auth_createCollectionObjectWithIncorrectPassword() {
+    @Test(dependsOnMethods = {"createWithoutPassword"})
+    public void createWithIncorrectPassword() {
         String identifier = this.createIdentifier();
-        CollectionObject collectionObject = createCollectionObject(identifier);
+        MultipartOutput multipart = createCollectionObjectInstance(identifier);
         CollectionObjectClient collectionObjectClient = new CollectionObjectClient();
         if(!collectionObjectClient.isServerSecure()){
             logger.warn("set -Dcspace.server.secure=true to run security tests");
@@ -142,19 +156,19 @@ public class AuthenticationServiceTest {
             collectionObjectClient.setupHttpClient();
             collectionObjectClient.setProxy();
         }catch(Exception e){
-            logger.error("auth_createCollectionObjectWithIncorrectPassword: caught " + e.getMessage());
+            logger.error("createWithIncorrectPassword: caught " + e.getMessage());
             return;
         }
-        ClientResponse<Response> res = collectionObjectClient.create(collectionObject);
-        verbose("auth_createCollectionObjectWithIncorrectPassword: status = " + res.getStatus());
+        ClientResponse<Response> res = collectionObjectClient.create(multipart);
+        verbose("createWithIncorrectPassword: status = " + res.getStatus());
         Assert.assertEquals(res.getStatus(), Response.Status.UNAUTHORIZED.getStatusCode(),
                 "expected " + Response.Status.UNAUTHORIZED.getStatusCode());
     }
 
-    @Test(dependsOnMethods = {"auth_createCollectionObjectWithoutPassword"})
-    public void auth_createCollectionObjectWithoutUserPassword() {
+    @Test(dependsOnMethods = {"createWithoutPassword"})
+    public void createWithoutUserPassword() {
         String identifier = this.createIdentifier();
-        CollectionObject collectionObject = createCollectionObject(identifier);
+        MultipartOutput multipart = createCollectionObjectInstance(identifier);
         CollectionObjectClient collectionObjectClient = new CollectionObjectClient();
         if(!collectionObjectClient.isServerSecure()){
             logger.warn("set -Dcspace.server.secure=true to run security tests");
@@ -167,19 +181,19 @@ public class AuthenticationServiceTest {
             collectionObjectClient.setupHttpClient();
             collectionObjectClient.setProxy();
         }catch(Exception e){
-            logger.error("auth_createCollectionObjectWithoutUserPassword: caught " + e.getMessage());
+            logger.error("createWithoutUserPassword: caught " + e.getMessage());
             return;
         }
-        ClientResponse<Response> res = collectionObjectClient.create(collectionObject);
-        verbose("auth_createCollectionObjectWithoutUserPassword: status = " + res.getStatus());
+        ClientResponse<Response> res = collectionObjectClient.create(multipart);
+        verbose("createWithoutUserPassword: status = " + res.getStatus());
         Assert.assertEquals(res.getStatus(), Response.Status.FORBIDDEN.getStatusCode(),
                 "expected " + Response.Status.FORBIDDEN.getStatusCode());
     }
 
-    @Test(dependsOnMethods = {"auth_createCollectionObjectWithoutPassword"})
-    public void auth_createCollectionObjectWithIncorrectUserPassword() {
+    @Test(dependsOnMethods = {"createWithoutPassword"})
+    public void createWithIncorrectUserPassword() {
         String identifier = this.createIdentifier();
-        CollectionObject collectionObject = createCollectionObject(identifier);
+        MultipartOutput multipart = createCollectionObjectInstance(identifier);
         CollectionObjectClient collectionObjectClient = new CollectionObjectClient();
         if(!collectionObjectClient.isServerSecure()){
             logger.warn("set -Dcspace.server.secure=true to run security tests");
@@ -192,17 +206,18 @@ public class AuthenticationServiceTest {
             collectionObjectClient.setupHttpClient();
             collectionObjectClient.setProxy();
         }catch(Exception e){
-            logger.error("auth_createCollectionObjectWithIncorrectUserPassword: caught " + e.getMessage());
+            logger.error("createWithIncorrectUserPassword: caught " + e.getMessage());
             return;
         }
-        ClientResponse<Response> res = collectionObjectClient.create(collectionObject);
-        verbose("auth_createCollectionObjectWithIncorrectUserPassword: status = " + res.getStatus());
+        ClientResponse<Response> res = collectionObjectClient.create(multipart);
+        verbose("createWithIncorrectUserPassword: status = " + res.getStatus());
         Assert.assertEquals(res.getStatus(), Response.Status.UNAUTHORIZED.getStatusCode(),
                 "expected " + Response.Status.UNAUTHORIZED.getStatusCode());
     }
 
-    @Test(dependsOnMethods = {"auth_createCollectionObjectWithIncorrectUserPassword"})
-    public void auth_deleteCollectionObject() {
+    @Override
+    @Test(dependsOnMethods = {"createWithIncorrectUserPassword"})
+    public void delete() {
         CollectionObjectClient collectionObjectClient = new CollectionObjectClient();
         collectionObjectClient = new CollectionObjectClient();
         if(!collectionObjectClient.isServerSecure()){
@@ -216,12 +231,12 @@ public class AuthenticationServiceTest {
             collectionObjectClient.setupHttpClient();
             collectionObjectClient.setProxy();
         }catch(Exception e){
-            logger.error("auth_deleteCollectionObject: caught " + e.getMessage());
+            logger.error("deleteCollectionObject: caught " + e.getMessage());
             return;
         }
-        verbose("Calling deleteCollectionObject:" + knownCollectionObjectId);
-        ClientResponse<Response> res = collectionObjectClient.delete(knownCollectionObjectId);
-        verbose("auth_deleteCollectionObject: status = " + res.getStatus());
+        verbose("Calling deleteCollectionObject:" + knownResourceId);
+        ClientResponse<Response> res = collectionObjectClient.delete(knownResourceId);
+        verbose("deleteCollectionObject: status = " + res.getStatus());
         Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode(),
                 "expected " + Response.Status.OK.getStatusCode());
     }
@@ -229,53 +244,73 @@ public class AuthenticationServiceTest {
     // ---------------------------------------------------------------
     // Utility methods used by tests above
     // ---------------------------------------------------------------
-    private CollectionObject createCollectionObject(String identifier) {
-        CollectionObject collectionObject = createCollectionObject("objectNumber-" + identifier,
+    private MultipartOutput createCollectionObjectInstance(String identifier) {
+        return createCollectionObjectInstance("objectNumber-" + identifier,
                 "objectName-" + identifier);
-
-        return collectionObject;
     }
 
-    private CollectionObject createCollectionObject(String objectNumber, String objectName) {
-        CollectionObject collectionObject = new CollectionObject();
+    private MultipartOutput createCollectionObjectInstance(String objectNumber, String objectName) {
+        CollectionobjectsCommon collectionObject = new CollectionobjectsCommon();
 
         collectionObject.setObjectNumber(objectNumber);
         collectionObject.setObjectName(objectName);
+        MultipartOutput multipart = new MultipartOutput();
+        OutputPart commonPart = multipart.addPart(collectionObject, MediaType.APPLICATION_XML_TYPE);
+        commonPart.getHeaders().add("label", getCommonPartName());
 
-        return collectionObject;
+        verbose("to be created, collectionobject common ", collectionObject, CollectionobjectsCommon.class);
+        return multipart;
     }
 
-    private String extractId(ClientResponse<Response> res) {
-        MultivaluedMap mvm = res.getMetadata();
-        String uri = (String) ((ArrayList) mvm.get("Location")).get(0);
-        verbose("extractId:uri=" + uri);
-        String[] segments = uri.split("/");
-        String id = segments[segments.length - 1];
-        verbose("id=" + id);
-        return id;
+    @Override
+    public void createList() {
     }
 
-    private void verbose(String msg) {
-        if(logger.isInfoEnabled()){
-            logger.debug(msg);
-        }
+    @Override
+    public void createWithEmptyEntityBody() {
     }
 
-    private void verbose(String msg, Object o, Class clazz) {
-        try{
-            verbose(msg);
-            JAXBContext jc = JAXBContext.newInstance(clazz);
-            Marshaller m = jc.createMarshaller();
-            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
-                    Boolean.TRUE);
-            m.marshal(o, System.out);
-        }catch(Exception e){
-            e.printStackTrace();
-        }
+    @Override
+    public void createWithMalformedXml() {
+    }
+
+    @Override
+    public void createWithWrongXmlSchema() {
+    }
+
+    @Override
+    public void read() {
+    }
+
+    @Override
+    public void readNonExistent() {
+    }
+
+    @Override
+    public void readList() {
+    }
+
+    @Override
+    public void update() {
+    }
+
+    @Override
+    public void updateWithEmptyEntityBody() {
+    }
+
+    @Override
+    public void updateWithMalformedXml() {
+    }
+
+    @Override
+    public void updateWithWrongXmlSchema() {
+    }
+
+    @Override
+    public void updateNonExistent() {
     }
 
-    private String createIdentifier() {
-        long identifier = System.currentTimeMillis();
-        return Long.toString(identifier);
+    @Override
+    public void deleteNonExistent() {
     }
 }
index 63dea9bde66d7b168057379c8358f637d304bd23..0391baf5e85385a8c6877edc907754815eb82959 100644 (file)
  */
 package org.collectionspace.services.client.test;
 
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
+import java.io.ByteArrayInputStream;
 import java.util.ArrayList;
-import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
 import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
 import javax.xml.bind.Marshaller;
 
+import javax.xml.bind.Unmarshaller;
 import org.collectionspace.services.client.TestServiceClient;
-import org.collectionspace.services.client.test.ServiceRequestType;
 
 import org.jboss.resteasy.client.ClientRequest;
 import org.jboss.resteasy.client.ClientResponse;
 
+import org.jboss.resteasy.plugins.providers.multipart.InputPart;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -50,18 +51,14 @@ import org.slf4j.LoggerFactory;
 public abstract class AbstractServiceTest implements ServiceTest {
 
     final Logger logger = LoggerFactory.getLogger(AbstractServiceTest.class);
-
     // A base-level client, used (only) to obtain the base service URL.
     private static final TestServiceClient serviceClient = new TestServiceClient();
-
     // A resource identifier believed to be non-existent in actual use,
     // used when testing service calls that reference non-existent resources.
     protected final String NON_EXISTENT_ID = createNonExistentIdentifier();
-
     // The HTTP status code expected to be returned in the response,
     // from a request made to a service (where relevant).
     int EXPECTED_STATUS_CODE = 0;
-    
     // The generic type of service request being tested (e.g. CREATE, UPDATE, DELETE).
     //
     // This makes it possible to check behavior specific to that type of request,
@@ -69,31 +66,28 @@ public abstract class AbstractServiceTest implements ServiceTest {
     //
     // Note that the default value is set to a guard value.
     protected ServiceRequestType REQUEST_TYPE = ServiceRequestType.NON_EXISTENT;
-
     // Static data to be submitted in various tests
     protected final static String XML_DECLARATION =
-      "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
-
+            "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
     // Note: this constant is intentionally missing its last angle bracket.
     protected final static String MALFORMED_XML_DATA =
-      XML_DECLARATION +
-      "<malformed_xml>wrong schema contents</malformed_xml";
-
+            XML_DECLARATION +
+            "<malformed_xml>wrong schema contents</malformed_xml";
     protected final String WRONG_XML_SCHEMA_DATA =
-      XML_DECLARATION +
-      "<wrong_schema>wrong schema contents</wrong_schema>";
+            XML_DECLARATION +
+            "<wrong_schema>wrong schema contents</wrong_schema>";
 
     // ---------------------------------------------------------------
     // CRUD tests : CREATE tests
     // ---------------------------------------------------------------
-
     // Success outcomes
-
     @Override
-    public abstract void create();
-    
+    public void create() {
+        
+    }
+
     protected void setupCreate() {
-        clearSetup();
+        clearSetup("Create");
         // Expected status code: 201 Created
         EXPECTED_STATUS_CODE = Response.Status.CREATED.getStatusCode();
         // Type of service request being tested
@@ -102,16 +96,14 @@ public abstract class AbstractServiceTest implements ServiceTest {
 
     @Override
     public abstract void createList();
-    
-    // No setup required for createList()
 
+    // No setup required for createList()
     // Failure outcomes
-
     @Override
     public abstract void createWithEmptyEntityBody();
 
     protected void setupCreateWithEmptyEntityBody() {
-        clearSetup();
+        clearSetup("CreateWithEmptyEntityBody");
         EXPECTED_STATUS_CODE = Response.Status.BAD_REQUEST.getStatusCode();
         REQUEST_TYPE = ServiceRequestType.CREATE;
     }
@@ -120,7 +112,7 @@ public abstract class AbstractServiceTest implements ServiceTest {
     public abstract void createWithMalformedXml();
 
     protected void setupCreateWithMalformedXml() {
-        clearSetup();
+        clearSetup("CreateWithMalformedXml");
         // Expected status code: 400 Bad Request
         EXPECTED_STATUS_CODE = Response.Status.BAD_REQUEST.getStatusCode();
         REQUEST_TYPE = ServiceRequestType.CREATE;
@@ -130,87 +122,74 @@ public abstract class AbstractServiceTest implements ServiceTest {
     public abstract void createWithWrongXmlSchema();
 
     protected void setupCreateWithWrongXmlSchema() {
-        clearSetup();
+        clearSetup("CreateWithWrongXmlSchema");
         // Expected status code: 400 Bad Request
         EXPECTED_STATUS_CODE = Response.Status.BAD_REQUEST.getStatusCode();
         REQUEST_TYPE = ServiceRequestType.CREATE;
     }
 
-
     // ---------------------------------------------------------------
     // CRUD tests : READ tests
     // ---------------------------------------------------------------
-
     // Success outcomes
-    
     @Override
     public abstract void read();
 
     protected void setupRead() {
-        clearSetup();
+        clearSetup("Read");
         // Expected status code: 200 OK
         EXPECTED_STATUS_CODE = Response.Status.OK.getStatusCode();
         REQUEST_TYPE = ServiceRequestType.READ;
     }
 
     // Failure outcomes
-
     @Override
     public abstract void readNonExistent();
 
     protected void setupReadNonExistent() {
-        clearSetup();
+        clearSetup("ReadNonExistent");
         // Expected status code: 404 Not Found
         EXPECTED_STATUS_CODE = Response.Status.NOT_FOUND.getStatusCode();
         REQUEST_TYPE = ServiceRequestType.READ;
     }
 
-
     // ---------------------------------------------------------------
     // CRUD tests : READ (list, or multiple) tests
     // ---------------------------------------------------------------
-
     // Success outcomes
-
     @Override
     public abstract void readList();
 
     protected void setupReadList() {
-        clearSetup();
+        clearSetup("ReadList");
         // Expected status code: 200 OK
         EXPECTED_STATUS_CODE = Response.Status.OK.getStatusCode();
         REQUEST_TYPE = ServiceRequestType.READ_LIST;
     }
 
     // Failure outcomes
-
     // None tested at present.
-
-
     // ---------------------------------------------------------------
     // CRUD tests : UPDATE tests
     // ---------------------------------------------------------------
-
     // Success outcomes
     // ----------------
-
     @Override
     public abstract void update();
 
     protected void setupUpdate() {
-        clearSetup();
+        clearSetup("Update");
         // Expected status code: 200 OK
         EXPECTED_STATUS_CODE = Response.Status.OK.getStatusCode();
         REQUEST_TYPE = ServiceRequestType.UPDATE;
     }
 
     // Failure outcomes
-
     @Override
     public abstract void updateWithEmptyEntityBody();
 
     protected void setupUpdateWithEmptyEntityBody() {
-        clearSetup();
+        clearSetup("UpdateWithEmptyEntityBody");
         EXPECTED_STATUS_CODE = Response.Status.BAD_REQUEST.getStatusCode();
         REQUEST_TYPE = ServiceRequestType.UPDATE;
     }
@@ -219,7 +198,7 @@ public abstract class AbstractServiceTest implements ServiceTest {
     public abstract void updateWithMalformedXml();
 
     protected void setupUpdateWithMalformedXml() {
-        clearSetup();
+        clearSetup("UpdateWithMalformedXml");
         // Expected status code: 400 Bad Request
         EXPECTED_STATUS_CODE = Response.Status.BAD_REQUEST.getStatusCode();
         REQUEST_TYPE = ServiceRequestType.UPDATE;
@@ -229,7 +208,7 @@ public abstract class AbstractServiceTest implements ServiceTest {
     public abstract void updateWithWrongXmlSchema();
 
     protected void setupUpdateWithWrongXmlSchema() {
-        clearSetup();
+        clearSetup("UpdateWithWrongXmlSchema");
         // Expected status code: 400 Bad Request
         EXPECTED_STATUS_CODE = Response.Status.BAD_REQUEST.getStatusCode();
         REQUEST_TYPE = ServiceRequestType.UPDATE;
@@ -239,69 +218,70 @@ public abstract class AbstractServiceTest implements ServiceTest {
     public abstract void updateNonExistent();
 
     protected void setupUpdateNonExistent() {
-        clearSetup();
+        clearSetup("UpdateNonExistent");
         // Expected status code: 404 Not Found
         EXPECTED_STATUS_CODE = Response.Status.NOT_FOUND.getStatusCode();
         REQUEST_TYPE = ServiceRequestType.UPDATE;
     }
 
-
     // ---------------------------------------------------------------
     // CRUD tests : DELETE tests
     // ---------------------------------------------------------------
-
     // Success outcomes
-
     @Override
     public abstract void delete();
-    
+
     protected void setupDelete() {
-        clearSetup();
+        clearSetup("Delete");
         // Expected status code: 200 OK
         EXPECTED_STATUS_CODE = Response.Status.OK.getStatusCode();
         REQUEST_TYPE = ServiceRequestType.DELETE;
     }
-    
+
     // Failure outcomes
-    
     @Override
     public abstract void deleteNonExistent();
 
     protected void setupDeleteNonExistent() {
-        clearSetup();
+        clearSetup("DeleteNonExistent");
         // Expected status code: 404 Not Found
         EXPECTED_STATUS_CODE = Response.Status.NOT_FOUND.getStatusCode();
         REQUEST_TYPE = ServiceRequestType.DELETE;
     }
 
-
     // ---------------------------------------------------------------
     // Abstract utility methods
     //
     // Must be implemented by classes that extend
     // this abstract base class.
     // ---------------------------------------------------------------
-
     /**
      * Returns the URL path component of the service.
      *
      * This component will follow directly after the
      * base path, if any.
      */
-    protected abstract String getServicePathComponent();
+    @Override
+    public abstract String getServicePathComponent();
 
+    @Override
+    public String getCommonPartName() {
+        return getServicePathComponent() + "-common";
+    }
 
     // ---------------------------------------------------------------
     // Utility methods
     // ---------------------------------------------------------------
-
     /**
      * Reinitializes setup values, to help expose any unintended reuse
      * of those values between tests.
      */
-    protected void clearSetup() {
+    protected void clearSetup(String testName) {
         EXPECTED_STATUS_CODE = 0;
         REQUEST_TYPE = ServiceRequestType.NON_EXISTENT;
+        logger.debug("========================================================");
+        logger.debug(" Test = " + testName);
+        logger.debug("========================================================");
     }
 
     /**
@@ -317,11 +297,10 @@ public abstract class AbstractServiceTest implements ServiceTest {
      * @return An error message.
      */
     protected String invalidStatusCodeMessage(ServiceRequestType requestType, int statusCode) {
-        return 
-            "Status code '" + statusCode + "' in response is NOT within the expected set: " +
-            requestType.validStatusCodesAsString();
+        return "Status code '" + statusCode + "' in response is NOT within the expected set: " +
+                requestType.validStatusCodesAsString();
     }
-    
+
     /**
      * Returns the root URL for a service.
      *
@@ -330,7 +309,7 @@ public abstract class AbstractServiceTest implements ServiceTest {
      *
      * @return The root URL for a service.
      */
-     protected String getServiceRootURL() {
+    protected String getServiceRootURL() {
         return serviceClient.getBaseURL() + getServicePathComponent();
     }
 
@@ -359,24 +338,24 @@ public abstract class AbstractServiceTest implements ServiceTest {
      */
     protected int submitRequest(String method, String url) {
         int statusCode = 0;
-        try {
+        try{
             ClientRequest request = new ClientRequest(url);
-            if (method.equals(javax.ws.rs.HttpMethod.DELETE)) {
+            if(method.equals(javax.ws.rs.HttpMethod.DELETE)){
                 ClientResponse res = request.delete();
-                statusCode = res.getStatus(); 
-            } else if (method.equals(javax.ws.rs.HttpMethod.GET)) {
+                statusCode = res.getStatus();
+            }else if(method.equals(javax.ws.rs.HttpMethod.GET)){
                 ClientResponse res = request.get();
-                statusCode = res.getStatus(); 
-            } else {
+                statusCode = res.getStatus();
+            }else{
                 // Do nothing - leave status code at default value.
             }
-        } catch (Exception e) {
-            logger.error( 
-              "Exception during HTTP " + method + " request to " + url + ":",
-              e);
+        }catch(Exception e){
+            logger.error(
+                    "Exception during HTTP " + method + " request to " + url + ":",
+                    e);
         }
         return statusCode;
-   }
+    }
 
     /**
      * Submits an HTTP request to a specified URL, with the submitted
@@ -394,31 +373,29 @@ public abstract class AbstractServiceTest implements ServiceTest {
      * @return The status code received in the HTTP response.
      */
     protected int submitRequest(String method, String url,
-        String mediaType, String entityStr) {
+            String mediaType, String entityStr) {
         int statusCode = 0;
-        try {
+        try{
             ClientRequest request = new ClientRequest(url);
             request.body(mediaType, entityStr);
-            if (method.equals(javax.ws.rs.HttpMethod.POST)) {
+            if(method.equals(javax.ws.rs.HttpMethod.POST)){
                 ClientResponse res = request.post(java.lang.String.class);
-                statusCode = res.getStatus(); 
-            } else if (method.equals(javax.ws.rs.HttpMethod.PUT)) {
+                statusCode = res.getStatus();
+            }else if(method.equals(javax.ws.rs.HttpMethod.PUT)){
                 ClientResponse res = request.put(java.lang.String.class);
-                statusCode = res.getStatus(); 
-            } else {
+                statusCode = res.getStatus();
+            }else{
                 // Do nothing - leave status code at default value.
             }
-        } catch (Exception e) {
-            logger.error( 
-              "Exception during HTTP " + method + " request to " + url + ":",
-              e);
+        }catch(Exception e){
+            logger.error(
+                    "Exception during HTTP " + method + " request to " + url + ":",
+                    e);
         }
         return statusCode;
-    } 
+    }
 
     // @TODO Add Javadoc comments to all methods requiring them, below.
-
-
     protected String extractId(ClientResponse<Response> res) {
         MultivaluedMap mvm = res.getMetadata();
         String uri = (String) ((ArrayList) mvm.get("Location")).get(0);
@@ -430,7 +407,7 @@ public abstract class AbstractServiceTest implements ServiceTest {
     }
 
     protected void verbose(String msg) {
-        if (logger.isDebugEnabled()) {
+        if(logger.isDebugEnabled()){
             logger.debug(msg);
         }
     }
@@ -463,7 +440,40 @@ public abstract class AbstractServiceTest implements ServiceTest {
     protected String createNonExistentIdentifier() {
         return Long.toString(Long.MAX_VALUE);
     }
-    
+
+    protected Object extractPart(MultipartInput input, String label, Class clazz) throws Exception {
+        Object obj = null;
+        for(InputPart part : input.getParts()){
+            String partLabel = part.getHeaders().getFirst("label");
+            if(label.equalsIgnoreCase(partLabel)){
+                String partStr = part.getBodyAsString();
+                verbose("extracted part str=\n" + partStr);
+                obj = part.getBody(clazz, null);
+                verbose("extracted part obj=\n", obj, clazz);
+                break;
+            }
+        }
+        return obj;
+    }
+
+    protected Object getPartObject(String partStr, Class clazz) throws JAXBException {
+        JAXBContext jc = JAXBContext.newInstance(clazz);
+        ByteArrayInputStream bais = null;
+        Object obj = null;
+        try{
+            bais = new ByteArrayInputStream(partStr.getBytes());
+            Unmarshaller um = jc.createUnmarshaller();
+            obj = um.unmarshal(bais);
+        }finally{
+            if(bais != null){
+                try{
+                    bais.close();
+                }catch(Exception e){
+                }
+            }
+        }
+        return obj;
+    }
 }
 
 
index 8305cae342bd16d00de9e7ba2f801c4137879a5c..8f54216f82ea6fb33499c9e8404fed1d16e301f9 100644 (file)
@@ -29,6 +29,21 @@ package org.collectionspace.services.client.test;
  */
 public interface ServiceTest {
 
+
+    /**
+     * Returns the URL path component of the service.
+     *
+     * This component will follow directly after the
+     * base path, if any.
+     */
+    public String getServicePathComponent();
+
+    /**
+     * getCommonPartName get common part name for the service request
+     * @return
+     */
+    public String getCommonPartName();
+
     // ---------------------------------------------------------------
     // CRUD tests : CREATE tests
     // ---------------------------------------------------------------
@@ -40,7 +55,7 @@ public interface ServiceTest {
      *
      * Relied upon by 'read', 'update' and 'delete' tests, below.
      */
-    public void create(); 
+    public void create();
 
     /**
      * Tests creation of a list of two or more new resources by repeatedly
@@ -54,23 +69,23 @@ public interface ServiceTest {
 
     /**
      * Tests creation of a resource by submitting
-     * an empty entity body (aka empty payload). 
+     * an empty entity body (aka empty payload).
      */
     public void createWithEmptyEntityBody();
 
     /**
      * Tests creation of a resource by submitting
-     * a representation with malformed XML data. 
+     * a representation with malformed XML data.
      */
     public void createWithMalformedXml();
 
     /**
      * Tests creation of a resource by submitting
      * a representation in the wrong XML schema
-     * (e.g. not matching the object's schema). 
+     * (e.g. not matching the object's schema).
      */
     public void createWithWrongXmlSchema();
-        
+
     // @TODO If feasible, implement a negative (failure)
     // test for creation of duplicate resources.
 
@@ -80,9 +95,9 @@ public interface ServiceTest {
     // ---------------------------------------------------------------
 
     // Success outcomes
-    
+
     /**
-     * Tests reading (i.e. retrieval) of a resource. 
+     * Tests reading (i.e. retrieval) of a resource.
      */
     public void read();
 
@@ -93,7 +108,7 @@ public interface ServiceTest {
      * resource, whose resource identifier does not exist
      * at the specified URL.
      */
-    public void readNonExistent(); 
+    public void readNonExistent();
 
 
     // ---------------------------------------------------------------
@@ -106,13 +121,13 @@ public interface ServiceTest {
      * Tests reading (i.e. retrieval) of a list of
      * multiple resources.
      */
-    public void readList(); 
+    public void readList();
 
     // If feasible, implement a test for reading
     // an empty list returned by the service.
 
     // Failure outcomes
-    
+
     // If feasible, implement a negative (failure) test
     // of handling of unrecognized query parameters
     // (e.g. other than filtering or chunking parameters, etc.
@@ -126,7 +141,7 @@ public interface ServiceTest {
     // ----------------
 
     /**
-     * Tests updating the content of a resource. 
+     * Tests updating the content of a resource.
      */
     public void update();
 
@@ -139,16 +154,16 @@ public interface ServiceTest {
     public void updateWithEmptyEntityBody();
 
     /**
-     * Tests updating the content of a resource 
+     * Tests updating the content of a resource
      * by submitting a representation with malformed
-     * XML data. 
+     * XML data.
      */
     public void updateWithMalformedXml();
 
     /**
      * Tests updating the content of a resource
      * by submitting a representation in the wrong
-     * XML schema (e.g. not matching the object's schema). 
+     * XML schema (e.g. not matching the object's schema).
      */
     public void updateWithWrongXmlSchema();
 
@@ -168,16 +183,16 @@ public interface ServiceTest {
     /**
      * Tests deleting a resource.
      */
-    public void delete(); 
-    
+    public void delete();
+
     // Failure outcomes
-    
+
     /**
      * Tests deleting a non-existent resource, whose resource
      * identifier does not exist at the specified URL.
      */
     public void deleteNonExistent();
-    
+
 }
 
 
index 72aa5ef1968ac7dc8383ce137f3f3fab9f6c1b31..8ab4cb2e023a1ae89eb63faf973845c5807515ba 100644 (file)
@@ -1,13 +1,15 @@
 <?xml version="1.0"?>
 <component name="org.collectionspace.collectionobject.coreTypes">
-  <extension target="org.nuxeo.ecm.core.schema.TypeService" point="schema">
-    <schema name="collectionobject" prefix="collectionobject" src="schemas/collectionobject.xsd"/>
-  </extension>
-  <extension target="org.nuxeo.ecm.core.schema.TypeService" point="doctype">
-    <doctype name="CollectionObject" extends="Document">
-      <schema name="common"/>
-      <schema name="dublincore"/>
-      <schema name="collectionobject"/>
-    </doctype>
-  </extension>
+    <extension target="org.nuxeo.ecm.core.schema.TypeService" point="schema">
+        <schema name="collectionobjects-common" prefix="collectionobjects-common" src="schemas/collectionobjects-common.xsd"/>
+        <schema name="collectionobjects-naturalhistory" prefix="collectionobjects-naturalhistory" src="schemas/collectionobjects-naturalhistory.xsd"/>
+    </extension>
+    <extension target="org.nuxeo.ecm.core.schema.TypeService" point="doctype">
+        <doctype name="CollectionObject" extends="Document">
+            <schema name="common"/>
+            <schema name="dublincore"/>
+            <schema name="collectionobjects-common"/>
+            <schema name="collectionobjects-naturalhistory"/>
+        </doctype>
+    </extension>
 </component>
diff --git a/services/collectionobject/3rdparty/nuxeo-platform-cs-collectionobject/src/main/resources/schemas/collectionobjects-naturalhistory.xsd b/services/collectionobject/3rdparty/nuxeo-platform-cs-collectionobject/src/main/resources/schemas/collectionobjects-naturalhistory.xsd
new file mode 100644 (file)
index 0000000..25aceab
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r
+<xs:schema \r
+    xmlns:xs="http://www.w3.org/2001/XMLSchema"\r
+    xmlns:ns="http://collectionspace.org/collectionobject/"\r
+    xmlns="http://collectionspace.org/collectionobject/"\r
+    targetNamespace="http://collectionspace.org/collectionobject/"\r
+    version="0.1">\r
+\r
+    <xs:element name="nh-string" type="xs:string" />\r
+    <xs:element name="nh-int" type="xs:int"/>\r
+    <xs:element name="nh-long" type="xs:long"/>\r
+    <xs:element name="nh-date" type="xs:dateTime"/>\r
+    <xs:element name="nh-note" type="xs:string"/>\r
+    \r
+</xs:schema>\r
diff --git a/services/collectionobject/3rdparty/pom.xml~ b/services/collectionobject/3rdparty/pom.xml~
new file mode 100644 (file)
index 0000000..ce7ce10
--- /dev/null
@@ -0,0 +1,36 @@
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <artifactId>org.collectionspace.services.collectionobject</artifactId>
+        <groupId>org.collectionspace.services</groupId>
+        <version>1.0</version>
+    </parent>
+
+    <artifactId>org.collectionspace.services.collectionobject.doctype</artifactId>
+    <packaging>jar</packaging>
+    <name>collectionobject.doctype</name>
+    <description>
+    CollectionObject Nuxeo document type
+    </description>
+    <properties>
+        <nuxeo.version.5.2>5.2-SNAPSHOT</nuxeo.version.5.2>
+        <nuxeo.version.1.5>1.5-SNAPSHOT</nuxeo.version.1.5>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.nuxeo.ecm.core</groupId>
+            <artifactId>nuxeo-core-schema</artifactId>
+            <version>${nuxeo.version.1.5}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.nuxeo.ecm.platform</groupId>
+            <artifactId>nuxeo-platform-types-core</artifactId>
+            <version>${nuxeo.version.5.2}</version>
+        </dependency>
+    </dependencies>
+
+</project>
index ffa4ab470e160e69a2559f871a3e827146e76916..b9135886e1f996eeb0564f6907b7654169c4c365 100644 (file)
@@ -55,7 +55,7 @@
         <dependency>\r
             <groupId>org.jboss.resteasy</groupId>\r
             <artifactId>resteasy-jaxrs</artifactId>\r
-            <version>1.0.2.GA</version>\r
+            <version>1.1.GA</version>\r
             <!-- filter out unwanted jars -->\r
             <exclusions>\r
                 <exclusion>\r
         <dependency>\r
             <groupId>org.jboss.resteasy</groupId>\r
             <artifactId>resteasy-jaxb-provider</artifactId>\r
-            <version>1.0.2.GA</version>\r
+            <version>1.1.GA</version>\r
         </dependency>\r
         <dependency>\r
             <groupId>org.jboss.resteasy</groupId>\r
             <artifactId>resteasy-multipart-provider</artifactId>\r
-            <version>1.0.2.GA</version>\r
+            <version>1.1.GA</version>\r
         </dependency>\r
         <dependency>\r
             <groupId>commons-httpclient</groupId>\r
diff --git a/services/collectionobject/client/received.xml b/services/collectionobject/client/received.xml
new file mode 100644 (file)
index 0000000..f8d8382
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<collectionobjects-common xmlns="http://collectionspace.org/services/collectionobject" xmlns:collectionobjects-common="http://collectionspace.org/services/collectionobject" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://collectionspace.org/services/collectionobject http://services.collectionspace.org/collectionobject/collectionobjects-common.xsd">\r
+<collectionobjects-common:objectNumber>objectNumber-1252961305700</collectionobjects-common:objectNumber>\r
+<collectionobjects-common:objectName>objectName-1252961305700</collectionobjects-common:objectName>\r
+</collectionobjects-common>\r
diff --git a/services/collectionobject/client/received.xml~ b/services/collectionobject/client/received.xml~
new file mode 100644 (file)
index 0000000..f69b0eb
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<collectionobjects-common xmlns="http://collectionspace.org/services/collectiono\r
+bject">\r
+<objectNumber>objectNumber-1252960223850</objectNumber>\r
+<objectName>objectName-1252960223850</objectName>\r
+</collectionobjects-common>\r
diff --git a/services/collectionobject/client/sent.xml b/services/collectionobject/client/sent.xml
new file mode 100644 (file)
index 0000000..eace94d
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r
+<ns2:collectionobjects-common xmlns:ns2="http://collectionspace.org/services/collectionobject">\r
+<objectNumber>objectNumber-1252960222412</objectNumber>\r
+<objectName>objectName-1252960222412</objectName>\r
+</ns2:collectionobjects-common>\r
+\r
diff --git a/services/collectionobject/client/sent.xml~ b/services/collectionobject/client/sent.xml~
new file mode 100644 (file)
index 0000000..d698276
--- /dev/null
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"\r
+      standalone="yes"?><ns2:collectionobjects-common xmlns:ns2="http://collectionspace.org/services/collectionobject"><objectNumber>objectNumber-1252960222412</objectNumber><objectName>objectName-1252960222412</objectName></ns2:collectionobjects-common>\r
+\r
index c44e452b995dd5373d88926c818e46826896b5b9..ea9c5b865bf1afcb1b9d0032026e4fc45dcc43fc 100644 (file)
@@ -2,12 +2,13 @@ package org.collectionspace.services.client;
 
 import javax.ws.rs.core.Response;
 
-import org.collectionspace.services.collectionobject.CollectionObject;
-import org.collectionspace.services.collectionobject.CollectionObjectList;
 
+import org.collectionspace.services.collectionobject.CollectionobjectsCommonList;
 import org.jboss.resteasy.client.ProxyFactory;
 import org.jboss.resteasy.plugins.providers.RegisterBuiltin;
 import org.jboss.resteasy.client.ClientResponse;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
 import org.jboss.resteasy.spi.ResteasyProviderFactory;
 
 /**
@@ -48,10 +49,11 @@ public class CollectionObjectClient extends BaseServiceClient {
 
     /**
      * @return
-     * @see org.collectionspace.hello.client.CollectionObjectProxy#getCollectionObject()
+     * @see org.collectionspace.hello.client.CollectionObjectProxy#readList()
      */
-    public ClientResponse<CollectionObjectList> readList() {
+    public ClientResponse<CollectionobjectsCommonList> readList() {
         return collectionObjectProxy.readList();
+
     }
 
     /**
@@ -59,27 +61,27 @@ public class CollectionObjectClient extends BaseServiceClient {
      * @return
      * @see org.collectionspace.hello.client.CollectionObjectProxy#getCollectionObject(java.lang.String)
      */
-    public ClientResponse<CollectionObject> read(String csid) {
+    public ClientResponse<MultipartInput> read(String csid) {
         return collectionObjectProxy.read(csid);
     }
 
     /**
      * @param collectionobject
      * @return
-     * @see org.collectionspace.hello.client.CollectionObjectProxy#createCollectionObject(org.collectionspace.hello.CollectionObject)
+     * @see org.collectionspace.hello.client.CollectionObjectProxy#create(org.collectionspace.services.collectionobject.CollectionobjectsCommon)
      */
-    public ClientResponse<Response> create(CollectionObject collectionObject) {
-        return collectionObjectProxy.create(collectionObject);
+    public ClientResponse<Response> create(MultipartOutput multipart) {
+        return collectionObjectProxy.create(multipart);
     }
 
     /**
      * @param csid
      * @param collectionobject
      * @return
-     * @see org.collectionspace.hello.client.CollectionObjectProxy#updateCollectionObject(java.lang.Long, org.collectionspace.hello.CollectionObject)
+     * @see org.collectionspace.hello.client.CollectionObjectProxy#updateCollectionObject(java.lang.Long, org.collectionspace.services.collectionobject.CollectionobjectsCommon)
      */
-    public ClientResponse<CollectionObject> update(String csid, CollectionObject collectionObject) {
-        return collectionObjectProxy.update(csid, collectionObject);
+    public ClientResponse<MultipartInput> update(String csid, MultipartOutput multipart) {
+        return collectionObjectProxy.update(csid, multipart);
     }
 
     /**
index a324f1cc0ecb9b8803ae3c7a537cde0511c6eb58..e6fcb8ec1652a05051d19d1575392caf6b21bf83 100644 (file)
@@ -10,37 +10,40 @@ import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.Response;
 
-import org.collectionspace.services.collectionobject.CollectionObject;
-import org.collectionspace.services.collectionobject.CollectionObjectList;
+import org.collectionspace.services.collectionobject.CollectionobjectsCommonList;
 import org.jboss.resteasy.client.ClientResponse;
 
+import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
+
 /**
  * @version $Revision:$
  */
 @Path("/collectionobjects/")
-@Produces({"application/xml"})
-@Consumes({"application/xml"})
+@Produces({"multipart/mixed"})
+@Consumes({"multipart/mixed"})
 public interface CollectionObjectProxy {
 
     @GET
-    ClientResponse<CollectionObjectList> readList();
+    @Produces({"application/xml"})
+    ClientResponse<CollectionobjectsCommonList> readList();
 
     //(C)reate
     @POST
-    ClientResponse<Response> create(CollectionObject co);
+    ClientResponse<Response> create(MultipartOutput multipart);
 
     //(R)ead
     @GET
     @Path("/{csid}")
-    ClientResponse<CollectionObject> read(@PathParam("csid") String csid);
+    ClientResponse<MultipartInput> read(@PathParam("csid") String csid);
 
     //(U)pdate
     @PUT
     @Path("/{csid}")
-    ClientResponse<CollectionObject> update(@PathParam("csid") String csid, CollectionObject co);
+    ClientResponse<MultipartInput> update(@PathParam("csid") String csid, MultipartOutput multipart);
 
     //(D)elete
     @DELETE
     @Path("/{csid}")
     ClientResponse<Response> delete(@PathParam("csid") String csid);
-}
\ No newline at end of file
+}
index 8ea4c8488b9ba2ce807bf4b689bc702ddd06b421..a8e4999057b2d96587e38f7723047faa66fbaef1 100644 (file)
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 package org.collectionspace.services.client.test;
 
 import java.util.List;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
 
 import org.collectionspace.services.client.CollectionObjectClient;
-import org.collectionspace.services.client.test.ServiceRequestType;
-import org.collectionspace.services.collectionobject.CollectionObject;
-import org.collectionspace.services.collectionobject.CollectionObjectList;
+import org.collectionspace.services.collectionobject.CollectionobjectsCommon;
+import org.collectionspace.services.collectionobject.domain.naturalhistory.CollectionObjectNaturalhistory;
+import org.collectionspace.services.collectionobject.CollectionobjectsCommonList;
 
 import org.jboss.resteasy.client.ClientResponse;
 
+import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
+import org.jboss.resteasy.plugins.providers.multipart.OutputPart;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
@@ -51,13 +52,11 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
     private CollectionObjectClient client = new CollectionObjectClient();
     final String SERVICE_PATH_COMPONENT = "collectionobjects";
     private String knownResourceId = null; 
+    
     // ---------------------------------------------------------------
     // CRUD tests : CREATE tests
     // ---------------------------------------------------------------
-
     // Success outcomes
-    
     @Override
     @Test
     public void create() {
@@ -69,9 +68,10 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
 
         // Submit the request to the service and store the response.
         String identifier = createIdentifier();
-        CollectionObject collectionObject =
-          createCollectionObjectInstance(identifier);
-        ClientResponse<Response> res = client.create(collectionObject);
+
+        MultipartOutput multipart = createCollectionObjectInstance(identifier);
+        ClientResponse<Response> res = client.create(multipart);
+
         int statusCode = res.getStatus();
 
         // Check the status code of the response: does it match
@@ -82,12 +82,13 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
         // Does it exactly match the expected status code?
         verbose("create: status = " + statusCode);
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
 
         // Store the ID returned from this create operation
         // for additional tests below.
         knownResourceId = extractId(res);
+        verbose("create: knownResourceId=" + knownResourceId);
     }
 
     @Override
@@ -99,7 +100,6 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
     }
 
     // Failure outcomes
-
     // Placeholders until the three tests below can be uncommented.
     // See Issue CSPACE-401.
     public void createWithEmptyEntityBody() {}
@@ -177,26 +177,33 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
     // ---------------------------------------------------------------
     // CRUD tests : READ tests
     // ---------------------------------------------------------------
-
     // Success outcomes
-
     @Override
     @Test(dependsOnMethods = {"create"})
     public void read() {
-    
+
         // Perform setup.
         setupRead();
 
         // Submit the request to the service and store the response.
-        ClientResponse<CollectionObject> res = client.read(knownResourceId);
+        ClientResponse<MultipartInput> res = client.read(knownResourceId);
         int statusCode = res.getStatus();
-            
+
         // Check the status code of the response: does it match
         // the expected response(s)?
         verbose("read: status = " + statusCode);
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+        //FIXME: remove the following try catch once Aron fixes signatures
+        try{
+            MultipartInput input = (MultipartInput) res.getEntity();
+            CollectionobjectsCommon collectionObject = (CollectionobjectsCommon) extractPart(input,
+                    getCommonPartName(), CollectionobjectsCommon.class);
+            Assert.assertNotNull(collectionObject);
+        }catch(Exception e){
+            throw new RuntimeException(e);
+        }
     }
     
     // Failure outcomes
@@ -207,52 +214,50 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
 
         // Perform setup.
         setupReadNonExistent();
-        
+
         // Submit the request to the service and store the response.
-        ClientResponse<CollectionObject> res = client.read(NON_EXISTENT_ID);
+        ClientResponse<MultipartInput> res = client.read(NON_EXISTENT_ID);
         int statusCode = res.getStatus();
 
         // Check the status code of the response: does it match
         // the expected response(s)?
         verbose("readNonExistent: status = " + res.getStatus());
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
     }
 
-
     // ---------------------------------------------------------------
     // CRUD tests : READ_LIST tests
     // ---------------------------------------------------------------
-
     // Success outcomes
-
     @Override
-    @Test(dependsOnMethods = {"createList"})
+    @Test(dependsOnMethods = {"createList", "read"})
     public void readList() {
-    
         // Perform setup.
         setupReadList();
 
         // Submit the request to the service and store the response.
-        ClientResponse<CollectionObjectList> res = client.readList();
-        CollectionObjectList list = res.getEntity();
+        ClientResponse<CollectionobjectsCommonList> res = client.readList();
+        CollectionobjectsCommonList list = res.getEntity();
+
         int statusCode = res.getStatus();
 
         // Check the status code of the response: does it match
         // the expected response(s)?
         verbose("readList: status = " + res.getStatus());
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
 
         // Optionally output additional data about list members for debugging.
         boolean iterateThroughList = false;
         if (iterateThroughList && logger.isDebugEnabled()) {
-            List<CollectionObjectList.CollectionObjectListItem> items =
+            List<CollectionobjectsCommonList.CollectionObjectListItem> items =
                 list.getCollectionObjectListItem();
             int i = 0;
-            for(CollectionObjectList.CollectionObjectListItem item : items){
+
+            for(CollectionobjectsCommonList.CollectionObjectListItem item : items){
                 verbose("readList: list-item[" + i + "] csid=" +
                     item.getCsid());
                 verbose("readList: list-item[" + i + "] objectNumber=" +
@@ -262,59 +267,63 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
                 i++;
             }
         }
-        
     }
 
     // Failure outcomes
-    
     // None at present.
-
-
     // ---------------------------------------------------------------
     // CRUD tests : UPDATE tests
     // ---------------------------------------------------------------
-
     // Success outcomes
-
     @Override
-    @Test(dependsOnMethods = {"create"})
+    @Test(dependsOnMethods = {"read"})
     public void update() {
-    
+
         // Perform setup.
         setupUpdate();
-
-        // Retrieve an existing resource that we can update.
-        ClientResponse<CollectionObject> res = client.read(knownResourceId);
-        verbose("read: status = " + res.getStatus());
-        Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
-        CollectionObject collectionObject = res.getEntity();
-        verbose("Got object to update with ID: " + knownResourceId,
-                collectionObject, CollectionObject.class);
-
-        // Update the content of this resource.
-        collectionObject.setObjectNumber("updated-" +
-          collectionObject.getObjectNumber());
-        collectionObject.setObjectName("updated-" +
-          collectionObject.getObjectName());
-
-        // Submit the request to the service and store the response.
-        res = client.update(knownResourceId, collectionObject);
-        int statusCode = res.getStatus();
-
-        // Check the status code of the response: does it match
-        // the expected response(s)?
-        verbose("update: status = " + res.getStatus());
-        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
-        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
-        
-        // Check the contents of the response: does it match
-        // what was submitted?
-        CollectionObject updatedObject = res.getEntity();
-        verbose("update: ", updatedObject, CollectionObject.class);
-        Assert.assertEquals(updatedObject.getObjectName(), 
-            collectionObject.getObjectName(), 
-            "Data in updated object did not match submitted data.");
+        try{ //ideally, just remove try-catch and let the exception bubble up
+            // Retrieve an existing resource that we can update.
+            ClientResponse<MultipartInput> res =
+                    client.read(knownResourceId);
+            verbose("update: read status = " + res.getStatus());
+            Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
+
+            verbose("got object to update with ID: " + knownResourceId);
+            MultipartInput input = (MultipartInput) res.getEntity();
+            CollectionobjectsCommon collectionObject = (CollectionobjectsCommon) extractPart(input,
+                    getCommonPartName(), CollectionobjectsCommon.class);
+            Assert.assertNotNull(collectionObject);
+
+            // Update the content of this resource.
+            collectionObject.setObjectNumber("updated-" + collectionObject.getObjectNumber());
+            collectionObject.setObjectName("updated-" + collectionObject.getObjectName());
+            verbose("updated object", collectionObject, CollectionobjectsCommon.class);
+            // Submit the request to the service and store the response.
+            MultipartOutput output = new MultipartOutput();
+            OutputPart commonPart = output.addPart(collectionObject, MediaType.APPLICATION_XML_TYPE);
+            commonPart.getHeaders().add("label", getCommonPartName());
+
+            res = client.update(knownResourceId, output);
+            int statusCode = res.getStatus();
+            // Check the status code of the response: does it match the expected response(s)?
+            verbose("update: status = " + res.getStatus());
+            Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+                    invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+            Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+
+
+            input = (MultipartInput) res.getEntity();
+            CollectionobjectsCommon updatedCollectionObject =
+                    (CollectionobjectsCommon) extractPart(input,
+                    getCommonPartName(), CollectionobjectsCommon.class);
+            Assert.assertNotNull(updatedCollectionObject);
+
+            Assert.assertEquals(updatedCollectionObject.getObjectName(),
+                    collectionObject.getObjectName(),
+                    "Data in updated object did not match submitted data.");
+        }catch(Exception e){
+            e.printStackTrace();
+        }
     }
     
     // Failure outcomes
@@ -327,6 +336,7 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
 
 /*
     @Override
+
     @Test(dependsOnMethods = {"create", "update", "testSubmitRequest"})
     public void updateWithEmptyEntityBody() {
     
@@ -402,29 +412,28 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
 
         // Submit the request to the service and store the response.
         // Note: The ID used in this 'create' call may be arbitrary.
-        // The only relevant ID may be the one used in update(), below.
-        CollectionObject collectionObject = createCollectionObjectInstance(NON_EXISTENT_ID);
-        ClientResponse<CollectionObject> res =
-          client.update(NON_EXISTENT_ID, collectionObject);
+
+        // The only relevant ID may be the one used in updateCollectionObject(), below.
+        MultipartOutput multipart = createCollectionObjectInstance(NON_EXISTENT_ID);
+        ClientResponse<MultipartInput> res =
+                client.update(NON_EXISTENT_ID, multipart);
+
         int statusCode = res.getStatus();
 
         // Check the status code of the response: does it match
         // the expected response(s)?
         verbose("updateNonExistent: status = " + res.getStatus());
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
     }
 
     // ---------------------------------------------------------------
     // CRUD tests : DELETE tests
     // ---------------------------------------------------------------
-
     // Success outcomes
-
     @Override
-    @Test(dependsOnMethods = 
-        {"create", "read", "update"})
+    @Test(dependsOnMethods = {"create", "readList", "testSubmitRequest", "update"})
     public void delete() {
 
         // Perform setup.
@@ -438,12 +447,11 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
         // the expected response(s)?
         verbose("delete: status = " + res.getStatus());
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
     }
 
     // Failure outcomes
-
     @Override
     @Test(dependsOnMethods = {"delete"})
     public void deleteNonExistent() {
@@ -459,15 +467,13 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
         // the expected response(s)?
         verbose("deleteNonExistent: status = " + res.getStatus());
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
     }
 
-
     // ---------------------------------------------------------------
     // Utility tests : tests of code used in tests above
     // ---------------------------------------------------------------
-
     /**
      * Tests the code for manually submitting data that is used by several
      * of the methods above.
@@ -482,7 +488,7 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
         String method = ServiceRequestType.READ.httpMethodName();
         String url = getResourceURL(knownResourceId);
         int statusCode = submitRequest(method, url);
-        
+
         // Check the status code of the response: does it match
         // the expected response(s)?
         verbose("testSubmitRequest: url=" + url + " status=" + statusCode);
@@ -493,7 +499,6 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
     // ---------------------------------------------------------------
     // Utility methods used by tests above
     // ---------------------------------------------------------------
-
     @Override
     public String getServicePathComponent() {
         // @TODO Determine if it is possible to obtain this
@@ -505,22 +510,36 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
         // return this value.
         return SERVICE_PATH_COMPONENT;
     }
-    
-    private CollectionObject createCollectionObjectInstance(String identifier) {
-        CollectionObject collectionObject =
-          createCollectionObjectInstance(
-              "objectNumber-" + identifier,
-              "objectName-" + identifier);
-        return collectionObject;
+
+    private MultipartOutput createCollectionObjectInstance(String identifier) {
+        return createCollectionObjectInstance("objectNumber-" + identifier,
+                "objectName-" + identifier);
     }
 
-    private CollectionObject createCollectionObjectInstance(
-      String objectNumber, String objectName) {
-        CollectionObject collectionObject = new CollectionObject();
+    private MultipartOutput createCollectionObjectInstance(String objectNumber, String objectName) {
+        CollectionobjectsCommon collectionObject = new CollectionobjectsCommon();
+
         collectionObject.setObjectNumber(objectNumber);
         collectionObject.setObjectName(objectName);
-        return collectionObject;
+        MultipartOutput multipart = new MultipartOutput();
+        OutputPart commonPart = multipart.addPart(collectionObject, MediaType.APPLICATION_XML_TYPE);
+        commonPart.getHeaders().add("label", getCommonPartName());
+
+        verbose("to be created, collectionobject common ", collectionObject, CollectionobjectsCommon.class);
+
+        CollectionObjectNaturalhistory conh = new CollectionObjectNaturalhistory();
+        conh.setNhString("test-string");
+        conh.setNhInt(999);
+        conh.setNhLong(9999);
+        OutputPart nhPart = multipart.addPart(conh, MediaType.APPLICATION_XML_TYPE);
+        nhPart.getHeaders().add("label", getNHPartName());
+
+        verbose("to be created, collectionobject nhistory", conh, CollectionObjectNaturalhistory.class);
+        return multipart;
+
+    }
+
+    private String getNHPartName() {
+        return "collectionobjects-naturalhistory";
     }
-    
-    
 }
diff --git a/services/collectionobject/client/test.xml b/services/collectionobject/client/test.xml
new file mode 100644 (file)
index 0000000..b407eab
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<collectionobjects-common xmlns="http://collectionspace.org/services/collectiono\r
+bject" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=\r
+"http://collectionspace.org/services/collectionobject http://services.collection\r
+space.org/collectionobject/collectionobjects-common.xsd">\r
+<objectNumber>objectNumber-1252955075364</objectNumber>\r
+<objectName>objectName-1252955075364</objectName>\r
+</collectionobjects-common>\r
index 15d479b37be09f30d1b65dc16761850256a9e103..6dd085c3f3f143b8504817955753c8840cde873b 100644 (file)
@@ -56,7 +56,7 @@
                     <dependency>
                         <groupId>com.sun.xml.bind</groupId>
                         <artifactId>jaxb-impl</artifactId>
-                        <version>2.1.2</version>
+                        <version>2.1.9</version>
                     </dependency>
                 </dependencies>
                 <configuration>
similarity index 57%
rename from services/collectionobject/jaxb/src/main/resources/collectionobject.xsd
rename to services/collectionobject/jaxb/src/main/resources/collectionobjects-common.xsd
index bb9575e8bf67abb1af9dee0b74f9c17bef112ab9..e34e35ce9154c75e52fa78bf447dab03e22f44bd 100644 (file)
@@ -1,33 +1,34 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <xs:schema 
   xmlns:xs="http://www.w3.org/2001/XMLSchema"
-  xmlns:ns="http://collectionspace.org/collectionobject"
-  xmlns="http://collectionspace.org/collectionobject"
-  targetNamespace="http://services.collectionspace.org/collectionobject"
+  xmlns:ns="http://collectionspace.org/servics/collectionobject"
+  xmlns="http://collectionspace.org/services/collectionobject"
+  targetNamespace="http://collectionspace.org/services/collectionobject"
   version="0.1"
 >
 
 <!-- avoid XmlRootElement nightnmare, see http://weblogs.java.net/blog/kohsuke/archive/2006/03/why_does_jaxb_p.html-->
-        
-    <!-- collection-object  -->
-    <xs:element name="collection-object">
+
+    <!-- collectionobjects-common -->
+    <!-- convention: <servicename>-common  -->
+    <xs:element name="collectionobjects-common">
         <xs:complexType>
             <xs:sequence>
-                           <xs:element name="csid" type="xs:string" />
-                           <xs:element name="objectNumber" type="xs:string"/>
-                           <xs:element name="otherNumber" type="xs:string"/>
-                           <xs:element name="briefDescription" type="xs:string"/>
-                           <xs:element name="comments" type="xs:string"/>
-                           <xs:element name="distFeatures" type="xs:string"/>
-                           <xs:element name="objectName" type="xs:string"/>
-                           <xs:element name="responsibleDept" type="xs:string"/>
-                           <xs:element name="title" type="xs:string"/>
+                <xs:element name="csid" type="xs:string" />
+                <xs:element name="objectNumber" type="xs:string"/>
+                <xs:element name="otherNumber" type="xs:string"/>
+                <xs:element name="briefDescription" type="xs:string"/>
+                <xs:element name="comments" type="xs:string"/>
+                <xs:element name="distFeatures" type="xs:string"/>
+                <xs:element name="objectName" type="xs:string"/>
+                <xs:element name="responsibleDept" type="xs:string"/>
+                <xs:element name="title" type="xs:string"/>
             </xs:sequence>
         </xs:complexType>
     </xs:element>
     
     <!-- collection objects as in nuxeo repository -->
-    <xs:element name="collection-object-list">
+    <xs:element name="collectionobjects-common-list">
         <xs:complexType>
             <xs:sequence>
                 <xs:element name="collection-object-list-item" maxOccurs="unbounded">
diff --git a/services/collectionobject/jaxb/src/main/resources/collectionobjects-naturalhistory.xsd b/services/collectionobject/jaxb/src/main/resources/collectionobjects-naturalhistory.xsd
new file mode 100644 (file)
index 0000000..f066192
--- /dev/null
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+    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
+
+    Document   : collectionobject-naturalhistory.xsd
+    Revision   : $LastChangedRevision: $
+    Created on : $LastChangedDate: $
+    Author     : $LastChangedBy: $
+    Description:
+-->
+<xs:schema 
+  xmlns:xs="http://www.w3.org/2001/XMLSchema"
+  xmlns:ns="http://collectionspace.org/services/collectionobject/domain/naturalhistory"
+  xmlns="http://collectionspace.org/services/collectionobject/domain/naturalhistory"
+  targetNamespace="http://collectionspace.org/services/collectionobject/domain/naturalhistory"
+  version="0.1"
+>
+    <!-- collection-object for museum of natural history  -->
+    <xs:element name="collection-object-naturalhistory">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="nh-string" type="xs:string" />
+                <xs:element name="nh-int" type="xs:int"/>
+                <xs:element name="nh-long" type="xs:long"/>
+                <xs:element name="nh-date" type="xs:dateTime"/>
+                <xs:element name="nh-note" type="xs:string"/>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+    
+</xs:schema>
+
index 4be97215e0373d7ba6b4d5f51406cd6355a599dd..e4ddeb6194e69059dec96fd884f9df8c3808e93f 100644 (file)
@@ -80,7 +80,7 @@
         <dependency>\r
             <groupId>org.jboss.resteasy</groupId>\r
             <artifactId>resteasy-jaxrs</artifactId>\r
-            <version>1.0.2.GA</version>\r
+            <version>1.1.GA</version>\r
             <exclusions>\r
                 <exclusion>\r
                     <groupId>tjws</groupId>\r
         <dependency>\r
             <groupId>org.jboss.resteasy</groupId>\r
             <artifactId>resteasy-jaxb-provider</artifactId>\r
-            <version>1.0.2.GA</version>\r
+            <version>1.1.GA</version>\r
         </dependency>\r
         <dependency>\r
             <groupId>org.jboss.resteasy</groupId>\r
             <artifactId>resteasy-multipart-provider</artifactId>\r
-            <version>1.0.2.GA</version>\r
+            <version>1.1.GA</version>\r
         </dependency>\r
         \r
         <!-- nuxeo -->\r
index cff244d51ba0959df432b5ad9dba83aa9fc0a4da..4a9d5930ed8a5300d818512a9909f47041d9841f 100644 (file)
@@ -1,3 +1,26 @@
+/**
+ *  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;
 
 import javax.ws.rs.Consumes;
@@ -13,53 +36,53 @@ 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.AbstractCollectionSpaceResource;
+import org.collectionspace.services.common.context.ServiceContext;
 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.plugins.providers.multipart.MultipartInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
 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 {
+@Consumes("multipart/mixed")
+@Produces("multipart/mixed")
+public class CollectionObjectResource
+        extends AbstractCollectionSpaceResource {
 
-    public final static String CO_SERVICE_NAME = "collectionobjects";
+    final private String serviceName = "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
+    @Override
+    public String getServiceName() {
+        return serviceName;
     }
 
-    @POST
-    public Response createCollectionObject(
-            CollectionObject collectionObject) {
+    @Override
+    public DocumentHandler createDocumentHandler(ServiceContext ctx) throws Exception {
+        DocumentHandler docHandler = CollectionObjectHandlerFactory.getInstance().getHandler(
+                ctx.getRepositoryClientType().toString());
+        docHandler.setServiceContext(ctx);
+        if(ctx.getInput() != null){
+            Object obj = ctx.getInputPart(ctx.getCommonPartLabel(), CollectionobjectsCommon.class);
+            if(obj != null){
+                docHandler.setCommonPart((CollectionobjectsCommon) obj);
+            }
+        }
+        return docHandler;
+    }
 
-        String csid = null;
+    @POST
+    public Response createCollectionObject(MultipartInput input) {
         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(collectionObject);
-            csid = client.create(CO_SERVICE_NAME, handler);
-            collectionObject.setCsid(csid);
-            if(logger.isDebugEnabled()){
-                verbose("createCollectionObject: ", collectionObject);
-            }
+            ServiceContext ctx = createServiceContext(input);
+            DocumentHandler handler = createDocumentHandler(ctx);
+            String csid = getRepositoryClient(ctx).create(ctx, handler);
             UriBuilder path = UriBuilder.fromResource(CollectionObjectResource.class);
             path.path("" + csid);
             Response response = Response.created(path.build()).build();
@@ -76,10 +99,10 @@ public class CollectionObjectResource {
 
     @GET
     @Path("{csid}")
-    public CollectionObject getCollectionObject(
+    public MultipartOutput getCollectionObject(
             @PathParam("csid") String csid) {
         if(logger.isDebugEnabled()){
-            verbose("getCollectionObject with csid=" + csid);
+            logger.debug("getCollectionObject with csid=" + csid);
         }
         if(csid == null || "".equals(csid)){
             logger.error("getCollectionObject: missing csid!");
@@ -88,14 +111,12 @@ public class CollectionObjectResource {
                     "text/plain").build();
             throw new WebApplicationException(response);
         }
-        CollectionObject collectionObject = null;
+        MultipartOutput result = 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);
-            collectionObject = (CollectionObject) handler.getCommonObject();
+            ServiceContext ctx = createServiceContext(null);
+            DocumentHandler handler = createDocumentHandler(ctx);
+            getRepositoryClient(ctx).get(ctx, csid, handler);
+            result = ctx.getOutput();
         }catch(DocumentNotFoundException dnfe){
             if(logger.isDebugEnabled()){
                 logger.debug("getCollectionObject", dnfe);
@@ -113,28 +134,24 @@ public class CollectionObjectResource {
             throw new WebApplicationException(response);
         }
 
-        if(collectionObject == null){
+        if(result == 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: ", collectionObject);
-        }
-        return collectionObject;
+        return result;
     }
 
     @GET
-    public CollectionObjectList getCollectionObjectList(@Context UriInfo ui) {
-        CollectionObjectList collectionObjectList = new CollectionObjectList();
+    @Produces("application/xml")
+    public CollectionobjectsCommonList getCollectionObjectList(@Context UriInfo ui) {
+        CollectionobjectsCommonList collectionObjectList = new CollectionobjectsCommonList();
         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);
-            collectionObjectList = (CollectionObjectList) handler.getCommonObjectList();
+            ServiceContext ctx = createServiceContext(null);
+            DocumentHandler handler = createDocumentHandler(ctx);
+            getRepositoryClient(ctx).getAll(ctx, handler);
+            collectionObjectList = (CollectionobjectsCommonList) handler.getCommonPartList();
         }catch(Exception e){
             if(logger.isDebugEnabled()){
                 logger.debug("Caught exception in getCollectionObjectList", e);
@@ -148,11 +165,11 @@ public class CollectionObjectResource {
 
     @PUT
     @Path("{csid}")
-    public CollectionObject updateCollectionObject(
+    public MultipartOutput updateCollectionObject(
             @PathParam("csid") String csid,
-            CollectionObject theUpdate) {
+            MultipartInput theUpdate) {
         if(logger.isDebugEnabled()){
-            verbose("updateCollectionObject with csid=" + csid);
+            logger.debug("updateCollectionObject with csid=" + csid);
         }
         if(csid == null || "".equals(csid)){
             logger.error("updateCollectionObject: missing csid!");
@@ -161,16 +178,12 @@ public class CollectionObjectResource {
                     "text/plain").build();
             throw new WebApplicationException(response);
         }
-        if(logger.isDebugEnabled()){
-            verbose("updateCollectionObject with input: ", theUpdate);
-        }
+        MultipartOutput result = 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(theUpdate);
-            client.update(csid, handler);
+            ServiceContext ctx = createServiceContext(theUpdate);
+            DocumentHandler handler = createDocumentHandler(ctx);
+            getRepositoryClient(ctx).update(ctx, csid, handler);
+            result = ctx.getOutput();
         }catch(DocumentNotFoundException dnfe){
             if(logger.isDebugEnabled()){
                 logger.debug("caugth exception in updateCollectionObject", dnfe);
@@ -184,7 +197,7 @@ public class CollectionObjectResource {
                     Response.Status.INTERNAL_SERVER_ERROR).entity("Update failed").type("text/plain").build();
             throw new WebApplicationException(response);
         }
-        return theUpdate;
+        return result;
     }
 
     @DELETE
@@ -192,7 +205,7 @@ public class CollectionObjectResource {
     public Response deleteCollectionObject(@PathParam("csid") String csid) {
 
         if(logger.isDebugEnabled()){
-            verbose("deleteCollectionObject with csid=" + csid);
+            logger.debug("deleteCollectionObject with csid=" + csid);
         }
         if(csid == null || "".equals(csid)){
             logger.error("deleteCollectionObject: missing csid!");
@@ -202,9 +215,8 @@ public class CollectionObjectResource {
             throw new WebApplicationException(response);
         }
         try{
-            RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
-            RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
-            client.delete(csid);
+            ServiceContext ctx = createServiceContext(null);
+            getRepositoryClient(ctx).delete(ctx, csid);
             return Response.status(HttpResponseCodes.SC_OK).build();
         }catch(DocumentNotFoundException dnfe){
             if(logger.isDebugEnabled()){
@@ -221,23 +233,4 @@ public class CollectionObjectResource {
         }
 
     }
-
-    private void verbose(String msg, CollectionObject collectionObject) {
-        try{
-            verbose(msg);
-            JAXBContext jc = JAXBContext.newInstance(
-                    CollectionObject.class);
-
-            Marshaller m = jc.createMarshaller();
-            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
-            m.marshal(collectionObject, 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/CollectionObjectService.java b/services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/CollectionObjectService.java
deleted file mode 100644 (file)
index a08b628..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/**\r
- * \r
- */\r
-package org.collectionspace.services.collectionobject;\r
-\r
-import java.io.IOException;\r
-import org.dom4j.Document;\r
-import org.dom4j.DocumentException;\r
-\r
-import org.collectionspace.services.collectionobject.CollectionObject;\r
-\r
-/**\r
- * @author remillet\r
- * \r
- */\r
-public interface CollectionObjectService {\r
-\r
-       public final static String CO_SCHEMA_NAME = "collectionobject";\r
-\r
-       // Create\r
-       Document postCollectionObject(CollectionObject co)\r
-                       throws DocumentException, IOException;\r
-\r
-       // Read single object\r
-       Document getCollectionObject(String csid) throws DocumentException,\r
-                       IOException;\r
-\r
-       // Read a list of objects\r
-       Document getCollectionObjectList() throws DocumentException, IOException;\r
-\r
-       // Update\r
-       Document putCollectionObject(String csid, CollectionObject theUpdate)\r
-                       throws DocumentException, IOException;\r
-\r
-       // Delete\r
-       Document deleteCollectionObject(String csid) throws DocumentException,\r
-                       IOException;\r
-}\r
index 4e593f19d042016e7e456e3d85ce273fba63fbc2..800f6d5b2a8cca818feae626c1176bfe0cb12fad 100644 (file)
@@ -26,11 +26,10 @@ package org.collectionspace.services.collectionobject.nuxeo;
 import java.util.Iterator;
 import java.util.List;
 
-import org.collectionspace.services.collectionobject.nuxeo.CollectionObjectConstants;
 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.CollectionobjectsCommon;
+import org.collectionspace.services.collectionobject.CollectionobjectsCommonList;
+import org.collectionspace.services.collectionobject.CollectionobjectsCommonList.CollectionObjectListItem;
 import org.collectionspace.services.common.repository.DocumentWrapper;
 import org.collectionspace.services.nuxeo.client.java.DocumentModelHandler;
 import org.nuxeo.ecm.core.api.DocumentModel;
@@ -45,146 +44,69 @@ import org.slf4j.LoggerFactory;
  * $LastChangedDate: $
  */
 public class CollectionObjectDocumentModelHandler
-        extends DocumentModelHandler<CollectionObject, CollectionObjectList> {
+        extends DocumentModelHandler<CollectionobjectsCommon, CollectionobjectsCommonList> {
 
     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;
+    private CollectionobjectsCommon 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
-    }
-
+    private CollectionobjectsCommonList collectionObjectList;
 
     /**
-     * getCommonObject get associated CollectionObject
+     * getCommonPart get associated CollectionobjectsCommon
      * @return
      */
     @Override
-    public CollectionObject getCommonObject() {
+    public CollectionobjectsCommon getCommonPart() {
         return collectionObject;
     }
 
     /**
-     * setCommonObject set associated collectionobject
+     * setCommonPart set associated collectionobject
      * @param collectionObject
      */
     @Override
-    public void setCommonObject(CollectionObject collectionObject) {
+    public void setCommonPart(CollectionobjectsCommon collectionObject) {
         this.collectionObject = collectionObject;
     }
 
     /**
-     * getCollectionObjectList get associated CollectionObject (for index/GET_ALL)
+     * getCollectionobjectsCommonList get associated CollectionobjectsCommon (for index/GET_ALL)
      * @return
      */
     @Override
-    public CollectionObjectList getCommonObjectList() {
+    public CollectionobjectsCommonList getCommonPartList() {
         return collectionObjectList;
     }
 
     @Override
-    public void setCommonObjectList(CollectionObjectList collectionObjectList) {
+    public void setCommonPartList(CollectionobjectsCommonList collectionObjectList) {
         this.collectionObjectList = collectionObjectList;
     }
 
     @Override
-    public CollectionObject extractCommonObject(DocumentWrapper wrapDoc)
+    public CollectionobjectsCommon extractCommonPart(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;
+        throw new UnsupportedOperationException();
     }
 
     @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.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());
-        }
+    public void fillCommonPart(CollectionobjectsCommon co, DocumentWrapper wrapDoc) throws Exception {
+        throw new UnsupportedOperationException();
     }
 
     @Override
-    public CollectionObjectList extractCommonObjectList(DocumentWrapper wrapDoc) throws Exception {
+    public CollectionobjectsCommonList extractCommonPartList(DocumentWrapper wrapDoc) throws Exception {
         DocumentModelList docList = (DocumentModelList) wrapDoc.getWrappedObject();
 
-        CollectionObjectList coList = new CollectionObjectList();
-        List<CollectionObjectList.CollectionObjectListItem> list = coList.getCollectionObjectListItem();
+        CollectionobjectsCommonList coList = new CollectionobjectsCommonList();
+        List<CollectionobjectsCommonList.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
@@ -192,10 +114,9 @@ public class CollectionObjectDocumentModelHandler
         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.setObjectNumber((String) docModel.getProperty(getServiceContext().getCommonPartLabel(),
+                    CollectionObjectJAXBSchema.OBJECT_NUMBER));
+            coListItem.setUri(getServiceContextPath() + docModel.getId());
             coListItem.setCsid(docModel.getId());
             list.add(coListItem);
         }
@@ -204,20 +125,26 @@ public class CollectionObjectDocumentModelHandler
     }
 
     @Override
-    public void fillCommonObjectList(CollectionObjectList obj, DocumentWrapper wrapDoc) throws Exception {
-        throw new UnsupportedOperationException();
+    public void fillAllParts(DocumentWrapper wrapDoc) throws Exception {
+
+        super.fillAllParts(wrapDoc);
+        fillDublinCoreObject(wrapDoc); //dublincore might not be needed in future
     }
-    
+
+    private void fillDublinCoreObject(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.NUXEO_DC_TITLE);
+    }
+
     public String getDocumentType() {
-       return CollectionObjectConstants.NUXEO_DOCTYPE;
+        return CollectionObjectConstants.NUXEO_DOCTYPE;
     }
 
-    /**
-     * getQProperty converts the given property to qualified schema property
-     * @param prop
-     * @return
-     */
-    private String getQProperty(String prop) {
+    @Override
+    public String getQProperty(String prop) {
         return CollectionObjectConstants.NUXEO_SCHEMA_NAME + ":" + prop;
     }
 }
index bcaa606b1200e0eb7975ac34e97a824e3b4abc5b..da019e737c86383f37f88f332890b13566aff63c 100644 (file)
@@ -23,7 +23,7 @@
  */
 package org.collectionspace.services.collectionobject.nuxeo;
 
-import org.collectionspace.services.common.NuxeoClientType;
+import org.collectionspace.services.common.ClientType;
 import org.collectionspace.services.common.repository.DocumentHandler;
 
 /**
@@ -45,9 +45,9 @@ public class CollectionObjectHandlerFactory {
     }
 
     public DocumentHandler getHandler(String clientType) {
-        if(NuxeoClientType.JAVA.toString().equals(clientType)){
+        if(ClientType.JAVA.toString().equals(clientType)){
             return new CollectionObjectDocumentModelHandler();
-        } else if(NuxeoClientType.REST.toString().equals(clientType)) {
+        } else if(ClientType.REST.toString().equals(clientType)) {
             return new CollectionObjectRepresenationHandler();
         }
         throw new IllegalArgumentException("Not supported client=" + clientType);
index 44dd741a3e9a04b8d1c8c0a2b9504f6f5764af35..034b0875b7249721edee66c28609d4235d2c80ea 100644 (file)
@@ -27,13 +27,13 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
+import java.util.StringTokenizer;
 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.CollectionobjectsCommon;
+import org.collectionspace.services.collectionobject.CollectionobjectsCommonList;
+import org.collectionspace.services.collectionobject.CollectionobjectsCommonList.CollectionObjectListItem;
 import org.collectionspace.services.common.repository.DocumentWrapper;
 import org.collectionspace.services.nuxeo.client.rest.RepresentationHandler;
-import org.collectionspace.services.collectionobject.nuxeo.CollectionObjectConstants;
 
 import org.dom4j.Document;
 import org.dom4j.Element;
@@ -47,7 +47,7 @@ import org.slf4j.LoggerFactory;
  * $LastChangedDate: $
  */
 public class CollectionObjectRepresenationHandler
-        extends RepresentationHandler<CollectionObject, CollectionObjectList>
+        extends RepresentationHandler<CollectionobjectsCommon, CollectionobjectsCommonList>
 {
 
     private final Logger logger = LoggerFactory.getLogger(CollectionObjectRepresenationHandler.class);
@@ -55,12 +55,12 @@ public class CollectionObjectRepresenationHandler
      * collectionObject is used to stash JAXB object to use when handle is called
      * for Action.CREATE, Action.UPDATE or Action.GET
      */
-    private CollectionObject collectionObject;
+    private CollectionobjectsCommon collectionObject;
     /**
      * collectionObjectList is stashed when handle is called
      * for ACTION.GET_ALL
      */
-    private CollectionObjectList collectionObjectList;
+    private CollectionobjectsCommonList collectionObjectList;
 
     @Override
     public void prepare(Action action) throws Exception {
@@ -73,7 +73,7 @@ public class CollectionObjectRepresenationHandler
 
     private void prepare() {
         Map<String, String> queryParams = getQueryParams();
-        CollectionObject co = getCommonObject();
+        CollectionobjectsCommon co = getCommonPart();
         // todo: intelligent merge needed
         if(co.getObjectNumber() != null){
             queryParams.put(CollectionObjectConstants.NUXEO_SCHEMA_NAME +
@@ -117,10 +117,10 @@ public class CollectionObjectRepresenationHandler
     }
 
     @Override
-    public CollectionObject extractCommonObject(DocumentWrapper wrapDoc)
+    public CollectionobjectsCommon extractCommonPart(DocumentWrapper wrapDoc)
             throws Exception {
         Document document = (Document) wrapDoc.getWrappedObject();
-        CollectionObject co = new CollectionObject();
+        CollectionobjectsCommon co = new CollectionobjectsCommon();
 
         //FIXME property get should be dynamically set using schema inspection
         //so it does not require hard coding
@@ -177,20 +177,20 @@ public class CollectionObjectRepresenationHandler
     }
 
     @Override
-    public void fillCommonObject(CollectionObject co, DocumentWrapper wrapDoc)
+    public void fillCommonPart(CollectionobjectsCommon co, DocumentWrapper wrapDoc)
             throws Exception {
         //Nuxeo REST takes create/update through queryParams, nothing to do here
     }
 
     @Override
-    public CollectionObjectList extractCommonObjectList(DocumentWrapper wrapDoc) throws Exception {
+    public CollectionobjectsCommonList extractCommonPartList(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();
+        CollectionobjectsCommonList coList = new CollectionobjectsCommonList();
+        List<CollectionobjectsCommonList.CollectionObjectListItem> list = coList.getCollectionObjectListItem();
         Element root = document.getRootElement();
         for(Iterator i = root.elementIterator(); i.hasNext();){
 
@@ -210,29 +210,24 @@ public class CollectionObjectRepresenationHandler
         return coList;
     }
 
-    @Override
-    public void fillCommonObjectList(CollectionObjectList obj, DocumentWrapper wrapDoc)
-            throws Exception {
-        throw new UnsupportedOperationException();
-    }
 
     @Override
-    public CollectionObject getCommonObject() {
+    public CollectionobjectsCommon getCommonPart() {
         return collectionObject;
     }
 
     @Override
-    public void setCommonObject(CollectionObject obj) {
+    public void setCommonPart(CollectionobjectsCommon obj) {
         this.collectionObject = obj;
     }
 
     @Override
-    public CollectionObjectList getCommonObjectList() {
+    public CollectionobjectsCommonList getCommonPartList() {
         return collectionObjectList;
     }
 
     @Override
-    public void setCommonObjectList(CollectionObjectList obj) {
+    public void setCommonPartList(CollectionobjectsCommonList obj) {
         this.collectionObjectList = obj;
     }
     
@@ -240,13 +235,11 @@ public class CollectionObjectRepresenationHandler
        return CollectionObjectConstants.NUXEO_DOCTYPE;
     }
 
-    /**
-     * getQProperty converts the given property to qualified schema property
-     * @param prop
-     * @return
-     */
-    private String getQProperty(String prop) {
+
+    @Override
+    public String getQProperty(String prop) {
         return CollectionObjectConstants.NUXEO_SCHEMA_NAME + ":" + prop;
     }
+
 }
 
diff --git a/services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/nuxeo/CollectionObjectServiceNuxeoImpl.java b/services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/nuxeo/CollectionObjectServiceNuxeoImpl.java
deleted file mode 100644 (file)
index e19e56d..0000000
+++ /dev/null
@@ -1,224 +0,0 @@
-/**\r
- * \r
- */\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
-import java.util.Arrays;\r
-import java.util.HashMap;\r
-import java.util.List;\r
-import java.util.Map;\r
-\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.util.NuxeoUtils;\r
-\r
-import org.dom4j.Document;\r
-import org.dom4j.DocumentException;\r
-import org.dom4j.io.SAXReader;\r
-import org.restlet.resource.Representation;\r
-\r
-import org.nuxeo.ecm.core.api.IdRef;\r
-import org.nuxeo.ecm.core.api.repository.RepositoryInstance;\r
-import org.nuxeo.ecm.core.api.DocumentModel;\r
-import org.nuxeo.ecm.core.api.DocumentRef;\r
-\r
-\r
-\r
-/**\r
- * @author remillet\r
- * \r
- */\r
-public class CollectionObjectServiceNuxeoImpl extends\r
-               CollectionSpaceServiceNuxeoImpl implements CollectionObjectService {\r
-\r
-       final static String CO_NUXEO_DOCTYPE = "CollectionObject";\r
-       final static String CO_NUXEO_SCHEMA_NAME = "collectionobject";\r
-       final static String CO_NUXEO_DC_TITLE = "CollectionSpace-CollectionObject";\r
-\r
-       // replace WORKSPACE_UID for resource workspace\r
-       static String CS_COLLECTIONOBJECT_WORKSPACE_UID = "9dd20955-fce7-4a87-8319-040ab9543f4f";\r
-\r
-       public Document deleteCollectionObject(String csid)\r
-                       throws DocumentException, IOException {\r
-\r
-               Document result = null;\r
-               \r
-//             NuxeoRESTClient nxClient = getClient();\r
-//             List<String> pathParams = new ArrayList<String>();\r
-//             Map<String, String> queryParams = new HashMap<String, String>();\r
-//\r
-//             pathParams.add("default");\r
-//             pathParams.add(csid);\r
-//             pathParams.add("deleteDocumentRestlet");\r
-//             Representation res = nxClient.get(pathParams, queryParams);\r
-//             SAXReader reader = new SAXReader();\r
-//             result = reader.read(res.getStream());\r
-               \r
-               return result;\r
-       }\r
-\r
-       public Document getCollectionObject(String csid) throws DocumentException,\r
-                       IOException {\r
-               \r
-               // Calling via Nuxeo Java API\r
-               //getCollectionObjectViaJavaAPI(csid);\r
-               \r
-               // Return to normal Nuxeo REST call\r
-               Document result = null;\r
-//             \r
-//             List<String> pathParams = new ArrayList<String>();\r
-//             Map<String, String> queryParams = new HashMap<String, String>();\r
-//\r
-//             pathParams.add("default");\r
-//             pathParams.add(csid);\r
-//             pathParams.add("export");\r
-//             queryParams.put("format", "XML");\r
-//\r
-//             NuxeoRESTClient nxClient = getClient();\r
-//             Representation res = nxClient.get(pathParams, queryParams);\r
-//\r
-//             SAXReader reader = new SAXReader();\r
-//             result = reader.read(res.getStream());\r
-\r
-               return result;\r
-       }\r
-       \r
-       \r
-       public Document getCollectionObjectList() throws DocumentException,\r
-                       IOException {\r
-               Document result = null;\r
-\r
-//             NuxeoRESTClient nxClient = getClient();\r
-//             List<String> pathParams = new ArrayList<String>();\r
-//             Map<String, String> queryParams = new HashMap<String, String>();\r
-//             pathParams = Arrays.asList("default",\r
-//                             CS_COLLECTIONOBJECT_WORKSPACE_UID, "browse");\r
-//             Representation res = nxClient.get(pathParams, queryParams);\r
-//             SAXReader reader = new SAXReader();\r
-//             result = reader.read(res.getStream());\r
-\r
-               return result;\r
-       }\r
-\r
-       public Document postCollectionObject(CollectionObject co)\r
-                       throws DocumentException, IOException {\r
-               Document result = null;\r
-               \r
-//             NuxeoRESTClient nxClient = getClient();\r
-//\r
-//             List<String> pathParams = new ArrayList<String>();\r
-//             Map<String, String> queryParams = new HashMap<String, String>();\r
-//             pathParams.add("default");\r
-//             pathParams.add(CS_COLLECTIONOBJECT_WORKSPACE_UID);\r
-//             pathParams.add("createDocument");\r
-//             queryParams.put("docType", CO_NUXEO_DOCTYPE);\r
-//\r
-//             // a default title for the Dublin Core schema\r
-//             queryParams.put("dublincore:title", CO_NUXEO_DC_TITLE);\r
-//\r
-//             // CollectionObject core values\r
-//             queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-//                             + CollectionObjectJAXBSchema.OBJECT_NUMBER, co\r
-//                             .getObjectNumber());\r
-//             queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-//                             + CollectionObjectJAXBSchema.OTHER_NUMBER, co.getOtherNumber());\r
-//             queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-//                             + CollectionObjectJAXBSchema.BRIEF_DESCRIPTION, co\r
-//                             .getBriefDescription());\r
-//             queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-//                             + CollectionObjectJAXBSchema.COMMENTS, co.getComments());\r
-//             queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-//                             + CollectionObjectJAXBSchema.DIST_FEATURES, co\r
-//                             .getDistFeatures());\r
-//             queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-//                             + CollectionObjectJAXBSchema.OBJECT_NAME, co.getObjectName());\r
-//             queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-//                             + CollectionObjectJAXBSchema.RESPONSIBLE_DEPT, co\r
-//                             .getResponsibleDept());\r
-//             queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-//                             + CollectionObjectJAXBSchema.TITLE, co.getTitle());\r
-//\r
-//             ByteArrayInputStream bais = new ByteArrayInputStream(new byte[0]);\r
-//             Representation res = nxClient.post(pathParams, queryParams, bais);\r
-//\r
-//             SAXReader reader = new SAXReader();\r
-//             result = reader.read(res.getStream());\r
-\r
-               return result;\r
-       }\r
-\r
-       public Document putCollectionObject(String csid, CollectionObject theUpdate)\r
-                       throws DocumentException, IOException {\r
-               \r
-               Document result = null;\r
-               \r
-//             List<String> pathParams = new ArrayList<String>();\r
-//             Map<String, String> queryParams = new HashMap<String, String>();\r
-//             pathParams.add("default");\r
-//             pathParams.add(csid);\r
-//             pathParams.add("updateDocumentRestlet");\r
-//\r
-//             // todo: intelligent merge needed\r
-//             if (theUpdate.getObjectNumber() != null) {\r
-//                     queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-//                                     + CollectionObjectJAXBSchema.OBJECT_NUMBER, theUpdate\r
-//                                     .getObjectNumber());\r
-//             }\r
-//\r
-//             if (theUpdate.getOtherNumber() != null) {\r
-//                     queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-//                                     + CollectionObjectJAXBSchema.OTHER_NUMBER, theUpdate\r
-//                                     .getOtherNumber());\r
-//             }\r
-//\r
-//             if (theUpdate.getBriefDescription() != null) {\r
-//                     queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-//                                     + CollectionObjectJAXBSchema.BRIEF_DESCRIPTION, theUpdate\r
-//                                     .getBriefDescription());\r
-//             }\r
-//\r
-//             if (theUpdate.getComments() != null) {\r
-//                     queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-//                                     + CollectionObjectJAXBSchema.COMMENTS, theUpdate\r
-//                                     .getComments());\r
-//             }\r
-//\r
-//             if (theUpdate.getDistFeatures() != null) {\r
-//                     queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-//                                     + CollectionObjectJAXBSchema.DIST_FEATURES, theUpdate\r
-//                                     .getDistFeatures());\r
-//             }\r
-//\r
-//             if (theUpdate.getObjectName() != null) {\r
-//                     queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-//                                     + CollectionObjectJAXBSchema.OBJECT_NAME, theUpdate\r
-//                                     .getObjectName());\r
-//             }\r
-//\r
-//             if (theUpdate.getResponsibleDept() != null) {\r
-//                     queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-//                                     + CollectionObjectJAXBSchema.RESPONSIBLE_DEPT, theUpdate\r
-//                                     .getResponsibleDept());\r
-//             }\r
-//\r
-//             if (theUpdate.getTitle() != null) {\r
-//                     queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-//                                     + CollectionObjectJAXBSchema.TITLE, theUpdate.getTitle());\r
-//             }\r
-//\r
-//             NuxeoRESTClient nxClient = getClient();\r
-//             Representation res = nxClient.get(pathParams, queryParams);\r
-//             SAXReader reader = new SAXReader();\r
-//             result = reader.read(res.getStream());\r
-\r
-               return result;\r
-       }\r
-\r
-}\r
index a3fffc52864e26f1ca2af08eedcec0b740df630e..13a59be0fc7322f091fa2c2172de3aade5b9c4f0 100644 (file)
 
     <target name="deploy" depends="package"
     description="deploy common elements in ${jboss.server.cspace}">
-        <copy file="${basedir}/src/main/config/service-config.xml"
-        todir="${jboss.server.cspace}/cspace/config/services"/>
+        <copy todir="${jboss.server.cspace}/cspace/config/services">
+            <fileset dir="${basedir}/src/main/config"/>
+        </copy>
     </target>
 
     <target name="undeploy"
     description="undeploy common elements from ${jboss.server.cspace}">
-        <delete failonerror="false" file="${jboss.server.cspace}/cspace/config/services/service-config.xml"/>
+        <delete failonerror="false" dir="${jboss.server.cspace}/cspace/config/services"/>
     </target>
 
     <target name="dist"
     description="generate distribution for common elements" depends="package">
         <copy todir="${services.trunk}/${dist.server.cspace}/cspace/config/services">
-            <fileset file="${basedir}/src/main/config/service-config.xml"/>
+            <fileset dir="${basedir}/src/main/config"/>
         </copy>
     </target>
 
index 16906e47edfd02443959b2dbe7282d864d27466f..c54f50d2025cec96fd596f0cdc1f13210c8c2fba 100644 (file)
     <name>services.common</name>\r
     \r
     <dependencies>\r
+        <dependency>\r
+            <groupId>com.sun.xml.bind</groupId>\r
+            <artifactId>jaxb-impl</artifactId>\r
+         </dependency>\r
+        <dependency>\r
+            <groupId>org.jvnet.jaxb2-commons</groupId>\r
+            <artifactId>property-listener-injector</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.jvnet.jaxb2_commons</groupId>\r
+            <artifactId>runtime</artifactId>\r
+        </dependency>\r
         <dependency>\r
             <groupId>org.jboss.resteasy</groupId>\r
             <artifactId>resteasy-jaxrs</artifactId>\r
-            <version>1.0.2.GA</version>\r
             <exclusions>\r
                 <exclusion>\r
                     <groupId>tjws</groupId>\r
         <dependency>\r
             <groupId>org.jboss.resteasy</groupId>\r
             <artifactId>resteasy-jaxb-provider</artifactId>\r
-            <version>1.0.2.GA</version>\r
+            <version>1.1.GA</version>\r
         </dependency>\r
         <dependency>\r
             <groupId>org.jboss.resteasy</groupId>\r
             <artifactId>resteasy-multipart-provider</artifactId>\r
-            <version>1.0.2.GA</version>\r
+            <version>1.1.GA</version>\r
         </dependency>\r
 \r
         <!-- utilities -->\r
         </dependency>\r
       <!-- javax -->\r
 \r
-\r
+        <dependency>\r
+            <groupId>javax.servlet</groupId>\r
+            <artifactId>servlet-api</artifactId>\r
+            <version>2.5</version>\r
+            <scope>provided</scope>\r
+        </dependency>\r
+        \r
         <dependency>\r
             <groupId>javax.security</groupId>\r
             <artifactId>jaas</artifactId>\r
             <version>1.1.1</version>\r
         </dependency>\r
 \r
-        <dependency>\r
-            <groupId>com.sun.xml.bind</groupId>\r
-            <artifactId>jaxb-impl</artifactId>\r
-            <version>2.0.2</version>\r
-        </dependency>\r
-        <dependency>\r
-            <groupId>org.jvnet.jaxb2-commons</groupId>\r
-            <artifactId>property-listener-injector</artifactId>\r
-            <version>1.0</version>\r
-        </dependency>\r
-        <dependency>\r
-            <groupId>org.jvnet.jaxb2_commons</groupId>\r
-            <artifactId>runtime</artifactId>\r
-            <version>0.4.1.4</version>\r
-        </dependency>\r
+\r
     </dependencies>\r
     \r
     <build>\r
                         </goals>\r
                     </execution>\r
                 </executions>\r
-                <dependencies>\r
-               <!-- javax.activation.DataSource provider is required by spec -->\r
-                    <dependency>\r
-                        <groupId>javax.activation</groupId>\r
-                        <artifactId>activation</artifactId>\r
-                        <version>1.1</version>\r
-                    </dependency>\r
-                    <dependency>\r
-                        <groupId>com.sun.xml.bind</groupId>\r
-                        <artifactId>jaxb-impl</artifactId>\r
-                        <version>2.1.2</version>\r
-                    </dependency>\r
-                </dependencies>\r
+\r
                 <configuration>\r
                     <args>\r
                         <arg>-XtoString</arg>\r
diff --git a/services/common/profiles.xml b/services/common/profiles.xml
new file mode 100644 (file)
index 0000000..347b9df
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<profilesXml xmlns="http://maven.apache.org/PROFILES/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/PROFILES/1.0.0 http://maven.apache.org/xsd/profiles-1.0.0.xsd">
+</profilesXml>
\ No newline at end of file
index 01bc94a1fd69e4a753543e901b1b41467394d6f0..a6315b9830801b3e4d90b28aea5ef9525d5ab20c 100644 (file)
 <ns1:service-config  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
    xmlns:ns1='http://collectionspace.org/services/common'
    xsi:schemaLocation='http://collectionspace.org/services/common ../resources/common.xsd'>
-    <nuxeo-client-config>
+
+    <!-- name of the repository client is referred in each service binding -->
+    <repository-client name="nuxeo-java" default="true">
         <!-- ip of network interface to which Nuxeo server is listening on -->
         <host>127.0.0.1</host>
         <port>62474</port> <!-- java -->
         <!--port>8080</port--> <!-- rest -->
-        <client-type>java</client-type>
         <user>Administrator</user>
         <password>Administrator</password>
-    </nuxeo-client-config>
-    <nuxeo-workspace>
-        <workspace>
+        <client-type>java</client-type>
+        <client-class>org.collectionspace.services.nuxeo.client.java.RepositoryJavaClient</client-class>
+    </repository-client>
+
+    <!-- TODO: remove once all the services start using service bindings -->
+    <repository-workspace>
+        <!--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>
         <workspace>
             <service-name>intakes</service-name>
             <workspace-name>Intakes</workspace-name>
-            <!-- use hard-coded workspace id for REST client -->
-            <!--workspace-id></workspace-id-->
         </workspace>
         <workspace>
             <service-name>relations</service-name>
             <workspace-name>Relations</workspace-name>
-        </workspace>        
+        </workspace>
         <workspace>
             <service-name>acquisitions</service-name>
             <workspace-name>Acquisitions</workspace-name>
-        </workspace>        
-    </nuxeo-workspace>
+        </workspace>
+    </repository-workspace>
 
 </ns1:service-config>
diff --git a/services/common/src/main/config/tenant-bindings.xml b/services/common/src/main/config/tenant-bindings.xml
new file mode 100644 (file)
index 0000000..ddcec89
--- /dev/null
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Document   : tenants-bindings.xml
+    Created on : August 31, 2009, 10:52 AM
+    Author     : 
+    Description:
+        tenant bindings
+-->
+<tenant:TenantBindingConfig  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+   xmlns:tenant='http://collectionspace.org/services/common/tenant'
+   xsi:schemaLocation='http://collectionspace.org/services/common/tenant http://collectionspace.org/services/common/tenant.xsd'
+   >
+    <!-- begin movinimages.us tenant meta-data -->
+    <tenant:tenantBinding
+        id="1" name="movingimages.us" displayName="Museum of Moving Images" version="0.1" repositoryDomain="default-domain">
+        <tenant:serviceBindings name="CollectionObjects" version="0.1">
+            <!-- begin collectionobject service meta-data -->
+            <service:repositoryClient xmlns:service='http://collectionspace.org/services/common/service'>nuxeo-java</service:repositoryClient>
+            <service:object id="1" name="CollectionObject" version="0.1"
+            xmlns:service='http://collectionspace.org/services/common/service'>
+                <service:part id="0" control_group="Managed"
+                            versionable="true" auditable="false"
+                            label="collectionobjects-system" updated="" order="0">
+                    <service:content contentType="application/xml">
+                        <service:xmlContent
+                        namespaceURI="http://collectionspace.org/services/common/system"
+                        schemaLocation="http://collectionspace.org/services/common/system http://collectionspace.org/services/common/system/system-response.xsd">
+                        </service:xmlContent>
+                    </service:content>
+                </service:part>
+                <service:part id="1" control_group="Managed"
+                            versionable="true" auditable="false"
+                            label="collectionobjects-common" updated="" order="1">
+                    <service:content contentType="application/xml">
+                        <service:xmlContent
+                        namespaceURI="http://collectionspace.org/services/collectionobject"
+                        schemaLocation="http://collectionspace.org/services/collectionobject http://services.collectionspace.org/collectionobject/collectionobjects-common.xsd">
+                        </service:xmlContent>
+                    </service:content>
+                </service:part>
+                <service:part id="2" control_group="Managed"
+                            versionable="true" auditable="false"
+                            label="collectionobjects-naturalhistory" updated="" order="2">
+                    <service:content contentType="application/xml">
+                        <service:xmlContent
+                        namespaceURI="http://collectionspace.org/services/collectionobject/domain/naturalhistory"
+                        schemaLocation="http://collectionspace.org/services/collectionobject/domain/naturalhistory http://collectionspace.org/services/collectionobject/domain/collectionobjects-naturalhistory.xsd">
+                        </service:xmlContent>
+                    </service:content>
+                </service:part>
+            </service:object>
+        </tenant:serviceBindings>
+        <!--end collectionobject service meta-data -->
+        <!-- begin intake service meta-data -->
+        <tenant:serviceBindings name="Intakes" version="0.1">
+            <service:repositoryClient xmlns:service='http://collectionspace.org/services/common/service'>nuxeo-java</service:repositoryClient>
+            <service:object id="2" name="Intake" version="0.1"
+            xmlns:service='http://collectionspace.org/services/common/service'>
+                <service:part id="0" control_group="Managed"
+                            versionable="true" auditable="false"
+                            label="intakes-system" updated="" order="0">
+                    <service:content contentType="application/xml">
+                        <service:xmlContent
+                        namespaceURI="http://collectionspace.org/services/common/system"
+                        schemaLocation="http://collectionspace.org/services/common/system http://collectionspace.org/services/common/system/system-response.xsd">
+                        </service:xmlContent>
+                    </service:content>
+                </service:part>
+                <service:part id="1" control_group="Managed"
+                            versionable="true" auditable="false"
+                            label="intakes-common" updated="" order="1">
+                    <service:content contentType="application/xml">
+                        <service:xmlContent
+                        namespaceURI="http://collectionspace.org/services/intake"
+                        schemaLocation="http://collectionspace.org/services/intake http://services.collectionspace.org/intake/intakes-common.xsd">
+                        </service:xmlContent>
+                    </service:content>
+                </service:part>
+            </service:object>
+        </tenant:serviceBindings>
+        <!-- end intake service meta-data -->
+                <!-- begin acquisition service meta-data -->
+        <tenant:serviceBindings name="Acquisitions" version="0.1">
+            <service:repositoryClient xmlns:service='http://collectionspace.org/services/common/service'>nuxeo-java</service:repositoryClient>
+            <service:object id="2" name="Acquisition" version="0.1"
+            xmlns:service='http://collectionspace.org/services/common/service'>
+                <service:part id="0" control_group="Managed"
+                            versionable="true" auditable="false"
+                            label="acquisitions-system" updated="" order="0">
+                    <service:content contentType="application/xml">
+                        <service:xmlContent
+                        namespaceURI="http://collectionspace.org/services/common/system"
+                        schemaLocation="http://collectionspace.org/services/common/system http://collectionspace.org/services/common/system/system-response.xsd">
+                        </service:xmlContent>
+                    </service:content>
+                </service:part>
+                <service:part id="1" control_group="Managed"
+                            versionable="true" auditable="false"
+                            label="acquisitions-common" updated="" order="1">
+                    <service:content contentType="application/xml">
+                        <service:xmlContent
+                        namespaceURI="http://collectionspace.org/services/acquisition"
+                        schemaLocation="http://collectionspace.org/services/acquisition http://services.collectionspace.org/acquisition/acquisitions-common.xsd">
+                        </service:xmlContent>
+                    </service:content>
+                </service:part>
+            </service:object>
+        </tenant:serviceBindings>
+        <!-- end acquisition service meta-data -->
+    </tenant:tenantBinding>
+    <!-- end movinimages.us tenant meta-data -->
+</tenant:TenantBindingConfig>
diff --git a/services/common/src/main/java/org/collectionspace/services/common/AbstractCollectionSpaceResource.java b/services/common/src/main/java/org/collectionspace/services/common/AbstractCollectionSpaceResource.java
new file mode 100644 (file)
index 0000000..ad2fef0
--- /dev/null
@@ -0,0 +1,70 @@
+/**\r
+ *  This document is a part of the source code and related artifacts\r
+ *  for CollectionSpace, an open source collections management system\r
+ *  for museums and related institutions:\r
+\r
+ *  http://www.collectionspace.org\r
+ *  http://wiki.collectionspace.org\r
+\r
+ *  Copyright 2009 University of California at Berkeley\r
+\r
+ *  Licensed under the Educational Community License (ECL), Version 2.0.\r
+ *  You may not use this file except in compliance with this License.\r
+\r
+ *  You may obtain a copy of the ECL 2.0 License at\r
+\r
+ *  https://source.collectionspace.org/collection-space/LICENSE.txt\r
+\r
+ *  Unless required by applicable law or agreed to in writing, software\r
+ *  distributed under the License is distributed on an "AS IS" BASIS,\r
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ *  See the License for the specific language governing permissions and\r
+ *  limitations under the License.\r
+ */\r
+package org.collectionspace.services.common;\r
+\r
+import org.collectionspace.services.common.context.ServiceContext;\r
+import org.collectionspace.services.common.context.ServiceContextImpl;\r
+import org.collectionspace.services.common.repository.DocumentHandler;\r
+import org.collectionspace.services.common.repository.RepositoryClient;\r
+import org.collectionspace.services.common.repository.RepositoryClientFactory;\r
+import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;\r
+\r
+public abstract class AbstractCollectionSpaceResource\r
+        implements CollectionSpaceResource {\r
+\r
+    // Fields for default client factory and client\r
+    private RepositoryClientFactory repositoryClientFactory;\r
+    private RepositoryClient repositoryClient;\r
+\r
+    public AbstractCollectionSpaceResource() {\r
+        repositoryClientFactory = RepositoryClientFactory.getInstance();\r
+    }\r
+\r
+    @Override\r
+    abstract public String getServiceName();\r
+\r
+    @Override\r
+    public RepositoryClientFactory getRepositoryClientFactory() {\r
+        return repositoryClientFactory;\r
+    }\r
+\r
+    @Override\r
+    synchronized public RepositoryClient getRepositoryClient(ServiceContext ctx) {\r
+        if(repositoryClient != null){\r
+            return repositoryClient;\r
+        }\r
+        repositoryClient = repositoryClientFactory.getClient(ctx.getRepositoryClientName());\r
+        return repositoryClient;\r
+    }\r
+\r
+    @Override\r
+    public ServiceContext createServiceContext(MultipartInput input) throws Exception {\r
+        ServiceContext ctx = new ServiceContextImpl(getServiceName());\r
+        ctx.setInput(input);\r
+        return ctx;\r
+    }\r
+\r
+    @Override\r
+    abstract public DocumentHandler createDocumentHandler(ServiceContext ctx) throws Exception ;\r
+}\r
index cd3368e26ef016206bd8ff009da3cba3f9422e4b..b3e310b0e364dc67672f13c759b39000090b82f2 100644 (file)
@@ -1,8 +1,37 @@
+/**\r
+ *  This document is a part of the source code and related artifacts\r
+ *  for CollectionSpace, an open source collections management system\r
+ *  for museums and related institutions:\r
+\r
+ *  http://www.collectionspace.org\r
+ *  http://wiki.collectionspace.org\r
+\r
+ *  Copyright 2009 University of California at Berkeley\r
+\r
+ *  Licensed under the Educational Community License (ECL), Version 2.0.\r
+ *  You may not use this file except in compliance with this License.\r
+\r
+ *  You may obtain a copy of the ECL 2.0 License at\r
+\r
+ *  https://source.collectionspace.org/collection-space/LICENSE.txt\r
+\r
+ *  Unless required by applicable law or agreed to in writing, software\r
+ *  distributed under the License is distributed on an "AS IS" BASIS,\r
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ *  See the License for the specific language governing permissions and\r
+ *  limitations under the License.\r
+ */\r
+\r
 package org.collectionspace.services.common;\r
 \r
 import org.collectionspace.services.common.repository.DocumentHandler;\r
-import org.collectionspace.services.common.NuxeoClientType;\r
 \r
 public interface CollectionSpaceHandlerFactory {\r
+    /**\r
+     * getHandler gets or creates a document handler per given client type\r
+     * @param clientType (java|rest)\r
+     * @return\r
+     * @throws IllegalArgumentException\r
+     */\r
     public DocumentHandler getHandler(String clientType) throws IllegalArgumentException;\r
 }\r
index e4b33b75713caef06d69a7cef5ea17bfafc0db33..2f601c334f85c3892ecabf4df238d8aa0e514f61 100644 (file)
@@ -1,38 +1,73 @@
-package org.collectionspace.services.common;\r
-\r
-import org.collectionspace.services.common.repository.DocumentHandler;\r
-import org.collectionspace.services.common.repository.RepositoryClient;\r
-import org.collectionspace.services.common.repository.RepositoryClientFactory;\r
-import org.collectionspace.services.common.CollectionSpaceHandlerFactory;\r
-//import org.collectionspace.services.relation.nuxeo.RelationHandlerFactory;\r
-\r
-public abstract class CollectionSpaceResource {\r
-\r
-       // Fields for default client factory and client\r
-       private RepositoryClientFactory defaultClientFactory;\r
-       private RepositoryClient defaultClient;\r
-       \r
-       // Fields for default document handler factory and handler\r
-       private CollectionSpaceHandlerFactory defaultHandlerFactory;\r
-       private DocumentHandler defaultHandler;\r
-       \r
-       // Methods that subclasses must implement\r
-       abstract protected String getClientType();\r
-       abstract protected RepositoryClientFactory getDefaultClientFactory();\r
-       abstract protected CollectionSpaceHandlerFactory getDefaultHandlerFactory();\r
-       \r
-       protected RepositoryClient getDefaultClient() {\r
-               return this.defaultClient;\r
-       }\r
-       \r
-       protected DocumentHandler getDefaultHandler() {\r
-               return this.defaultHandler;\r
-       }\r
-       \r
-       public CollectionSpaceResource() {\r
-               defaultClientFactory = getDefaultClientFactory(); //implemented by subclasses\r
-               defaultClient = defaultClientFactory.getClient(getClientType());\r
-               defaultHandlerFactory = getDefaultHandlerFactory(); //implemented by subclasses\r
-               defaultHandler = defaultHandlerFactory.getHandler(getClientType());\r
-       }       \r
-}\r
+/**
+ *  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;
+
+import org.collectionspace.services.common.context.ServiceContext;
+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.plugins.providers.multipart.MultipartInput;
+
+/**
+ * CollectionSpaceResource is a resource interface implemented by every
+ * entity/service in CollectionSpace
+ */
+public interface CollectionSpaceResource {
+
+    /**
+     * getServiceName returns the name of the service
+     */
+    public String getServiceName();
+    
+    /**
+     * getRepositoryClientFactory
+     * @return
+     */
+    public RepositoryClientFactory getRepositoryClientFactory();
+
+    /**
+     * getRepositoryClient
+     * @param ctx service context
+     */
+    public RepositoryClient getRepositoryClient(ServiceContext ctx);
+
+    /**
+     * createServiceContext is a facotry method to create a service context
+     * a service contex is created on every service request call
+     * @param input
+     * @return
+     */
+    public ServiceContext createServiceContext(MultipartInput input) throws Exception;
+
+    /**
+     * createDocumentHandler creates a document handler and populates it with given
+     * service context. document handler should never be used
+     * across service invocations. it is a stateful object that holds request,
+     * response and service context
+     * @param ctx
+     * @return
+     */
+    public DocumentHandler createDocumentHandler(ServiceContext ctx) throws Exception ;
+}
similarity index 58%
rename from services/common/src/main/java/org/collectionspace/services/common/ServiceContextListener.java
rename to services/common/src/main/java/org/collectionspace/services/common/CollectionSpaceServiceContextListener.java
index 5015d7394b2ddb74d846dfdf583951a5643d1446..c7e72736f301660478896dc2122d8f5df2472229 100644 (file)
@@ -8,23 +8,25 @@ import javax.servlet.ServletContextEvent;
 import javax.servlet.ServletContextListener;
 
 /**
- * ServiceContextListener is a ServletContextListener that helps initialize
+ * CollectionSpaceServiceContextListener is a ServletContextListener that helps initialize
  * the services layer at deployment and undeployment times
  */
-public class ServiceContextListener implements ServletContextListener {
+public class CollectionSpaceServiceContextListener implements ServletContextListener {
 
+    @Override
     public void contextInitialized(ServletContextEvent event) {
         try{
-        ServletContext sc = event.getServletContext();
-        ServiceMain svcMain = ServiceMain.getInstance(); //first access initializes as well
-        svcMain.getWorkspaceIds();
-        }catch(Exception e) {
+            ServletContext sc = event.getServletContext();
+            ServiceMain svcMain = ServiceMain.getInstance(); //first access initializes as well
+            svcMain.retrieveAllWorkspaceIds();
+        }catch(Exception e){
             e.printStackTrace();
             //fail here
             throw new RuntimeException(e);
         }
     }
 
+    @Override
     public void contextDestroyed(ServletContextEvent event) {
         ServiceMain.getInstance().release();
     }
index 75c6efc4e892bca3deb156e881568dab68cf78fa..2d8e39eb296c123ead7062c12c01f19f18dcda57 100644 (file)
@@ -3,13 +3,9 @@
  */
 package org.collectionspace.services.common;
 
-import java.io.File;
 import java.util.Hashtable;
-import java.util.List;
-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.common.config.ServicesConfigReader;
+import org.collectionspace.services.common.config.TenantBindingConfigReader;
 import org.collectionspace.services.nuxeo.client.java.NuxeoConnector;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -21,16 +17,15 @@ import org.slf4j.LoggerFactory;
  */
 public class ServiceMain {
 
+    /**
+     * volatile is used here to assume about ordering (post JDK 1.5)
+     */
     private static volatile ServiceMain instance = null;
-    final public static String CSPACE_DIR_NAME = "cspace";
-    final public static String CONFIG_DIR_NAME = "config" + File.separator + "services";
-    final private static String CONFIG_FILE_NAME = "service-config.xml";
     final Logger logger = LoggerFactory.getLogger(ServiceMain.class);
-    private ServiceConfig serviceConfig;
-    private Hashtable<String, String> serviceWorkspaces = new Hashtable<String, String>();
     private NuxeoConnector nuxeoConnector;
     private String serverRootDir = null;
-    private NuxeoClientType nuxeoClientType = null;
+    private ServicesConfigReader servicesConfigReader;
+    private TenantBindingConfigReader tenantBindingConfigReader;
 
     private ServiceMain() {
     }
@@ -64,10 +59,11 @@ public class ServiceMain {
 
     private void initialize() throws Exception {
         setServerRootDir();
-        serviceConfig = readConfig();
-        if(getNuxeoClientType().equals(NuxeoClientType.JAVA)){
+        readConfig();
+        if(getClientType().equals(ClientType.JAVA)){
             nuxeoConnector = NuxeoConnector.getInstance();
-            nuxeoConnector.initialize(serviceConfig.getNuxeoClientConfig());
+            nuxeoConnector.initialize(
+                    getServicesConfigReader().getConfiguration().getRepositoryClient());
         }
     }
 
@@ -80,7 +76,6 @@ public class ServiceMain {
             if(nuxeoConnector != null){
                 nuxeoConnector.release();
             }
-            serviceWorkspaces.clear();
             instance = null;
         }catch(Exception e){
             e.printStackTrace();
@@ -88,74 +83,28 @@ public class ServiceMain {
         }
     }
 
-    private ServiceConfig readConfig() throws Exception {
-        JAXBContext jc = JAXBContext.newInstance(ServiceConfig.class);
-        Unmarshaller um = jc.createUnmarshaller();
-        String configFileName = getServerRootDir() +
-                File.separator + CSPACE_DIR_NAME +
-                File.separator + CONFIG_DIR_NAME +
-                File.separator + CONFIG_FILE_NAME;
-        File configFile = new File(configFileName);
-        if(!configFile.exists()){
-            String msg = "Could not find configuration file " + configFileName;
-            logger.error(msg);
-            throw new RuntimeException(msg);
-        }
-        ServiceConfig sconfig = (ServiceConfig) um.unmarshal(configFile);
-        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 = new Hashtable<String, String>();
+    private void readConfig() throws Exception {
+        //read service config
+        servicesConfigReader = new ServicesConfigReader(getServerRootDir());
+        getServicesConfigReader().read();
 
-        if(getNuxeoClientType().equals(NuxeoClientType.JAVA)){
-            workspaceIds = nuxeoConnector.retrieveWorkspaceIds();
-        }
-        NuxeoWorkspace nuxeoWorkspace = serviceConfig.getNuxeoWorkspace();
-        List<Workspace> workspaces = nuxeoWorkspace.getWorkspace();
-        String workspaceId = null;
-        for(Workspace workspace : workspaces){
-            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;
-                }
-            }
+        tenantBindingConfigReader = new TenantBindingConfigReader(getServerRootDir());
+        getTenantBindingConfigReader().read();
+    }
 
-            serviceWorkspaces.put(workspace.getServiceName(), workspaceId);
-            if(logger.isDebugEnabled()){
-                logger.debug("retrieved workspace id=" + workspaceId +
-                        " service=" + workspace.getServiceName() +
-                        " workspace=" + workspace.getWorkspaceName());
-            }
-        }
+    void retrieveAllWorkspaceIds() throws Exception {
+        //all configs are read, connector is initialized, retrieve workspaceids
+        getTenantBindingConfigReader().retrieveAllWorkspaceIds();
     }
 
     /**
-     * @return the serviceConfig
+     * retrieveWorkspaceIds for given tenant domain. 
+     * @param tenantDomain
+     * @return Hashtable<String, String> key=workspace name, value=workspace id
+     * @throws Exception
      */
-    public ServiceConfig getServiceConfig() {
-        return serviceConfig;
-    }
-
-    synchronized public String getWorkspaceId(String serviceName) {
-        return serviceWorkspaces.get(serviceName);
+    public Hashtable<String, String> retrieveWorkspaceIds(String tenantDomain) throws Exception {
+        return nuxeoConnector.retrieveWorkspaceIds(tenantDomain);
     }
 
     /**
@@ -180,9 +129,30 @@ public class ServiceMain {
     }
 
     /**
-     * @return the nuxeoClientType
+     * @return the serviceConfig
+     */
+    public ServiceConfig getServiceConfig() {
+        return getServicesConfigReader().getConfiguration();
+    }
+
+    /**
+     * @return the clientType
+     */
+    public ClientType getClientType() {
+        return getServicesConfigReader().getClientType();
+    }
+
+    /**
+     * @return the servicesConfigReader
+     */
+    public ServicesConfigReader getServicesConfigReader() {
+        return servicesConfigReader;
+    }
+
+    /**
+     * @return the tenantBindingConfigReader
      */
-    public NuxeoClientType getNuxeoClientType() {
-        return nuxeoClientType;
+    public TenantBindingConfigReader getTenantBindingConfigReader() {
+        return tenantBindingConfigReader;
     }
 }
diff --git a/services/common/src/main/java/org/collectionspace/services/common/config/AbstractConfigReader.java b/services/common/src/main/java/org/collectionspace/services/common/config/AbstractConfigReader.java
new file mode 100644 (file)
index 0000000..8621caa
--- /dev/null
@@ -0,0 +1,86 @@
+/**
+ *  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.config;
+
+import java.io.File;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Unmarshaller;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * AbstractConfigReader
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ */
+public abstract class AbstractConfigReader<T>
+        implements ConfigReader<T> {
+
+    private final Logger logger = LoggerFactory.getLogger(AbstractConfigReader.class);
+    private String serverRootDir;
+
+    AbstractConfigReader(String serverRootDir) {
+        this.serverRootDir = serverRootDir;
+    }
+
+    @Override
+    abstract public String getFileName();
+
+    @Override
+    abstract public void read() throws Exception;
+
+    @Override
+    abstract public T getConfiguration();
+
+
+    /**
+     * parse parses given configuration file from the disk based on given class
+     * definition
+     * @param configFile
+     * @param clazz
+     * @return A JAXB object
+     * @throws Exception
+     */
+    protected Object parse(File configFile, Class clazz) throws Exception {
+        JAXBContext jc = JAXBContext.newInstance(clazz);
+        Unmarshaller um = jc.createUnmarshaller();
+        Object readObject = um.unmarshal(configFile);
+        if(logger.isDebugEnabled()){
+            logger.debug("read() read file " + configFile.getAbsolutePath());
+        }
+        return readObject;
+    }
+
+    protected String getAbsoluteFileName(String configFileName) {
+        return serverRootDir +
+                File.separator + CSPACE_DIR_NAME +
+                File.separator + CONFIG_DIR_NAME +
+                File.separator + configFileName;
+    }
+
+    protected String getServerRootDir() {
+        return serverRootDir;
+    }
+}
diff --git a/services/common/src/main/java/org/collectionspace/services/common/config/ConfigReader.java b/services/common/src/main/java/org/collectionspace/services/common/config/ConfigReader.java
new file mode 100644 (file)
index 0000000..689841c
--- /dev/null
@@ -0,0 +1,54 @@
+/**
+ *  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.config;
+
+import java.io.File;
+
+/**
+ * ConfigReader is an interface for a configuration reader
+ */
+public interface ConfigReader<T> {
+
+    final public static String CSPACE_DIR_NAME = "cspace";
+    final public static String CONFIG_DIR_NAME = "config" + File.separator + "services";
+
+    /**
+     * getFileName - get configuration file name
+     * @return
+     */
+    public String getFileName();
+
+    /**
+     * read parse and read the configruation file.
+     * @throws Exception
+     */
+    public void read() throws Exception;
+
+    /**
+     * getConfig get configuration binding
+     * @return
+     */
+    public T getConfiguration();
+}
diff --git a/services/common/src/main/java/org/collectionspace/services/common/config/ServicesConfigReader.java b/services/common/src/main/java/org/collectionspace/services/common/config/ServicesConfigReader.java
new file mode 100644 (file)
index 0000000..9ce98de
--- /dev/null
@@ -0,0 +1,94 @@
+/**
+ *  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.config;
+
+import java.io.File;
+import org.collectionspace.services.common.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * ServicesConfigReader reads service layer specific configuration
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ */
+public class ServicesConfigReader
+        extends AbstractConfigReader<ServiceConfig> {
+
+    final private static String CONFIG_FILE_NAME = "service-config.xml";
+    final Logger logger = LoggerFactory.getLogger(ServicesConfigReader.class);
+    private ServiceConfig serviceConfig;
+    private ClientType clientType;
+    private String clientClassName;
+
+    public ServicesConfigReader(String serverRootDir) {
+        super(serverRootDir);
+    }
+
+    @Override
+    public String getFileName() {
+        return CONFIG_FILE_NAME;
+    }
+
+    @Override
+    public void read() throws Exception {
+        String configFileName = getAbsoluteFileName(CONFIG_FILE_NAME);
+        File configFile = new File(configFileName);
+        if(!configFile.exists()){
+            String msg = "Could not find configuration file " + configFileName;
+            logger.error(msg);
+            throw new RuntimeException(msg);
+        }
+        serviceConfig = (ServiceConfig) parse(configFile, ServiceConfig.class);
+        clientType = serviceConfig.getRepositoryClient().getClientType();
+        if(clientType == null){
+            String msg = "Missing <client-type> in <repository-client>";
+            logger.error(msg);
+            throw new IllegalArgumentException(msg);
+        }
+        clientClassName = serviceConfig.getRepositoryClient().getClientClass();
+        if(clientClassName == null){
+            String msg = "Missing <client-class> in <repository-client>";
+            logger.error(msg);
+            throw new IllegalArgumentException(msg);
+        }
+        if(logger.isDebugEnabled()){
+            logger.debug("using client=" + clientType.toString() + " class=" + clientClassName);
+        }
+    }
+
+    @Override
+    public ServiceConfig getConfiguration() {
+        return serviceConfig;
+    }
+
+    public ClientType getClientType() {
+        return clientType;
+    }
+
+    public String getClientClass() {
+        return clientClassName;
+    }
+}
diff --git a/services/common/src/main/java/org/collectionspace/services/common/config/TenantBindingConfigReader.java b/services/common/src/main/java/org/collectionspace/services/common/config/TenantBindingConfigReader.java
new file mode 100644 (file)
index 0000000..d6186a8
--- /dev/null
@@ -0,0 +1,193 @@
+/**
+ *  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.config;
+
+import java.io.File;
+import java.util.Hashtable;
+import java.util.List;
+import org.collectionspace.services.common.ClientType;
+import org.collectionspace.services.common.RepositoryWorkspaceType;
+import org.collectionspace.services.common.ServiceConfig;
+import org.collectionspace.services.common.ServiceMain;
+import org.collectionspace.services.common.service.ServiceBindingType;
+import org.collectionspace.services.common.tenant.TenantBindingType;
+import org.collectionspace.services.common.tenant.TenantBindingConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * ServicesConfigReader reads service layer specific configuration
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ */
+public class TenantBindingConfigReader
+        extends AbstractConfigReader<TenantBindingConfig> {
+
+    final private static String CONFIG_FILE_NAME = "tenant-bindings.xml";
+    final Logger logger = LoggerFactory.getLogger(TenantBindingConfigReader.class);
+    private TenantBindingConfig tenantBindingConfig;
+    //tenant name, tenant binding
+    private Hashtable<String, TenantBindingType> tenantBindings =
+            new Hashtable<String, TenantBindingType>();
+    //tenant-qualified servicename, service binding
+    private Hashtable<String, ServiceBindingType> serviceBindings =
+            new Hashtable<String, ServiceBindingType>();
+    //tenant-qualified service, workspace
+    private Hashtable<String, String> serviceWorkspaces = new Hashtable<String, String>();
+
+    public TenantBindingConfigReader(String serverRootDir) {
+        super(serverRootDir);
+    }
+
+    @Override
+    public String getFileName() {
+        return CONFIG_FILE_NAME;
+    }
+
+    @Override
+    public void read() throws Exception {
+        String configFileName = getAbsoluteFileName(CONFIG_FILE_NAME);
+        File configFile = new File(configFileName);
+        if(!configFile.exists()){
+            String msg = "Could not find configuration file " + configFileName;
+            logger.error(msg);
+            throw new RuntimeException(msg);
+        }
+        tenantBindingConfig = (TenantBindingConfig) parse(configFile, TenantBindingConfig.class);
+        for(TenantBindingType tenantBinding : tenantBindingConfig.getTenantBinding()){
+            tenantBindings.put(tenantBinding.getId(), tenantBinding);
+            readServiceBindings(tenantBinding);
+            if(logger.isDebugEnabled()){
+                logger.debug("read() added tenant id=" + tenantBinding.getId() +
+                        " name=" + tenantBinding.getName());
+            }
+        }
+    }
+
+    private void readServiceBindings(TenantBindingType tenantBinding) throws Exception {
+        for(ServiceBindingType serviceBinding : tenantBinding.getServiceBindings()){
+            String key = getTenantQualifiedServiceName(tenantBinding.getId(),
+                    serviceBinding.getName());
+            serviceBindings.put(key, serviceBinding);
+            if(logger.isDebugEnabled()){
+                logger.debug("readServiceBindings() added service " +
+                        " name=" + key +
+                        " workspace=" + serviceBinding.getName());
+            }
+        }
+    }
+
+    /**
+     * retrieveWorkspaceIds is called at initialization time to retrieve
+     * workspace ids of all the tenants
+     * @throws Exception
+     */
+    public void retrieveAllWorkspaceIds() throws Exception {
+        for(TenantBindingType tenantBinding : tenantBindings.values()){
+            retrieveWorkspaceIds(tenantBinding);
+        }
+    }
+
+    public void retrieveWorkspaceIds(TenantBindingType tenantBinding) throws Exception {
+        String tenantDomain = tenantBinding.getRepositoryDomain();
+        Hashtable<String, String> workspaceIds = new Hashtable<String, String>();
+        ServiceMain svcMain = ServiceMain.getInstance();
+        ClientType clientType = svcMain.getClientType();
+        if(clientType.equals(ClientType.JAVA)){
+            workspaceIds = svcMain.retrieveWorkspaceIds(tenantDomain);
+        }
+        for(ServiceBindingType serviceBinding : tenantBinding.getServiceBindings()){
+            String serviceName = serviceBinding.getName();
+            String workspaceId = null;
+            //workspace name is service name by convention
+            String workspace = serviceBinding.getName().toLowerCase();
+            if(clientType.equals(ClientType.JAVA)){
+                workspaceId = workspaceIds.get(workspace);
+                if(workspaceId == null){
+                    logger.warn("failed to retrieve workspace id for " + workspace);
+                    //FIXME: should we throw an exception here?
+                    continue;
+                }
+            }else{
+                workspaceId = serviceBinding.getRepositoryWorkspaceId();
+                if(workspaceId == null || "".equals(workspaceId)){
+                    logger.error("could not find workspace id for " + workspace);
+                    //FIXME: should we throw an exception here?
+                    continue;
+                }
+            }
+            String tenantService = getTenantQualifiedServiceName(tenantBinding.getId(), serviceName);
+            serviceWorkspaces.put(tenantService, workspaceId);
+            if(logger.isDebugEnabled()){
+                logger.debug("retrieved workspace id=" + workspaceId +
+                        " service=" + serviceName +
+                        " workspace=" + workspace);
+            }
+        }
+    }
+
+    @Override
+    public TenantBindingConfig getConfiguration() {
+        return tenantBindingConfig;
+    }
+
+    /**
+     * getTenantBinding gets tenant binding for given tenant
+     * @param tenantId
+     * @return
+     */
+    public TenantBindingType getTenantBinding(
+            String tenantId) {
+        return tenantBindings.get(tenantId);
+    }
+
+    /**
+     * getServiceBinding gets service binding for given tenant for a given service
+     * @param tenantId
+     * @param serviceName
+     * @return
+     */
+    public ServiceBindingType getServiceBinding(
+            String tenantId, String serviceName) {
+        String key = getTenantQualifiedServiceName(tenantId, serviceName);
+        return serviceBindings.get(key);
+    }
+
+    /**
+     * getWorkspaceId retrieves workspace id for given tenant for given service
+     * @param tenantId
+     * @param serviceName
+     * @return
+     */
+    public String getWorkspaceId(String tenantId, String serviceName) {
+        String tenantService = getTenantQualifiedServiceName(tenantId, serviceName);
+        return serviceWorkspaces.get(tenantService);
+    }
+
+    public static String getTenantQualifiedServiceName(
+            String tenantId, String serviceName) {
+        return tenantId + "." + serviceName.toLowerCase();
+    }
+}
diff --git a/services/common/src/main/java/org/collectionspace/services/common/context/ServiceContext.java b/services/common/src/main/java/org/collectionspace/services/common/context/ServiceContext.java
new file mode 100644 (file)
index 0000000..a74d556
--- /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.common.context;
+
+import java.io.IOException;
+import java.util.Map;
+import org.collectionspace.services.common.ClientType;
+import org.collectionspace.services.common.service.ObjectPartType;
+import org.collectionspace.services.common.service.ServiceBindingType;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
+import org.w3c.dom.Document;
+
+/**
+ *
+ * ServiceContext is used to pass along metadata and runtime context
+ * between various components of the service framework while processing
+ * a service request.
+ */
+public interface ServiceContext {
+
+    /**
+     * getTenantId get tenant id
+     * @return tenant id
+     */
+    public String getTenantId();
+
+    /**
+     * getTenantName get tenant name from the binding
+     * @return tenant name such as movingimage.us
+     */
+    public String getTenantName();
+
+    /**
+     * getServiceBinding gets service binding metadata
+     * @return service binding metadata
+     */
+    public ServiceBindingType getServiceBinding();
+
+    /**
+     * getServiceName returns the unqualified name of the service
+     * @return service name
+     */
+    public String getServiceName();
+
+    /**
+     * getQualifiedServiceName returns tenant id qualified service name
+     * @return tenant qualified service name
+     */
+    public String getQualifiedServiceName();
+
+    /**
+     * getRepositoryDomainName returns repository domain for the tenant
+     * @return repository domain for the tenant
+     */
+    public String getRepositoryDomainName();
+
+    /**
+     * getRepositoryClientName returns the repository client name as
+     * configured for the service
+     */
+    public String getRepositoryClientName();
+
+    /**
+     * getRepositoryClientType returns the type of client configured for the
+     * service layer
+     * @param ctx service context
+     * @return
+     */
+    public ClientType getRepositoryClientType();
+
+    /**
+     * getRepositoryWorkspaceName returns repository workspace for the service for
+     * the tenant. Not every service has a corresponding repository workspace.
+     * If the service does not have any repository workspace, this method
+     * returns null.
+     * @return repository workspace
+     */
+    public String getRepositoryWorkspaceName();
+
+    /**
+     * getRepositoryWorksapceId returns workspace id for the service for the
+     * tenant. Not every service has a corresponding repository workspace.
+     * If the service does not have any repository workspace, this method
+     * returns null.
+     * @return repository workspace
+     */
+    public String getRepositoryWorkspaceId();
+
+    /**
+     * setInput is used to set (multipart) request input before starting to
+     * process input data
+     * @param input multipart data input
+     * @exception IOException
+     */
+    public void setInput(MultipartInput input) throws IOException;
+
+    /**
+     * Get input parts as received over the wire from service consumer
+     * @return the input
+     */
+    public MultipartInput getInput();
+
+    /**
+     * Get output parts to send over the wire to service consumer
+     * @return the output
+     */
+    public MultipartOutput getOutput();
+
+    /**
+     * getInputPart returns part for given label from input
+     * @param label
+     * @param clazz class of the object
+     * @return part
+     */
+    public Object getInputPart(String label, Class clazz) throws IOException;
+
+    /**
+     * addOutputPart adds given XML part with given label and content type to output
+     * @param label
+     * @param document
+     * @param contentType media type
+     */
+    public void addOutputPart(String label, Document doc, String contentType) throws Exception;
+
+    /**
+     * getPartsMetadata returns metadata for object parts used by the service
+     * @return
+     */
+    public Map<String, ObjectPartType> getPartsMetadata();
+
+    /**
+     * getCommonPartLabel retruns label for common part of a service 
+     * @return label
+     */
+    public String getCommonPartLabel();
+}
+
+
+
diff --git a/services/common/src/main/java/org/collectionspace/services/common/context/ServiceContextImpl.java b/services/common/src/main/java/org/collectionspace/services/common/context/ServiceContextImpl.java
new file mode 100644 (file)
index 0000000..b88a6a7
--- /dev/null
@@ -0,0 +1,239 @@
+/**
+ *  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.context;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.ws.rs.core.MediaType;
+import org.collectionspace.services.common.ClientType;
+import org.collectionspace.services.common.ServiceMain;
+import org.collectionspace.services.common.config.TenantBindingConfigReader;
+import org.collectionspace.services.common.repository.DocumentUtils;
+import org.collectionspace.services.common.service.ObjectPartType;
+import org.collectionspace.services.common.service.ServiceBindingType;
+import org.collectionspace.services.common.service.ServiceObjectType;
+import org.collectionspace.services.common.tenant.TenantBindingType;
+import org.jboss.resteasy.plugins.providers.multipart.InputPart;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
+import org.jboss.resteasy.plugins.providers.multipart.OutputPart;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+
+/**
+ * ServiceContextImpl
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ */
+public class ServiceContextImpl
+        implements ServiceContext {
+
+    final Logger logger = LoggerFactory.getLogger(ServiceContextImpl.class);
+    private TenantBindingType tenantBinding;
+    private ServiceBindingType serviceBinding;
+    //input stores original content as received over the wire
+    private MultipartInput input;
+    private MultipartOutput output;
+    Map<String, ObjectPartType> objectPartMap = new HashMap<String, ObjectPartType>();
+
+    @Override
+    public String toString() {
+        return "ServiceContextImpl [" +
+                "service name=" + serviceBinding.getName() + " " +
+                "service version=" + serviceBinding.getVersion() + " " +
+                "tenant id=" + tenantBinding.getId() + " " +
+                "tenant name=" + tenantBinding.getName() + " " + tenantBinding.getDisplayName() + " " +
+                "tenant repository domain=" + tenantBinding.getRepositoryDomain() + " " +
+                "]";
+    }
+
+    public ServiceContextImpl(String serviceName) {
+        TenantBindingConfigReader tReader =
+                ServiceMain.getInstance().getTenantBindingConfigReader();
+        //TODO: get tenant binding from security context (Subject.g
+        String tenantId = "1"; //hardcoded for movingimages.us
+        tenantBinding = tReader.getTenantBinding(tenantId);
+        if(tenantBinding == null){
+            String msg = "No tenant binding found while processing request for " +
+                    serviceName;
+            logger.error(msg);
+            throw new IllegalStateException(msg);
+        }
+        serviceBinding = tReader.getServiceBinding(tenantId, serviceName);
+        if(serviceBinding == null){
+            String msg = "No service binding found while processing request for " +
+                    serviceName + " for tenant id=" + getTenantId() +
+                    " name=" + getTenantName();
+            logger.error(msg);
+            throw new IllegalStateException(msg);
+        }
+        if(logger.isDebugEnabled()){
+            logger.debug("tenantId=" + tenantId +
+                    " service binding=" + serviceBinding.getName());
+        }
+        output = new MultipartOutput();
+    }
+
+    @Override
+    public String getTenantId() {
+        return tenantBinding.getId();
+    }
+
+    @Override
+    public String getTenantName() {
+        return tenantBinding.getName();
+    }
+
+    @Override
+    public ServiceBindingType getServiceBinding() {
+        return serviceBinding;
+    }
+
+    @Override
+    public String getServiceName() {
+        return serviceBinding.getName();
+    }
+
+    @Override
+    public String getQualifiedServiceName() {
+        return TenantBindingConfigReader.getTenantQualifiedServiceName(
+                getTenantId(), getServiceName());
+    }
+
+    @Override
+    public String getRepositoryDomainName() {
+        return tenantBinding.getRepositoryDomain();
+    }
+
+    @Override
+    public String getRepositoryClientName() {
+        return serviceBinding.getRepositoryClient();
+    }
+
+    @Override
+    public ClientType getRepositoryClientType() {
+        //assumption: there is only one repository client configured
+        return ServiceMain.getInstance().getClientType();
+    }
+
+    @Override
+    public String getRepositoryWorkspaceName() {
+        //service name is workspace name by convention
+        return serviceBinding.getName();
+    }
+
+    @Override
+    public String getRepositoryWorkspaceId() {
+        TenantBindingConfigReader tbConfigReader =
+                ServiceMain.getInstance().getTenantBindingConfigReader();
+        return tbConfigReader.getWorkspaceId(getTenantId(), getServiceName());
+    }
+
+    @Override
+    public MultipartInput getInput() {
+        return input;
+    }
+
+    @Override
+    public MultipartOutput getOutput() {
+        return output;
+    }
+
+    @Override
+    public Object getInputPart(String label, Class clazz) throws IOException {
+        Object obj = null;
+        if(getInput() != null){
+            MultipartInput fdip = getInput();
+
+            for(InputPart part : fdip.getParts()){
+                String partLabel = part.getHeaders().getFirst("label");
+                if(label.equalsIgnoreCase(partLabel)){
+                    if(logger.isDebugEnabled()){
+                        logger.debug("received part label=" + partLabel +
+                                "\npayload=" + part.getBodyAsString());
+                    }
+                    obj = part.getBody(clazz, null);
+                    break;
+                }
+            }
+        }
+        return obj;
+    }
+
+    @Override
+    public void addOutputPart(String label, Document doc, String contentType) throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try{
+            DocumentUtils.writeDocument(doc, baos);
+            baos.close();
+            OutputPart part = output.addPart(new String(baos.toByteArray()),
+                    MediaType.valueOf(contentType));
+            part.getHeaders().add("label", label);
+        }finally{
+            if(baos != null){
+                try{
+                    baos.close();
+                }catch(Exception e){
+                }
+            }
+        }
+    }
+
+    @Override
+    public void setInput(MultipartInput input) throws IOException {
+        this.input = input;
+    }
+
+    @Override
+    public Map<String, ObjectPartType> getPartsMetadata() {
+        if(objectPartMap.size() != 0){
+            return objectPartMap;
+        }
+
+        ServiceBindingType serviceBinding = getServiceBinding();
+        List<ServiceObjectType> objectTypes = serviceBinding.getObject();
+        for(ServiceObjectType objectType : objectTypes){
+            List<ObjectPartType> objectPartTypes = objectType.getPart();
+            for(ObjectPartType objectPartType : objectPartTypes){
+                objectPartMap.put(objectPartType.getLabel(), objectPartType);
+            }
+
+        }
+        return objectPartMap;
+    }
+
+    /**
+     * getCommonPartLabel get common part label
+     * @return
+     */
+    @Override
+    public String getCommonPartLabel() {
+        return getServiceName().toLowerCase() + "-common";
+    }
+}
diff --git a/services/common/src/main/java/org/collectionspace/services/common/repository/AbstractDocumentHandler.java b/services/common/src/main/java/org/collectionspace/services/common/repository/AbstractDocumentHandler.java
new file mode 100644 (file)
index 0000000..367def5
--- /dev/null
@@ -0,0 +1,188 @@
+/**
+ *  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.HashMap;
+import java.util.Map;
+
+import java.util.StringTokenizer;
+import org.collectionspace.services.common.context.ServiceContext;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * AbstractDocumentHandler
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ */
+public abstract class AbstractDocumentHandler<T, TL>
+        implements DocumentHandler<T, TL> {
+
+    private final Logger logger = LoggerFactory.getLogger(AbstractDocumentHandler.class);
+    private Map<String, Object> properties = new HashMap<String, Object>();
+    private ServiceContext serviceContext;
+
+    public AbstractDocumentHandler() {
+    }
+
+    @Override
+    public ServiceContext getServiceContext() {
+        return serviceContext;
+    }
+
+    @Override
+    public void setServiceContext(ServiceContext ctx) {
+        serviceContext = ctx;
+    }
+
+    /**
+     * @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;
+    }
+
+    @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;
+
+        }
+    }
+
+    @Override
+    public abstract void handleCreate(DocumentWrapper wrapDoc) throws Exception;
+
+    @Override
+    public abstract void handleUpdate(DocumentWrapper wrapDoc) throws Exception;
+
+    @Override
+    public abstract void handleGet(DocumentWrapper wrapDoc) throws Exception;
+
+    @Override
+    public abstract void handleGetAll(DocumentWrapper wrapDoc) throws Exception;
+
+    @Override
+    public void complete(Action action, DocumentWrapper wrapDoc) throws Exception {
+        switch(action){
+            //TODO: add more actions if needed
+            case UPDATE:
+                completeUpdate(wrapDoc);
+                break;
+        }
+    }
+
+    @Override
+    public void completeUpdate(DocumentWrapper wrapDoc) throws Exception {
+        //no specific action needed
+    }
+
+    @Override
+    public abstract void extractAllParts(DocumentWrapper wrapDoc)
+            throws Exception;
+
+    @Override
+    public abstract void fillAllParts(DocumentWrapper wrapDoc)
+            throws Exception;
+
+    @Override
+    public abstract T extractCommonPart(DocumentWrapper wrapDoc)
+            throws Exception;
+
+    @Override
+    public abstract void fillCommonPart(T obj, DocumentWrapper wrapDoc)
+            throws Exception;
+
+    @Override
+    public abstract TL extractCommonPartList(DocumentWrapper wrapDoc)
+            throws Exception;
+
+    @Override
+    final public void fillCommonPartList(TL obj, DocumentWrapper wrapDoc) throws Exception {
+        throw new UnsupportedOperationException("bulk create/update not yet supported");
+    }
+
+    @Override
+    public abstract T getCommonPart();
+
+    @Override
+    public abstract void setCommonPart(T obj);
+
+    @Override
+    public abstract TL getCommonPartList();
+
+    @Override
+    public abstract void setCommonPartList(TL obj);
+
+    @Override
+    public abstract String getQProperty(String prop);
+
+    @Override
+    public String getUnQProperty(String qProp) {
+        StringTokenizer tkz = new StringTokenizer(qProp, ":");
+        if(tkz.countTokens() != 2){
+            String msg = "Property must be in the form xxx:yyy, " +
+                    "e.g. collectionobjects-common:objectNumber";
+            logger.error(msg);
+            throw new IllegalArgumentException(msg);
+        }
+        tkz.nextToken(); //skip
+        return tkz.nextToken();
+    }
+
+    @Override
+    public String getServiceContextPath() {
+        return "/" + getServiceContext().getServiceName().toLowerCase() + "/";
+    }
+}
index 39043b068ebbd5a3dcc3133c9ac463bf64ed0e39..826b7eb03ddce70d8f1c331bd6bd80415869b8eb 100644 (file)
@@ -20,7 +20,7 @@ package org.collectionspace.services.common.repository;
 
 /**
  * DocumentException
- * Nuxeo document handling exception
+ * document handling exception
  */
 public class DocumentException extends Exception {
 
index f3f3e251226646fc2565190ebf592e003fa5c826..5afe00bcb4c151d8d7c51d5ac6ea6b40dadc28f8 100644 (file)
  */
 package org.collectionspace.services.common.repository;
 
-import org.collectionspace.services.common.repository.DocumentWrapper;
-import org.collectionspace.services.common.repository.DocumentException;
+import java.io.IOException;
 import java.util.Map;
-import org.dom4j.Document;
+import org.collectionspace.services.common.context.ServiceContext;
+import org.w3c.dom.Document;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
 
 /**
  *
  * DocumentHandler provides document processing methods. It is an interface
- * between Nuxeo repository client and CollectionSpace service resource. It provides
+ * between repository client and CollectionSpace service resource. It provides
  * methods to setup request via repository client and handle its response.
  *
  * Typical call sequence is:
@@ -43,8 +45,26 @@ public interface DocumentHandler<T, TL> {
     }
 
     /**
-     * prepare is called by the Nuxeo client to prepare required parameters to set
-     * before invoking repository operation. this is mainly useful for create and 
+     * getServiceContext returns service context
+     * @return
+     */
+    public ServiceContext getServiceContext();
+
+    /**
+     * getServiceContextPath such as "/collectionobjects/"
+     * @return
+     */
+    public String getServiceContextPath();
+
+    /**
+     * setServiceContext sets service contex to the handler
+     * @param ctx
+     */
+    public void setServiceContext(ServiceContext ctx);
+
+    /**
+     * prepare is called by the client for preparation of stuff before
+     * invoking repository operation. this is mainly useful for create and 
      * update kind of actions
      * @param action
      * @throws Exception
@@ -52,108 +72,117 @@ public interface DocumentHandler<T, TL> {
     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
+     * handle is called by the client to hand over the document processing task
      * @param action 
-     * @param doc wrapped Nuxeo doc
+     * @param doc wrapped doc
      * @throws Exception
      */
     public void handle(Action action, DocumentWrapper docWrap) throws Exception;
 
-        /**
-     * handleCreate processes create operation response
+    /**
+     * handleCreate processes documents before creating document in repository
      * @param wrapDoc
      * @throws Exception
      */
     public void handleCreate(DocumentWrapper wrapDoc) throws Exception;
 
     /**
-     * handleUpdate processes update operation response
+     * handleUpdate processes documents for the update of document in repository
      * @param wrapDoc
      * @throws Exception
      */
     public void handleUpdate(DocumentWrapper wrapDoc) throws Exception;
 
     /**
-     * handleGet processes get operation response
+     * handleGet processes documents from repository before responding to consumer
      * @param wrapDoc
      * @throws Exception
      */
     public void handleGet(DocumentWrapper wrapDoc) throws Exception;
 
     /**
-     * handleGetAll processes index operation response
+     * handleGetAll processes documents from repository before responding to consumer
      * @param wrapDoc
      * @throws Exception
      */
     public void handleGetAll(DocumentWrapper wrapDoc) throws Exception;
-    
+
     /**
-     * extractCommonObject extracts common part of a CS document from given Nuxeo document.
-     * @param docWrap nuxeo document
-     * @return common part of CS object
+     * complete is called by the client to provide an opportunity to the handler
+     * to take care of stuff before closing session with the repository. example
+     * could be to reclaim resources or to populate response to the consumer
+     * @param wrapDoc
      * @throws Exception
      */
-    public T extractCommonObject(DocumentWrapper docWrap) throws Exception;
+    public void complete(Action action, DocumentWrapper wrapDoc) throws Exception;
 
     /**
-     * fillCommonObject sets common part of CS object into given Nuxeo document
-     * @param obj input object
-     * @param docWrap target Nuxeo document
+     * completeUpdate is called by the client to indicate completion of the update call.
+     * this gives opportunity to prepare updated object that should be sent back to the consumer
+     * @param wrapDoc
      * @throws Exception
      */
-    public void fillCommonObject(T obj, DocumentWrapper docWrap) throws Exception;
+    public void completeUpdate(DocumentWrapper wrapDoc) throws Exception;
 
-        /**
-     * extractCommonObject extracts common part of a CS document from given Nuxeo document.
-     * @param docWrap nuxeo document
-     * @return common part of CS object
+    /**
+     * extractAllParts extracts all parts of a CS object from given document.
+     * this is usually called AFTER the get operation is invoked on the repository
+     * Called in handle GET/GET_ALL actions.
+     * @param docWrap document
      * @throws Exception
      */
-    public TL extractCommonObjectList(DocumentWrapper docWrap) throws Exception;
+    public void extractAllParts(DocumentWrapper docWrap) throws Exception;
 
     /**
-     * fillCommonObject sets common part of CS object into given Nuxeo document
+     * fillAllParts sets parts of CS object into given document
+     * this is usually called BEFORE create/update operations are invoked on the
+     * repository. Called in handle CREATE/UPDATE actions.
      * @param obj input object
-     * @param docWrap target Nuxeo document
+     * @param docWrap target document
      * @throws Exception
      */
-    public void fillCommonObjectList(TL obj, DocumentWrapper docWrap) throws Exception;
+    public void fillAllParts(DocumentWrapper docWrap) throws Exception;
 
     /**
-     * getCommonObject provides the common part of a CS document.
-     * @return common part of CS document
+     * extractCommonPart extracts common part of a CS object from given document.
+     * this is usually called AFTER the get operation is invoked on the repository.
+     * Called in handle GET/GET_ALL actions.
+     * @param docWrap document
+     * @return common part of CS object
+     * @throws Exception
      */
-    public T getCommonObject();
+    public T extractCommonPart(DocumentWrapper docWrap) throws Exception;
 
     /**
-     * setCommonObject sets common part of CS document as input for operation on
-     * Nuxeo repository
+     * fillCommonPart sets common part of CS object into given document
+     * this is usually called BEFORE create/update operations are invoked on the
+     * repository. Called in handle CREATE/UPDATE actions.
      * @param obj input object
+     * @param docWrap target document
+     * @throws Exception
      */
-    public void setCommonObject(T obj);
+    public void fillCommonPart(T obj, DocumentWrapper docWrap) throws Exception;
 
     /**
-     * getCommonObjectList provides the default list object of a CS document.
-     * @return default list of CS document
+     * extractCommonPart extracts common part of a CS object from given document.
+     * this is usually called AFTER bulk get (index/list) operation is invoked on
+     * the repository
+     * @param docWrap document
+     * @return common part of CS object
+     * @throws Exception
      */
-    public TL getCommonObjectList();
+    public TL extractCommonPartList(DocumentWrapper docWrap) throws Exception;
 
     /**
-     * setCommonObjectList sets default list object for CS document as input for operation on
-     * Nuxeo repository
-     * @param default list of CS document
+     * fillCommonPartList sets list common part of CS object into given document
+     * this is usually called BEFORE bulk create/update on the repository
+     * (not yet supported)
+     * @param obj input object
+     * @param docWrap target document
+     * @throws Exception
      */
-    public void setCommonObjectList(TL obj);
+    public void fillCommonPartList(TL obj, DocumentWrapper docWrap) throws Exception;
 
-    /**
-     * getDocument get org.dom4j.Document from given DocumentModel
-     * @param Nuxeo document wrapper
-     * @return
-     * @throws DocumentException
-     */
-    public Document getDocument(DocumentWrapper docWrap) throws DocumentException;
-    
     /**
      * Gets the document type.
      * 
@@ -169,8 +198,48 @@ public interface DocumentHandler<T, TL> {
 
     /**
      * setProperties provides means to the CollectionSpace service resource to
-     * set up parameters before invoking create request via the Nuxeo client.
+     * set up parameters before invoking any request via the client.
      * @param properties
      */
     public void setProperties(Map<String, Object> properties);
+
+    /**
+     * getCommonPart provides the common part of a CS object.
+     * @return common part of CS object
+     */
+    public T getCommonPart();
+
+    /**
+     * setCommonPart sets common part of CS object as input for operation on
+     * repository
+     * @param obj input object
+     */
+    public void setCommonPart(T obj);
+
+    /**
+     * getCommonPartList provides the default list object of a CS object.
+     * @return default list of CS object
+     */
+    public TL getCommonPartList();
+
+    /**
+     * setCommonPartList sets common part list entry for CS object as input for operation on
+     * repository
+     * @param default list of CS object
+     */
+    public void setCommonPartList(TL obj);
+
+    /**
+     * getQProperty get qualified property (useful for mapping to repository document property)
+     * @param prop
+     * @return
+     */
+    public String getQProperty(String prop);
+
+    /**
+     * getUnQProperty unqualifies document property from repository
+     * @param qProp qualifeid property
+     * @return unqualified property
+     */
+    public String getUnQProperty(String qProp);
 }
diff --git a/services/common/src/main/java/org/collectionspace/services/common/repository/DocumentUtils.java b/services/common/src/main/java/org/collectionspace/services/common/repository/DocumentUtils.java
new file mode 100644 (file)
index 0000000..2560842
--- /dev/null
@@ -0,0 +1,172 @@
+/**
+ *  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.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Map;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import org.collectionspace.services.common.service.ObjectPartContentType;
+import org.collectionspace.services.common.service.ObjectPartType;
+import org.collectionspace.services.common.service.XmlContentType;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+/**
+* DocumentUtils is a collection of utilities related to document management
+*
+* $LastChangedRevision: $
+* $LastChangedDate: $
+*/
+public class DocumentUtils {
+
+    /**
+     * parseProperties given payload to create XML document. this
+     * method also closes given stream after parsing.
+     * @param payload stream
+     * @return parsed Document
+     * @throws Exception
+     */
+    public static Document parseDocument(InputStream payload)
+            throws Exception {
+        try{
+            // Create a builder factory
+            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+            factory.setValidating(false);//TODO take validating value from meta
+
+            // Create the builder and parse the file
+            return factory.newDocumentBuilder().parse(payload);
+
+        }finally{
+            if(payload != null){
+                payload.close();
+            }
+
+        }
+    }
+
+    /**
+     * parseProperties extract given payload (XML) into Name-Value properties. this
+     * @param document to parse
+     * @return map key=property name, value=property value
+     * @throws Exception
+     */
+    public static Map<String, Object> parseProperties(Document document)
+            throws Exception {
+        HashMap<String, Object> objectProps = new HashMap<String, Object>();
+        // Get a list of all elements in the document
+        Node root = document.getFirstChild();
+        NodeList children = root.getChildNodes();
+        for(int i = 0; i < children.getLength(); i++){
+            Node node = (Node) children.item(i);
+            if(node.getNodeType() == Node.ELEMENT_NODE){
+                Node cnode = node.getFirstChild();
+                if(cnode.getNodeType() != Node.TEXT_NODE){
+                    continue;
+                }
+                Node textNode = (Text) cnode;
+                objectProps.put(node.getNodeName(),
+                        textNode.getNodeValue());
+            }
+        }
+        return objectProps;
+    }
+
+    /**
+     * buildDocument builds org.w3c.dom.Document from given properties using
+     * given metadata for a part
+     * @param partMeta
+     * @param rootElementName
+     * @param objectProps
+     * @return
+     * @throws Exception
+     */
+    public static Document buildDocument(ObjectPartType partMeta, String rootElementName,
+            Map<String, Object> objectProps)
+            throws Exception {
+        ObjectPartContentType partContentMeta = partMeta.getContent();
+        XmlContentType xc = partContentMeta.getXmlContent();
+        if(xc == null){
+            return null;
+        }
+
+        DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+        Document document = builder.newDocument();
+        document.setXmlStandalone(true);
+        //JAXB unmarshaller recognizes the following kind of namespace qualification
+        //only. More investigation is needed to use other prefix
+//        <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+//        <ns2:collectionobjects-common xmlns:ns2="http://collectionspace.org/services/collectionobject">
+//        <objectNumber>objectNumber-1252960222412</objectNumber>
+//        <objectName>objectName-1252960222412</objectName>
+//        </ns2:collectionobjects-common>
+
+        String ns = "ns2";
+        Element root = document.createElementNS(xc.getNamespaceURI(), ns + ":" + rootElementName);
+        root.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
+        root.setAttribute("xsi:schemaLocation", xc.getSchemaLocation());
+        root.setAttribute("xmlns:" + ns, xc.getNamespaceURI());
+        document.appendChild(root);
+
+        for(String prop : objectProps.keySet()){
+            Object value = objectProps.get(prop);
+            if(value != null){
+                //no need to qualify each element name as namespace is already added
+                Element e = document.createElement(prop);
+                root.appendChild(e);
+                String strValue = objectProps.get(prop).toString();
+                Text tNode = document.createTextNode(strValue);
+                e.appendChild(tNode);
+            }
+        }
+        return document;
+    }
+
+    /**
+     * writeDocument streams out given document to given output stream
+     * @param document
+     * @param os
+     * @throws Exception
+     */
+    public static void writeDocument(Document document, OutputStream os) throws Exception {
+        TransformerFactory tFactory =
+                TransformerFactory.newInstance();
+        Transformer transformer = tFactory.newTransformer();
+        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+        DOMSource source = new DOMSource(document);
+        StreamResult result = new StreamResult(os);
+        transformer.transform(source, result);
+    }
+}
index 433db1f0cafe48df263e6072244a29d09e352a0e..d2bfa6bdb0086f9558a1283c205b65e545f43ad2 100644 (file)
@@ -23,6 +23,8 @@
  */
 package org.collectionspace.services.common.repository;
 
+import org.collectionspace.services.common.context.ServiceContext;
+
 
 /**
  * RepositoryClient is a generic Document Repository client
@@ -38,52 +40,50 @@ 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 serviceName entity service for which document is created. this is used to find mapping
-     * to a Nuxeo workspace using service-config.xml
+     * @param ctx service context under which this method is invoked
      * @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, DocumentHandler handler) throws BadRequestException, DocumentException;
+    String create(ServiceContext ctx, DocumentHandler handler) throws BadRequestException, DocumentException;
 
     /**
      * delete a document from the Document repository
+     * @param ctx service context under which this method is invoked
      * @param id of the document
      * @throws DocumentNotFoundException if document not found
      * @throws DocumentException
      */
-    void delete(String id) throws DocumentNotFoundException, DocumentException;
+    void delete(ServiceContext ctx, String id) throws DocumentNotFoundException, DocumentException;
 
     /**
      * get document from the Document repository
+     * @param ctx service context under which this method is invoked
      * @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;
+    void get(ServiceContext ctx, 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 ctx service context under which this method is invoked
      * @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;
+    void getAll(ServiceContext ctx, DocumentHandler handler) throws DocumentNotFoundException, DocumentException;
 
     /**
      * update given document in the Document repository
+     * @param ctx service context under which this method is invoked
      * @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;
+    void update(ServiceContext ctx, String id, DocumentHandler handler) throws BadRequestException, DocumentNotFoundException, DocumentException;
 }
index c14549322e22e38870e0cfb20d226f9387d5cd2c..0159fc0e8dc9ed763627b2a064bd9c2a5589a4b1 100644 (file)
  */
 package org.collectionspace.services.common.repository;
 
+import java.lang.ClassLoader;
 import java.util.Hashtable;
-import org.collectionspace.services.common.NuxeoClientType;
+import org.collectionspace.services.common.RepositoryClientConfigType;
+import org.collectionspace.services.common.ServiceMain;
+import org.collectionspace.services.common.config.ServicesConfigReader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
- * RepositoryClientFactory is a singleton factory that provides required Nuxeo client
- * it does not create clients as the clients are singletons
+ * RepositoryClientFactory is a singleton factory that creates required repository
+ * clients. Repository clients are singletons.
  *
  * $LastChangedRevision: $
  * $LastChangedDate: $
  */
 public class RepositoryClientFactory {
 
-    
     private static final RepositoryClientFactory self = new RepositoryClientFactory();
+    final Logger logger = LoggerFactory.getLogger(RepositoryClientFactory.class);
+    //clients key=client name, value=repository client
     private Hashtable<String, RepositoryClient> clients = new Hashtable<String, RepositoryClient>();
 
     private RepositoryClientFactory() {
         try{
+            ServicesConfigReader scReader = ServiceMain.getInstance().getServicesConfigReader();
+            RepositoryClientConfigType repositoryClientConfig = scReader.getConfiguration().getRepositoryClient();
+            String clientClassName = repositoryClientConfig.getClientClass();
+            String clientName = repositoryClientConfig.getName();
             ClassLoader cloader = Thread.currentThread().getContextClassLoader();
 
-            Class jclazz = cloader.loadClass("org.collectionspace.services.nuxeo.client.java.RepositoryJavaClient");
+            Class jclazz = cloader.loadClass(clientClassName);
             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);
+            clients.put(clientName, (RepositoryClient) jclient);
 
         }catch(Exception e){
             throw new RuntimeException(e);
@@ -60,7 +66,12 @@ public class RepositoryClientFactory {
         return self;
     }
 
-    public RepositoryClient getClient(String clientType) {
-        return clients.get(clientType);
+    /**
+     * get repository client
+     * @param clientName name of the client as found in service binding
+     * @return
+     */
+    public RepositoryClient getClient(String clientName) {
+        return clients.get(clientName);
     }
 }
index 3bb10b3955aecf129e8e6983eea1d487315112b3..977d31b31329849736683c63fadc5d0f444cfa75 100644 (file)
  */
 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.io.InputStream;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import javax.ws.rs.core.MediaType;
+import org.collectionspace.services.common.repository.DocumentWrapper;
+import org.collectionspace.services.common.repository.AbstractDocumentHandler;
+import org.collectionspace.services.common.repository.BadRequestException;
+import org.collectionspace.services.common.repository.DocumentUtils;
+import org.collectionspace.services.common.service.ObjectPartType;
 import org.collectionspace.services.nuxeo.client.*;
-import org.collectionspace.services.nuxeo.util.NuxeoUtils;
-import org.dom4j.Document;
+import org.jboss.resteasy.plugins.providers.multipart.InputPart;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
 import org.nuxeo.ecm.core.api.DocumentModel;
 import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
 
 /**
  * DocumentModelHandler is a base abstract Nuxeo document handler
@@ -44,132 +52,170 @@ import org.slf4j.LoggerFactory;
  * $LastChangedDate: $
  */
 public abstract class DocumentModelHandler<T, TL>
-        implements DocumentHandler<T, TL> {
+        extends AbstractDocumentHandler<T, TL> {
 
     private final Logger logger = LoggerFactory.getLogger(DocumentModelHandler.class);
-    private Map<String, Object> properties = new HashMap<String, Object>();
     private RepositoryInstance repositorySession;
+    //key=schema, value=documentpart
 
-    @Override
-    public abstract void prepare(Action action) throws Exception;
+    /**
+     * getRepositorySession returns Nuxeo Repository Session
+     * @return
+     */
+    public RepositoryInstance getRepositorySession() {
+        return repositorySession;
+    }
 
-    @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;
-        }
+    /**
+     * setRepositorySession sets repository session
+     * @param repoSession
+     */
+    public void setRepositorySession(RepositoryInstance repoSession) {
+        this.repositorySession = repoSession;
     }
 
     @Override
     public void handleCreate(DocumentWrapper wrapDoc) throws Exception {
-        if(getCommonObject() == null){
-            String msg = "Error creating document: Missing input data";
-            logger.error(msg);
-            throw new IllegalStateException(msg);
-        }
-        //FIXME set other parts as well
-        fillCommonObject(getCommonObject(), wrapDoc);
+        fillAllParts(wrapDoc);
     }
 
     @Override
     public void handleUpdate(DocumentWrapper wrapDoc) throws Exception {
-        if(getCommonObject() == null){
-            String msg = "Error updating document: Missing input data";
-            logger.error(msg);
-            throw new IllegalStateException(msg);
-        }
-        //FIXME set other parts as well
-        fillCommonObject(getCommonObject(), wrapDoc);
+        fillAllParts(wrapDoc);
     }
 
     @Override
     public void handleGet(DocumentWrapper wrapDoc) throws Exception {
-        setCommonObject(extractCommonObject(wrapDoc));
-
-        //FIXME retrive other parts as well
+        extractAllParts(wrapDoc);
     }
 
     @Override
     public void handleGetAll(DocumentWrapper wrapDoc) throws Exception {
-        setCommonObjectList(extractCommonObjectList(wrapDoc));
+        setCommonPartList(extractCommonPartList(wrapDoc));
     }
 
-    /**
-     * getRepositorySession returns Nuxeo Repository Session
-     * @return
-     */
-    public RepositoryInstance getRepositorySession() {
-        return repositorySession;
+    @Override
+    public void completeUpdate(DocumentWrapper wrapDoc) throws Exception {
+        DocumentModel docModel = (DocumentModel) wrapDoc.getWrappedObject();
+        //return at least those document part(s) that were received
+        Map<String, ObjectPartType> partsMetaMap = getServiceContext().getPartsMetadata();
+        List<InputPart> inputParts = getServiceContext().getInput().getParts();
+        for(InputPart part : inputParts){
+            String partLabel = part.getHeaders().getFirst("label");
+            ObjectPartType partMeta = partsMetaMap.get(partLabel);
+            extractObject(docModel, partLabel, partMeta);
+        }
     }
 
-    /**
-     * setRepositorySession sets repository session
-     * @param repoSession
-     */
-    public void setRepositorySession(RepositoryInstance repoSession) {
-        this.repositorySession = repoSession;
+    @Override
+    public void extractAllParts(DocumentWrapper wrapDoc) throws Exception {
+
+        DocumentModel docModel = (DocumentModel) wrapDoc.getWrappedObject();
+        String[] schemas = docModel.getDeclaredSchemas();
+        Map<String, ObjectPartType> partsMetaMap = getServiceContext().getPartsMetadata();
+        for(String schema : schemas){
+            ObjectPartType partMeta = partsMetaMap.get(schema);
+            if(partMeta == null){
+                continue; //unknown part, ignore
+            }
+            extractObject(docModel, schema, partMeta);
+        }
     }
 
     @Override
-    public abstract T extractCommonObject(DocumentWrapper wrapDoc) throws Exception;
+    public abstract T extractCommonPart(DocumentWrapper wrapDoc) throws Exception;
 
     @Override
-    public abstract void fillCommonObject(T obj, DocumentWrapper wrapDoc) throws Exception;
+    public void fillAllParts(DocumentWrapper wrapDoc) throws Exception {
 
-    @Override
-    public abstract TL extractCommonObjectList(DocumentWrapper wrapDoc) throws Exception;
+        //TODO filling extension parts should be dynamic
+        //Nuxeo APIs lack to support stream/byte[] input, get/setting properties is
+        //not an ideal way of populating objects.
+        DocumentModel docModel = (DocumentModel) wrapDoc.getWrappedObject();
+        MultipartInput input = getServiceContext().getInput();
+        if(input.getParts().isEmpty()){
+            String msg = "No payload found!";
+            logger.error(msg + "Ctx=" + getServiceContext().toString());
+            throw new BadRequestException(msg);
+        }
+
+        Map<String, ObjectPartType> partsMetaMap = getServiceContext().getPartsMetadata();
+
+        //iterate over parts received and fill those parts
+        List<InputPart> inputParts = input.getParts();
+        for(InputPart part : inputParts){
+
+            String partLabel = part.getHeaders().getFirst("label");
+            //skip if the part is not in metadata
+            if(!partsMetaMap.containsKey(partLabel)){
+                continue;
+            }
+            InputStream payload = part.getBody(InputStream.class, null);
+
+            //check if this is an xml part
+            if(part.getMediaType().equals(MediaType.APPLICATION_XML_TYPE)){
+                if(payload != null){
+                    Document document = DocumentUtils.parseDocument(payload);
+                    //TODO: callback to handler if registered to validate the
+                    //document
+                    Map<String, Object> objectProps = DocumentUtils.parseProperties(document);
+                    docModel.setProperties(partLabel, objectProps);
+                }
+            }
+        }//rof
+
+    }
 
     @Override
-    public abstract void fillCommonObjectList(TL obj, DocumentWrapper wrapDoc) throws Exception;
+    public abstract void fillCommonPart(T obj, DocumentWrapper wrapDoc) throws Exception;
 
     @Override
-    public abstract T getCommonObject();
+    public abstract TL extractCommonPartList(DocumentWrapper wrapDoc) throws Exception;
 
     @Override
-    public abstract void setCommonObject(T obj);
+    public abstract T getCommonPart();
 
     @Override
-    public abstract TL getCommonObjectList();
+    public abstract void setCommonPart(T obj);
 
     @Override
-    public abstract void setCommonObjectList(TL obj);
+    public abstract TL getCommonPartList();
 
     @Override
-    public Document getDocument(DocumentWrapper wrapDoc) throws DocumentException {
-        DocumentModel docModel = (DocumentModel) wrapDoc.getWrappedObject();
-        return NuxeoUtils.getDocument(getRepositorySession(), docModel);
-    }
-    
+    public abstract void setCommonPartList(TL obj);
+
     /* (non-Javadoc)
      * @see org.collectionspace.services.common.repository.DocumentHandler#getDocumentType()
      */
     @Override
     public abstract String getDocumentType();
-    
-    /**
-     * @return the properties
-     */
-    @Override
-    public Map<String, Object> getProperties() {
-        return properties;
-    }
 
     /**
-     * @param properties the properties to set
+     * extractObject extracts an XML object from given DocumentModel
+     * @param docModel
+     * @param schema of the object to extract
+     * @param partMeta metadata for the object to extract
+     * @throws Exception
      */
-    @Override
-    public void setProperties(Map<String, Object> properties) {
-        this.properties = properties;
+    protected void extractObject(DocumentModel docModel, String schema, ObjectPartType partMeta)
+            throws Exception {
+        MediaType mt = MediaType.valueOf(partMeta.getContent().getContentType());
+        if(mt.equals(MediaType.APPLICATION_XML_TYPE)){
+            Map<String, Object> objectProps = docModel.getProperties(schema);
+            //unqualify properties before sending the doc over the wire (to save bandwidh)
+            //FIXME: is there a better way to avoid duplication of a collection?
+            Map<String, Object> unQObjectProperties = new HashMap<String, Object>();
+            Set<Entry<String, Object>> qualifiedEntries = objectProps.entrySet();
+            for(Entry<String, Object> entry : qualifiedEntries){
+                String unqProp = getUnQProperty(entry.getKey());
+                unQObjectProperties.put(unqProp, entry.getValue());
+            }
+            Document doc = DocumentUtils.buildDocument(partMeta, schema, unQObjectProperties);
+            if(logger.isDebugEnabled()){
+                DocumentUtils.writeDocument(doc, System.out);
+            }
+            getServiceContext().addOutputPart(schema, doc, partMeta.getContent().getContentType());
+        } //TODO: handle other media types
     }
+
 }
index adde28f86aff37ef87269a0fa487a45a090d3292..de56a8a57e846d4ff6fa8c3e31d74443cd897d7f 100644 (file)
@@ -27,7 +27,7 @@ import java.io.File;
 import java.util.Collection;
 import java.util.Hashtable;
 import java.util.Iterator;
-import org.collectionspace.services.common.ServiceConfig.NuxeoClientConfig;
+import org.collectionspace.services.common.RepositoryClientConfigType;
 import org.nuxeo.ecm.core.api.DocumentModel;
 import org.nuxeo.ecm.core.api.DocumentModelList;
 import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
@@ -48,7 +48,7 @@ public class NuxeoConnector {
     private NuxeoApp app;
     private NuxeoClient client;
     private volatile boolean initialized = false; //use volatile for lazy initialization in singleton
-    private NuxeoClientConfig nuxeoClientConfig;
+    private RepositoryClientConfigType repositoryClientConfig;
 
     private NuxeoConnector() {
     }
@@ -62,17 +62,17 @@ public class NuxeoConnector {
      * is initialized in a thread-safe manner and not initialized more than once.
      * Initialization involves starting Nuxeo runtime, loading Nuxeo APIs jars
      * in OSGI container as well as establishing initial connection.
-     * @param nuxeoClientConfig
+     * @param repositoryClientConfig
      * @throws java.lang.Exception
      */
-    public void initialize(NuxeoClientConfig nuxeoClientConfig) throws Exception {
+    public void initialize(RepositoryClientConfigType repositoryClientConfig) throws Exception {
 
         if(initialized == false){
             synchronized(this){
                 if(initialized == false){
                     try{
-                        this.nuxeoClientConfig = nuxeoClientConfig;
-                        setProperties(nuxeoClientConfig);
+                        this.repositoryClientConfig = repositoryClientConfig;
+                        setProperties(repositoryClientConfig);
                         app = new NuxeoApp();
                         app.start();
                         if(logger.isDebugEnabled()){
@@ -130,13 +130,13 @@ public class NuxeoConnector {
         }
     }
 
-    private void setProperties(NuxeoClientConfig nuxeoClientConfig) {
+    private void setProperties(RepositoryClientConfigType repositoryClientConfig) {
         System.setProperty("nuxeo.client.on.jboss", Boolean.TRUE.toString());
         System.setProperty("org.nuxeo.runtime.server.enabled", Boolean.FALSE.toString());
-        System.setProperty("org.nuxeo.runtime.server.port", "" + nuxeoClientConfig.getPort());
-        System.setProperty("org.nuxeo.runtime.server.host", nuxeoClientConfig.getHost());
+        System.setProperty("org.nuxeo.runtime.server.port", "" + repositoryClientConfig.getPort());
+        System.setProperty("org.nuxeo.runtime.server.host", repositoryClientConfig.getHost());
         //System.setProperty("org.nuxeo.runtime.1.3.3.streaming.port", "3233");
-        System.setProperty("org.nuxeo.runtime.streaming.serverLocator", "socket://" + nuxeoClientConfig.getHost() + ":3233");
+        System.setProperty("org.nuxeo.runtime.streaming.serverLocator", "socket://" + repositoryClientConfig.getHost() + ":3233");
         System.setProperty("org.nuxeo.runtime.streaming.isServer", Boolean.FALSE.toString());
         //org.nuxeo.client.remote is part of the fix to Nuxeo Runtime to use Java Remote APIs
         //from JBoss
@@ -156,10 +156,10 @@ public class NuxeoConnector {
 //            }else{
             //authentication failure error comes when reusing the client
             //force connect for now
-            client.forceConnect(nuxeoClientConfig.getHost(), nuxeoClientConfig.getPort());
+            client.forceConnect(repositoryClientConfig.getHost(), repositoryClientConfig.getPort());
             if(logger.isDebugEnabled()){
                 logger.debug("getClient(): connection successful port=" +
-                        nuxeoClientConfig.getPort());
+                        repositoryClientConfig.getPort());
             }
             return client;
 //            }
@@ -199,23 +199,31 @@ public class NuxeoConnector {
 
     /**
      * retrieveWorkspaceIds retrieves all workspace ids from default repository
-     * @return
+     * @param tenantDomain domain representing tenant
+     * @return 
      * @throws java.lang.Exception
      */
-    public Hashtable<String, String> retrieveWorkspaceIds() throws Exception {
+    public Hashtable<String, String> retrieveWorkspaceIds(String tenantDomain) throws Exception {
         RepositoryInstance repoSession = null;
         Hashtable<String, String> workspaceIds = new Hashtable<String, String>();
         try{
             repoSession = getRepositorySession();
             DocumentModel rootDoc = repoSession.getRootDocument();
             DocumentModelList rootChildrenList = repoSession.getChildren(rootDoc.getRef());
-            Iterator<DocumentModel> riter = rootChildrenList.iterator();
-            if(riter.hasNext()){
-                DocumentModel domain = riter.next();
+            Iterator<DocumentModel> diter = rootChildrenList.iterator();
+            while(diter.hasNext()){
+                DocumentModel domain = diter.next();
+                String domainPath = "/" + tenantDomain;
+                if(!domain.getPathAsString().equalsIgnoreCase(domainPath)) {
+                    continue;
+                }
+                if(logger.isDebugEnabled()) {
+                    logger.debug("domain=" + domain.toString());
+                }
                 DocumentModelList domainChildrenList = repoSession.getChildren(domain.getRef());
-                Iterator<DocumentModel> diter = domainChildrenList.iterator();
-                while(diter.hasNext()){
-                    DocumentModel childNode = diter.next();
+                Iterator<DocumentModel> witer = domainChildrenList.iterator();
+                while(witer.hasNext()){
+                    DocumentModel childNode = witer.next();
                     if("Workspaces".equalsIgnoreCase(childNode.getName())){
                         DocumentModelList workspaceList = repoSession.getChildren(childNode.getRef());
                         Iterator<DocumentModel> wsiter = workspaceList.iterator();
index 330661c0763a212cafacc5bcde6cdbf76494e9ce..afa8160489bc77abeb2db82bf544492196eb6a70 100644 (file)
@@ -18,7 +18,7 @@
 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.context.ServiceContext;
 import org.collectionspace.services.common.repository.BadRequestException;
 import org.collectionspace.services.common.repository.DocumentNotFoundException;
 import org.collectionspace.services.common.repository.DocumentHandler;
@@ -30,6 +30,7 @@ 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.PathRef;
 import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
 import org.nuxeo.ecm.core.client.NuxeoClient;
 import org.slf4j.Logger;
@@ -44,308 +45,304 @@ import org.slf4j.LoggerFactory;
  */
 public class RepositoryJavaClient implements RepositoryClient {
 
-       private final Logger logger = LoggerFactory
-                       .getLogger(RepositoryJavaClient.class);
+    private final Logger logger = LoggerFactory.getLogger(RepositoryJavaClient.class);
 
-       public RepositoryJavaClient() {
-       }
+    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,
-                       DocumentHandler handler) throws BadRequestException,
-                       DocumentException {
+    /**
+     * create document in the Nuxeo repository
+     *
+     * @param ctx service context under which this method is invoked
+     * @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(ServiceContext ctx,
+            DocumentHandler handler) throws BadRequestException,
+            DocumentException {
 
-               if (serviceName == null) {
-                       throw new IllegalArgumentException(
-                                       "RemoteRepositoryClient.create: serviceName is missing");
-               }
-               if (handler.getDocumentType() == 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();
+        if(handler.getDocumentType() == null){
+            throw new IllegalArgumentException(
+                    "RemoteRepositoryClient.create: docType is missing");
+        }
+        if(handler == null){
+            throw new IllegalArgumentException(
+                    "RemoteRepositoryClient.create: handler is missing");
+        }
+        String nuxeoWspaceId = ctx.getRepositoryWorkspaceId();
+        if(nuxeoWspaceId == null){
+            throw new DocumentNotFoundException(
+                    "Unable to find workspace for service " + ctx.getServiceName() +
+                    " 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 " + handler.getDocumentType());
+            // create document model
+            DocumentModel doc = repoSession.createDocumentModel(wspacePath, id,
+                    handler.getDocumentType());
+            ((DocumentModelHandler) handler).setRepositorySession(repoSession);
+            DocumentModelWrapper wrapDoc = new DocumentModelWrapper(doc);
+            handler.handle(Action.CREATE, wrapDoc);
+            // create document with documentmodel
+            doc = repoSession.createDocument(doc);
+            repoSession.save();
+            handler.complete(Action.CREATE, wrapDoc);
+            return doc.getId();
+        }catch(Exception e){
+            if(logger.isDebugEnabled()){
+                logger.debug("Caught exception ", e);
+            }
+            throw new DocumentException(e);
+        }finally{
+            if(repoSession != null){
+                releaseRepositorySession(repoSession);
+            }
+        }
 
-                       DocumentRef nuxeoWspace = new IdRef(nuxeoWspaceId);
-                       DocumentModel wspaceDoc = repoSession.getDocument(nuxeoWspace);
-                       String wspacePath = wspaceDoc.getPathAsString();
-                       String id = IdUtils.generateId("New " + handler.getDocumentType());
-                       // create document model
-                       DocumentModel doc = repoSession.createDocumentModel(wspacePath, id,
-                                       handler.getDocumentType());
-                       ((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 ctx service context under which this method is invoked
+     * @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(ServiceContext ctx, String id, DocumentHandler handler)
+            throws DocumentNotFoundException, DocumentException {
 
-       /**
-        * 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;
 
-               if (handler == null) {
-                       throw new IllegalArgumentException(
-                                       "RemoteRepositoryClient.get: handler is missing");
-               }
-               RepositoryInstance repoSession = null;
+        try{
+            handler.prepare(Action.GET);
+            repoSession = getRepositorySession();
+            //FIXME, there is a potential privacy violation here, one tenant could
+            //retrieve doc id of another tenant and could retrieve the document
+            //PathRef does not seem to come to rescue as expected. Needs more thoughts.
+            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);
+            }
+            //set reposession to handle the document
+            ((DocumentModelHandler) handler).setRepositorySession(repoSession);
+            DocumentModelWrapper wrapDoc = new DocumentModelWrapper(doc);
+            handler.handle(Action.GET, wrapDoc);
+            handler.complete(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);
+            }
+        }
+    }
 
-               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 ctx service context under which this method is invoked
+     * @param handler
+     *            should be used by the caller to provide and transform the
+     *            document
+     * @throws DocumentException
+     */
+    @Override
+    public void getAll(ServiceContext ctx, DocumentHandler handler)
+            throws DocumentNotFoundException, DocumentException {
+        if(handler == null){
+            throw new IllegalArgumentException(
+                    "RemoteRepositoryClient.getAll: handler is missing");
+        }
+        String nuxeoWspaceId = ctx.getRepositoryWorkspaceId();
+        if(nuxeoWspaceId == null){
+            throw new DocumentNotFoundException(
+                    "Unable to find workspace for service " + 
+                    ctx.getServiceName() + " check if the mapping exists in service-config.xml or " +
+                    " the the mapped workspace exists in the Nuxeo repository");
+        }
+        RepositoryInstance repoSession = null;
 
-       /**
-        * 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);
+            //set reposession to handle the document
+            ((DocumentModelHandler) handler).setRepositorySession(repoSession);
+            DocumentModelListWrapper wrapDoc = new DocumentModelListWrapper(
+                    docList);
+            handler.handle(Action.GET_ALL, wrapDoc);
+            handler.complete(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);
+            }
+        }
+    }
 
-               try {
-                       handler.prepare(Action.GET_ALL);
-                       repoSession = getRepositorySession();
-                       DocumentRef wsDocRef = new IdRef(nuxeoWspaceId);
-                       DocumentModelList docList = repoSession.getChildren(wsDocRef);
+    /**
+     * update given document in the Nuxeo repository
+     *
+     * @param ctx service context under which this method is invoked
+     * @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(ServiceContext ctx, 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();
+            //FIXME, there is a potential privacy violation here, one tenant could
+            //retrieve doc id of another tenant and could retrieve the document
+            //PathRef does not seem to come to rescue as expected. Needs more thoughts.
+            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);
+            }
+            //set reposession to handle the document
+            ((DocumentModelHandler) handler).setRepositorySession(repoSession);
+            DocumentModelWrapper wrapDoc = new DocumentModelWrapper(doc);
+            handler.handle(Action.UPDATE, wrapDoc);
+            repoSession.saveDocument(doc);
+            repoSession.save();
+            handler.complete(Action.UPDATE, 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);
+            }
+        }
+    }
 
-                       ((DocumentModelHandler) handler).setRepositorySession(repoSession);
-                       DocumentModelListWrapper wrapDoc = new DocumentModelListWrapper(
-                                       docList);
-                       handler.handle(Action.GET_ALL, wrapDoc);
+    /**
+     * delete a document from the Nuxeo repository
+     * @param ctx service context under which this method is invoked
+     * @param id
+     *            of the document
+     * @throws DocumentException
+     */
+    @Override
+    public void delete(ServiceContext ctx, String id) throws DocumentNotFoundException,
+            DocumentException {
 
-               } 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);
-                       }
-               }
-       }
+        if(logger.isDebugEnabled()){
+            logger.debug("deleting document with id=" + id);
+        }
+        RepositoryInstance repoSession = null;
+        try{
+            repoSession = getRepositorySession();
+            //FIXME, there is a potential privacy violation here, one tenant could
+            //retrieve doc id of another tenant and could retrieve the document
+            //PathRef does not seem to come to rescue as expected. needs more thoughts.
+            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);
+            }
+        }
+    }
 
-       /**
-        * 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);
-                       }
-               }
-       }
+    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;
+    }
 
-       /**
-        * 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
-               }
-       }
+    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
+        }
+    }
 }
index 9a762fd1d92a6b5f6fe0471c3f85657f19ca3a83..4ebe43e60126bc890472e3b1242cbbdc5701e87f 100644 (file)
@@ -43,8 +43,10 @@ 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.RepositoryClientConfigType;
 import org.collectionspace.services.common.ServiceMain;
+import org.collectionspace.services.common.config.TenantBindingConfigReader;
+import org.collectionspace.services.common.context.ServiceContext;
 import org.collectionspace.services.common.repository.BadRequestException;
 import org.collectionspace.services.common.repository.DocumentNotFoundException;
 import org.collectionspace.services.common.repository.DocumentHandler.Action;
@@ -78,20 +80,17 @@ public class RepositoryRESTClient implements RepositoryClient {
     }
 
     @Override
-    public String create(String serviceName, DocumentHandler handler) throws BadRequestException, DocumentException {
-        if(serviceName == null){
-            throw new IllegalArgumentException("RepositoryRESTClient.create: serviceName is missing");
-        }
+    public String create(ServiceContext ctx, DocumentHandler handler) throws BadRequestException, DocumentException {
+
         if(handler.getDocumentType() == 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);
+        String nuxeoWspaceId = ctx.getRepositoryWorkspaceId();
         if(nuxeoWspaceId == null){
-            throw new DocumentNotFoundException("Unable to find workspace for service " + serviceName +
+            throw new DocumentNotFoundException("Unable to find workspace for service " + ctx.getServiceName() +
                     " check if the mapping exists in service-config.xml or " +
                     " the the mapped workspace exists in the Nuxeo repository");
         }
@@ -142,6 +141,7 @@ public class RepositoryRESTClient implements RepositoryClient {
             //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
+            repHandler.complete(Action.CREATE, wrapDoc);
             return extractId(document);
 
         }catch(Exception e){
@@ -154,7 +154,7 @@ public class RepositoryRESTClient implements RepositoryClient {
     }
 
     @Override
-    public void get(String id, DocumentHandler handler) throws DocumentNotFoundException, DocumentException {
+    public void get(ServiceContext ctx, String id, DocumentHandler handler) throws DocumentNotFoundException, DocumentException {
 
         if(handler == null){
             throw new IllegalArgumentException("RepositoryRESTClient.get: handler is missing");
@@ -183,6 +183,7 @@ public class RepositoryRESTClient implements RepositoryClient {
             Document document = executeRequest(request, completeURL, Status.SUCCESS_OK);
             RepresentationWrapper wrapDoc = new RepresentationWrapper(document);
             repHandler.handle(Action.GET, wrapDoc);
+            repHandler.complete(Action.GET, wrapDoc);
         }catch(Exception e){
             if(logger.isDebugEnabled()){
                 logger.debug("Caught exception ", e);
@@ -193,17 +194,13 @@ public class RepositoryRESTClient implements RepositoryClient {
     }
 
     @Override
-    public void getAll(String serviceName, DocumentHandler handler) throws DocumentNotFoundException, DocumentException {
-        if(serviceName == null){
-            throw new IllegalArgumentException("RepositoryRESTClient.getAll: serviceName is missing");
-        }
+    public void getAll(ServiceContext ctx, DocumentHandler handler) throws DocumentNotFoundException, DocumentException {
         if(handler == null){
             throw new IllegalArgumentException("RepositoryRESTClient.getAll: handler is missing");
         }
-        ServiceMain smain = ServiceMain.getInstance();
-        String nuxeoWspaceId = smain.getWorkspaceId(serviceName);
+        String nuxeoWspaceId = ctx.getRepositoryWorkspaceId();
         if(nuxeoWspaceId == null){
-            throw new DocumentNotFoundException("Unable to find workspace for service " + serviceName +
+            throw new DocumentNotFoundException("Unable to find workspace for service " + ctx.getServiceName() +
                     " check if the mapping exists in service-config.xml or " +
                     " the the mapped workspace exists in the Nuxeo repository");
         }
@@ -225,6 +222,7 @@ public class RepositoryRESTClient implements RepositoryClient {
             Document document = executeRequest(request, completeURL, Status.SUCCESS_OK);
             RepresentationWrapper wrapDoc = new RepresentationWrapper(document);
             repHandler.handle(Action.GET_ALL, wrapDoc);
+            repHandler.complete(Action.GET_ALL, wrapDoc);
         }catch(Exception e){
             if(logger.isDebugEnabled()){
                 logger.debug("Caught exception ", e);
@@ -235,7 +233,7 @@ public class RepositoryRESTClient implements RepositoryClient {
     }
 
     @Override
-    public void update(String id, DocumentHandler handler) throws BadRequestException, DocumentNotFoundException, DocumentException {
+    public void update(ServiceContext ctx, String id, DocumentHandler handler) throws BadRequestException, DocumentNotFoundException, DocumentException {
         if(handler == null){
             throw new IllegalArgumentException("RepositoryRESTClient.update: handler is missing");
         }
@@ -259,7 +257,7 @@ public class RepositoryRESTClient implements RepositoryClient {
             repHandler.handle(Action.UPDATE, wrapDoc);
             Request request = buildRequest(Method.PUT, completeURL);
             Document document = executeRequest(request, completeURL, Status.SUCCESS_OK);
-
+            repHandler.complete(Action.UPDATE, wrapDoc);
         }catch(Exception e){
             if(logger.isDebugEnabled()){
                 logger.debug("Caught exception ", e);
@@ -270,7 +268,7 @@ public class RepositoryRESTClient implements RepositoryClient {
     }
 
     @Override
-    public void delete(String id) throws DocumentNotFoundException, DocumentException {
+    public void delete(ServiceContext ctx, String id) throws DocumentNotFoundException, DocumentException {
 
         if(logger.isDebugEnabled()){
             logger.debug("deleting document with id=" + id);
@@ -379,15 +377,16 @@ public class RepositoryRESTClient implements RepositoryClient {
     private NuxeoRESTClient getNuxeoRestClient() {
         if(nuxeoRestClient == null){
             ServiceConfig sconfig = ServiceMain.getInstance().getServiceConfig();
-            NuxeoClientConfig nxConfig = sconfig.getNuxeoClientConfig();
+            //assumption: there is only one client and that also is rest
+            RepositoryClientConfigType repConfig = sconfig.getRepositoryClient();
             String protocol = "http";
-            if(nxConfig.getProtocol() != null && !"".equals(nxConfig.getProtocol())){
-                protocol = nxConfig.getProtocol();
+            if(repConfig.getProtocol() != null && !"".equals(repConfig.getProtocol())){
+                protocol = repConfig.getProtocol();
             }
             NuxeoRESTClient tempClient = new NuxeoRESTClient(protocol,
-                    nxConfig.getHost(), "" + nxConfig.getPort());
+                    repConfig.getHost(), "" + repConfig.getPort());
 
-            tempClient.setBasicAuthentication(nxConfig.getUser(), nxConfig.getPassword());
+            tempClient.setBasicAuthentication(repConfig.getUser(), repConfig.getPassword());
 
             nuxeoRestClient = tempClient;
 
index f2d4b0ce6d1563e80a1db69cf93be697cfca42bc..1bdd44e54955adc8b99e64ae34ae9af1a91c35c2 100644 (file)
  */
 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.common.repository.AbstractDocumentHandler;
 import org.collectionspace.services.nuxeo.client.*;
-import org.dom4j.Document;
+import org.w3c.dom.Document;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -44,98 +43,72 @@ import org.slf4j.LoggerFactory;
  * $LastChangedDate: $
  */
 public abstract class RepresentationHandler<T, TL>
-        implements DocumentHandler<T, TL> {
+        extends AbstractDocumentHandler<T, TL> {
 
     private final Logger logger = LoggerFactory.getLogger(RepresentationHandler.class);
-    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 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;
-        }
-    }
-
     @Override
     public void handleCreate(DocumentWrapper wrapDoc) throws Exception {
-        if(getCommonObject() == null){
-            String msg = "Error creating document: Missing input data";
-            logger.error(msg);
-            throw new IllegalStateException(msg);
-        }
-        //FIXME set other parts as well
-        fillCommonObject(getCommonObject(), wrapDoc);
+        fillAllParts(wrapDoc);
     }
 
     @Override
     public void handleUpdate(DocumentWrapper wrapDoc) throws Exception {
-        if(getCommonObject() == null){
-            String msg = "Error updating document: Missing input data";
-            logger.error(msg);
-            throw new IllegalStateException(msg);
-        }
-        //FIXME set other parts as well
-        fillCommonObject(getCommonObject(), wrapDoc);
+        fillAllParts(wrapDoc);
     }
 
     @Override
     public void handleGet(DocumentWrapper wrapDoc) throws Exception {
-        setCommonObject(extractCommonObject(wrapDoc));
-
-        //FIXME retrive other parts as well
+        extractAllParts(wrapDoc);
     }
 
     @Override
     public void handleGetAll(DocumentWrapper wrapDoc) throws Exception {
-        setCommonObjectList(extractCommonObjectList(wrapDoc));
+        setCommonPartList(extractCommonPartList(wrapDoc));
     }
 
     @Override
-    public abstract T extractCommonObject(DocumentWrapper wrapDoc) throws Exception;
+    public void extractAllParts(DocumentWrapper wrapDoc) throws Exception {
+        setCommonPart(extractCommonPart(wrapDoc));
+
+        //FIXME retrive other parts as well
+    }
 
     @Override
-    public abstract void fillCommonObject(T obj, DocumentWrapper wrapDoc) throws Exception;
+    public abstract T extractCommonPart(DocumentWrapper wrapDoc) throws Exception;
 
     @Override
-    public abstract TL extractCommonObjectList(DocumentWrapper wrapDoc) throws Exception;
+    public void fillAllParts(DocumentWrapper wrapDoc) throws Exception {
+        if(getCommonPart() == null){
+            String msg = "Error creating document: Missing input data";
+            logger.error(msg);
+            throw new IllegalStateException(msg);
+        }
+        //FIXME set other parts as well
+        fillCommonPart(getCommonPart(), wrapDoc);
+    }
 
     @Override
-    public abstract void fillCommonObjectList(TL obj, DocumentWrapper wrapDoc) throws Exception;
+    public abstract void fillCommonPart(T obj, DocumentWrapper wrapDoc) throws Exception;
 
     @Override
-    public abstract T getCommonObject();
+    public abstract TL extractCommonPartList(DocumentWrapper wrapDoc) throws Exception;
 
     @Override
-    public abstract void setCommonObject(T obj);
+    public abstract T getCommonPart();
 
     @Override
-    public abstract TL getCommonObjectList();
+    public abstract void setCommonPart(T obj);
 
     @Override
-    public abstract void setCommonObjectList(TL obj);
+    public abstract TL getCommonPartList();
 
     @Override
-    public Document getDocument(DocumentWrapper wrapDoc) throws DocumentException {
-        throw new UnsupportedOperationException("DocumentHandler.getDocument(wrapDoc)");
-    }
+    public abstract void setCommonPartList(TL obj);
 
     /**
      * @return the pathParams
@@ -194,20 +167,4 @@ public abstract class RepresentationHandler<T, TL>
     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;
-    }
 }
index bd459d1ddb995df278b22f77e7f6d5021da35902..d27869ea7bd3ca6e5157fdfbad84e1143b25cea3 100644 (file)
@@ -104,75 +104,75 @@ public class NuxeoUtils {
         }
         return doc;
     }
-    
-/**
- * Gets the document.
- * 
- * @param repoSession the repo session
- * @param csid the csid
- * 
- * @return the document
- * 
- * @throws DocumentException the document exception
- */
-public static Document getDocument(RepositoryInstance repoSession, String csid)
-       throws DocumentException {
-               Document result = null;
-               
-               DocumentModel docModel = getDocumentModel(repoSession, csid);
-               result = getDocument(repoSession, docModel);
-               
-               return result;
-       }
-       
-       /**
-        * Gets the workspace model.
-        * 
-        * @param repoSession the repo session
-        * @param workspaceName the workspace name
-        * 
-        * @return the workspace model
-        * 
-        * @throws DocumentException the document exception
-        * @throws IOException Signals that an I/O exception has occurred.
-        * @throws ClientException the client exception
-        */
-       public static DocumentModel getWorkspaceModel(
-                       RepositoryInstance repoSession, String workspaceName)
-                       throws DocumentException, IOException, ClientException {
-               DocumentModel result = null;
-
-               String workspaceUUID = ServiceMain.getInstance().getWorkspaceId(
-                               workspaceName);
-               DocumentRef workspaceRef = new IdRef(workspaceUUID);
-               result = repoSession.getDocument(workspaceRef);
-
-               return result;
-       }
-
-       /**
-        * Gets the document model.
-        * 
-        * @param repoSession the repo session
-        * @param csid the csid
-        * 
-        * @return the document model
-        * 
-        * @throws DocumentException the document exception
-        */
-       public static DocumentModel getDocumentModel(
-                       RepositoryInstance repoSession, String csid)
-                       throws DocumentException {
-               DocumentModel result = null;
-
-               try {
-                       DocumentRef documentRef = new IdRef(csid);
-                       result = repoSession.getDocument(documentRef);
-               } catch (ClientException e) {
-                       e.printStackTrace();
-               }
-
-               return result;
-       }
-           
+
+    /**
    * Gets the document.
+     *
    * @param repoSession the repo session
    * @param csid the csid
+     *
    * @return the document
+     *
    * @throws DocumentException the document exception
    */
+    public static Document getDocument(RepositoryInstance repoSession, String csid)
+            throws DocumentException {
+        Document result = null;
+
+        DocumentModel docModel = getDocumentModel(repoSession, csid);
+        result = getDocument(repoSession, docModel);
+
+        return result;
+    }
+
+    /**
+     * Gets the workspace model.
+     *
+     * @param repoSession the repo session
+     * @param workspaceName the workspace name
+     *
+     * @return the workspace model
+     *
+     * @throws DocumentException the document exception
+     * @throws IOException Signals that an I/O exception has occurred.
+     * @throws ClientException the client exception
+     */
+    public static DocumentModel getWorkspaceModel(
+            RepositoryInstance repoSession, String workspaceName)
+            throws DocumentException, IOException, ClientException {
+        DocumentModel result = null;
+        //FIXME: commented out as this does not work without tenant qualification
+        String workspaceUUID = null;
+//             String workspaceUUID = ServiceMain.getInstance().getWorkspaceId(
+//                             workspaceName);
+        DocumentRef workspaceRef = new IdRef(workspaceUUID);
+        result = repoSession.getDocument(workspaceRef);
+
+        return result;
+    }
+
+    /**
+     * Gets the document model.
+     *
+     * @param repoSession the repo session
+     * @param csid the csid
+     *
+     * @return the document model
+     *
+     * @throws DocumentException the document exception
+     */
+    public static DocumentModel getDocumentModel(
+            RepositoryInstance repoSession, String csid)
+            throws DocumentException {
+        DocumentModel result = null;
+
+        try{
+            DocumentRef documentRef = new IdRef(csid);
+            result = repoSession.getDocument(documentRef);
+        }catch(ClientException e){
+            e.printStackTrace();
+        }
+
+        return result;
+    }
 }
diff --git a/services/common/src/main/java/org/collectionspace/services/svn-commit.tmp~ b/services/common/src/main/java/org/collectionspace/services/svn-commit.tmp~
new file mode 100644 (file)
index 0000000..58b9185
--- /dev/null
@@ -0,0 +1,4 @@
+\r
+--This line, and those below, will be ignored--\r
+\r
+M    common/repository/RepositoryClient.java\r
index 78e85ba0ffe1905c938d387a9e9515728ccd48df..ed7d5c5d73c90226b6a3ab0f1ff17d0fc98fdc6b 100644 (file)
     <xs:element name="service-config">
         <xs:complexType>
             <xs:sequence>
-                <xs:element name="nuxeo-client-config" minOccurs="1"  maxOccurs="1">
-                    <xs:complexType>
-                        <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:element name="nuxeo-workspace" minOccurs="0"  maxOccurs="1" >
-                    <xs:complexType>
-                        <xs:sequence>
-                            <xs:element name="workspace" maxOccurs="unbounded" >
-                                <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:sequence>
-                    </xs:complexType>
-                </xs:element>
+                <!-- assumption: there is only one type of repository client used  -->
+                <xs:element name="repository-client" type="RepositoryClientConfigType" minOccurs="1"  maxOccurs="1"/>
+                <xs:element name="repository-workspace" type="RepositoryWorkspaceType" minOccurs="0"  maxOccurs="1" />
             </xs:sequence>
         </xs:complexType>
     </xs:element>
 
-    <!-- enumeration defining the type nuxeo client -->
-    <xs:simpleType name="NuxeoClientType">
+    <xs:complexType name="RepositoryClientConfigType">
+        <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" />
+            <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" />
+            <!-- default client is java -->
+            <xs:element name="client-type" type="ClientType" minOccurs="1"  maxOccurs="1" />
+            <!-- default client is org.collectionspace.services.nuxeo.client.java.RepositoryJavaClient -->
+            <xs:element name="client-class" type="xs:string" minOccurs="1"  maxOccurs="1" />
+        </xs:sequence>
+        <!-- name of the client -->
+        <xs:attribute name="name" type="xs:string" use="required"/>
+        <xs:attribute name="default" type="xs:boolean" use="required"/>
+    </xs:complexType>
+
+    <xs:complexType name="RepositoryWorkspaceType">
+        <xs:sequence>
+            <xs:element name="workspace" maxOccurs="unbounded" >
+                <xs:complexType>
+                    <xs:sequence>
+                        <xs:element name="service-name" type="xs:string" minOccurs="1"  maxOccurs="1" />
+                        <!-- workspace name is required for Repository Java client -->
+                        <xs:element name="workspace-name" type="xs:string" minOccurs="1"  maxOccurs="1" />
+                        <!-- workspace ids are required only for Repository REST client -->
+                        <xs:element name="workspace-id" type="xs:string" minOccurs="1"  maxOccurs="1" />
+                    </xs:sequence>
+                </xs:complexType>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+    
+    <!-- enumeration defining the type repository client -->
+    <xs:simpleType name="ClientType">
         <xs:restriction base="xs:string">
             <xs:enumeration value="java" />
             <xs:enumeration value="rest" />
diff --git a/services/common/src/main/resources/service.xsd b/services/common/src/main/resources/service.xsd
new file mode 100644 (file)
index 0000000..9bc6a7d
--- /dev/null
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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
+
+    Document   : service.xsd
+    Revision   : $LastChangedRevision: $
+    Created on : $LastChangedDate: $
+    Author     : $LastChangedBy: $
+    Description: ServiceBinding desribes how a possibly tenant-specific service is
+                 bound to corresponding service framework at runtime
+                 ServiceObjectType is used to describe the
+                 structure of a CollectionSpace object - an entity or relation.
+                 This is NOT used to encode or decode the stream in or out the
+                 content over the wire or to the storage.
+                 Derived from Fedora Digtial Object Model and MIME Multipart
+-->
+<xs:schema
+  xmlns:xs="http://www.w3.org/2001/XMLSchema"
+  xmlns="http://collectionspace.org/services/common/service"
+  xmlns:types="http://collectionspace.org/services/common/types"
+  targetNamespace="http://collectionspace.org/services/common/service"
+  version="0.1"
+  elementFormDefault="qualified"
+>
+
+    <xs:import namespace="http://collectionspace.org/services/common/types" schemaLocation="types.xsd" />
+
+    <xs:complexType name="ServiceBindingType">
+        <xs:sequence>
+            <!-- object(s) served by the service -->
+            <xs:element name="object" type="ServiceObjectType" minOccurs="1" maxOccurs="unbounded"/>
+
+            <!-- name of the repository client (from service-config.xml) -->
+            <xs:element name="repositoryClient" type="xs:string" minOccurs="0" maxOccurs="1"/>
+            <!-- repositoryWorkspaceId could be workspace id -->
+            <!-- used only for Nuxeo rest client -->
+            <xs:element name="repositoryWorkspaceId" type="xs:string" minOccurs="0" maxOccurs="1"/>
+        </xs:sequence>
+        <xs:attribute name="name" type="xs:string" use="required"/>
+        <xs:attribute name="version" type="types:VersionType" use="required"/>
+    </xs:complexType>
+
+    <!--
+        ServiceObjectType defines the manifest for a collectionspace
+        object.  includes properties of the object as well as manifests
+        for zero or more parts of the object.
+    -->
+    <xs:complexType name="ServiceObjectType">
+        <xs:annotation>
+            <xs:documentation/>
+        </xs:annotation>
+        <xs:sequence>
+            <xs:element name="property" type="types:PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="part" type="ObjectPartType" minOccurs="0" maxOccurs="unbounded"/>
+            <!-- a handler Java class to process the content of this service -->
+            <xs:element name="serviceHandler" type="xs:string" minOccurs="0" maxOccurs="1"/>
+        </xs:sequence>
+        <xs:attribute name="id" type="xs:ID" use="required"/>
+        <!-- the object name could be collectionobject|intake|location, etc. -->
+        <xs:attribute name="name" type="xs:string" use="required"/>
+        <xs:attribute name="version" type="types:VersionType" use="required"/>
+    </xs:complexType>
+
+
+    <!---
+    ObjectPartType describes a part of an object
+    -->
+    <xs:complexType name="ObjectPartType">
+        <xs:annotation>
+            <xs:documentation/>
+        </xs:annotation>
+        <xs:sequence>
+            <xs:element name="properties" type="types:PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="content" type="ObjectPartContentType" minOccurs="1" maxOccurs="1"/>
+        </xs:sequence>
+        <xs:attribute name="id" type="xs:ID" use="required"/>
+        <!-- control group indicates where the content resides -->
+        <xs:attribute name="control_group" use="required">
+            <xs:simpleType>
+                <xs:restriction base="xs:string">
+                    <!-- managed by an external repository such as MediaVault -->
+                    <xs:enumeration value="External"/>
+                    <!-- managed by CollectionSpace -->
+                    <xs:enumeration value="Managed"/>
+                    <!-- inlined from this manifest -->
+                    <xs:enumeration value="Inline"/>
+                </xs:restriction>
+            </xs:simpleType>
+        </xs:attribute>
+        <xs:attribute name="versionable" type="xs:boolean" use="optional" default="true"/>
+        <xs:attribute name="auditable" type="xs:boolean" use="optional" default="true"/>
+        <!-- application defined label to identify the part, e.g. collectionobject.ucmp.berkeley -->
+        <xs:attribute name="label" type="xs:string" use="optional"/>
+        <xs:attribute name="updated" type="xs:dateTime" use="optional"/>
+        <!-- order in the sequence of one or more parts -->
+        <xs:attribute name="order" type="xs:int" use="optional"/>
+    </xs:complexType>
+
+    <!--
+        ObjectPartContentType describes the content of a part as well as provides
+        information about how to handle the part
+    -->
+    <xs:complexType name="ObjectPartContentType">
+        <xs:sequence>
+            <xs:element name="contentDigest" type="ContentDigestType" minOccurs="0"/>
+            <xs:choice>
+                <xs:element name="xmlContent" type="XmlContentType"/>
+                <xs:element name="contentLocation" type="ContentLocationType"/>
+                <xs:element name="binaryContent" type="xs:base64Binary"/>
+            </xs:choice>
+            <!-- a handler Java class to process the content of this part -->
+            <xs:element name="partHandler" type="xs:string" minOccurs="0" maxOccurs="1"/>
+        </xs:sequence>
+        <!-- MIME content type -->
+        <xs:attribute name="contentType" type="xs:string" use="required"/>
+    </xs:complexType>
+
+    <!--
+    content digest provides information about the digest algorithm used
+    and the digest itself
+    -->
+    <xs:complexType name="ContentDigestType">
+        <xs:attribute name="algorithm" use="required">
+            <xs:simpleType>
+                <xs:restriction base="xs:string">
+                    <xs:enumeration value="MD5"/>
+                    <xs:enumeration value="SHA-1"/>
+                    <xs:enumeration value="SHA-256"/>
+                    <xs:enumeration value="SHA-384"/>
+                    <xs:enumeration value="SHA-512"/>
+                </xs:restriction>
+            </xs:simpleType>
+        </xs:attribute>
+        <xs:attribute name="value" type="xs:string" use="required"/>
+    </xs:complexType>
+    
+    <xs:complexType name="XmlContentType">
+        <xs:sequence>
+            <xs:any namespace="##any" processContents="skip" minOccurs="0" maxOccurs="1"/>
+        </xs:sequence>
+        <!-- location to retrieve the schema from -->
+        <!-- in fact, schema should be retrievable by the parser, validator -->
+        <xs:attribute name="schemaLocation" type="xs:string" use="optional"/>
+        <xs:attribute name="namespaceURI" type="xs:string" use="optional"/>
+    </xs:complexType>
+
+    <xs:complexType name="ContentLocationType">
+        <xs:attribute name="type" use="required">
+            <xs:simpleType>
+                <xs:restriction base="xs:string">
+                    <xs:enumeration value="internalId"/>
+                    <xs:enumeration value="URL"/>
+                </xs:restriction>
+            </xs:simpleType>
+        </xs:attribute>
+        <xs:attribute name="ref" use="required">
+            <xs:simpleType>
+                <xs:restriction base="xs:anyURI">
+                    <xs:minLength value="1"/>
+                </xs:restriction>
+            </xs:simpleType>
+        </xs:attribute>
+    </xs:complexType>
+
+</xs:schema>
diff --git a/services/common/src/main/resources/tenant.xsd b/services/common/src/main/resources/tenant.xsd
new file mode 100644 (file)
index 0000000..0706851
--- /dev/null
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+<!--
+    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
+
+    Document   : tenant-binding.xsd
+    Revision   : $LastChangedRevision: $
+    Created on : $LastChangedDate: $
+    Description:
+        
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+  xmlns="http://collectionspace.org/services/common/tenant"
+  xmlns:types="http://collectionspace.org/services/common/types"
+  xmlns:service="http://collectionspace.org/services/common/service"
+  targetNamespace="http://collectionspace.org/services/common/tenant"
+  version="0.1"
+  elementFormDefault="qualified">
+
+    <xs:import namespace="http://collectionspace.org/services/common/types" schemaLocation="types.xsd" />
+    <xs:import namespace="http://collectionspace.org/services/common/service" schemaLocation="service.xsd" />
+
+    <xs:element name="TenantBindingConfig">
+        <xs:annotation>
+            <xs:documentation/>
+        </xs:annotation>
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="tenantBinding" type="TenantBindingType" minOccurs="0" maxOccurs="unbounded"/>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+    <!--
+        TenantBindingType describes bindings for each tenant in CollectionSpace
+    -->
+    <xs:complexType name="TenantBindingType">
+        <xs:sequence>
+            <xs:element name="serviceBindings" type="service:ServiceBindingType" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+        <!-- tenant id, a UUID -->
+        <xs:attribute name="id" type="xs:ID" use="required"/>
+        <!-- domain name including subdomain but not TLD -->
+        <!-- e.g. hearstmuseum.berkeley or movingimage.us -->
+        <xs:attribute name="name" type="xs:string" use="required"/>
+        <!-- display name as Museum of Moving Images -->
+        <xs:attribute name="displayName" type="xs:string" use="required"/>
+        <xs:attribute name="version" type="types:VersionType" use="required"/>
+        <!-- repository domain -->
+        <xs:attribute name="repositoryDomain" type="xs:string" use="optional" default="default-domain"/>
+    </xs:complexType>
+
+</xs:schema>
diff --git a/services/common/src/main/resources/types.xsd b/services/common/src/main/resources/types.xsd
new file mode 100644 (file)
index 0000000..ab24291
--- /dev/null
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<!--
+    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
+
+    Document   : types.xsd
+    Revision   : $LastChangedRevision: $
+    Created on : $LastChangedDate: $
+    Description:
+        
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+    xmlns="http://collectionspace.org/services/common/types"
+    targetNamespace="http://collectionspace.org/services/common/types"
+    elementFormDefault="qualified"
+>
+    <!--
+        PropertyType defines the type for property in the property bag
+    -->
+    <xs:complexType name="PropertyType">
+        <xs:sequence>
+            <xs:element name="item" type="PropertyItemType" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="PropertyItemType">
+        <xs:sequence>
+            <xs:element name="key" type="xs:string"/>
+            <xs:element name="value" type="xs:string"/>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:simpleType name="VersionType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="1.0"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+</xs:schema>
\ No newline at end of file
diff --git a/services/common/src/main/svn-commit.tmp~ b/services/common/src/main/svn-commit.tmp~
new file mode 100644 (file)
index 0000000..6990c4d
--- /dev/null
@@ -0,0 +1,5 @@
+\r
+--This line, and those below, will be ignored--\r
+\r
+D    resources/common.xsd\r
+A    resources/system-response.xsd\r
index c8b1a545a872a8c6934363bf779ff70dcd6a34a0..129a1dc271d66a0f1d497d29eea6000986d21325 100644 (file)
@@ -82,7 +82,6 @@
           <dependency>
             <groupId>com.sun.xml.bind</groupId>
             <artifactId>jaxb-impl</artifactId>
-            <version>2.1.2</version>
           </dependency>
         </dependencies>
         <configuration>
index 5c44671978f66a1ed08d709810d3c094081d5562..6347f26403b6a4abff30e6a96eb5de0bcafdaad5 100644 (file)
       <groupId>com.thoughtworks.xstream</groupId>
       <artifactId>xstream</artifactId>
       <version>1.3.2-SNAPSHOT</version>
-    </dependency> 
+    </dependency>
 
   </dependencies>
   
index 96e156a0fd32f4631377d6fe57debcab1e957122..2fa6e50a649d31eb3f9e4e6925dd33b6399d0df1 100644 (file)
@@ -1,13 +1,13 @@
 <?xml version="1.0"?>
 <component name="org.collectionspace.intake.coreTypes">
   <extension target="org.nuxeo.ecm.core.schema.TypeService" point="schema">
-    <schema name="intake" prefix="intake" src="schemas/intake.xsd"/>
+    <schema name="intakes-common" prefix="intakes-common" src="schemas/intakes-common.xsd"/>
   </extension>
   <extension target="org.nuxeo.ecm.core.schema.TypeService" point="doctype">
     <doctype name="Intake" extends="Document">
       <schema name="common"/>
       <schema name="dublincore"/>
-      <schema name="intake"/>
+      <schema name="intakes-common"/>
     </doctype>
   </extension>
 </component>
index ec51628ec45661e0b214ee3a0210ef4bb6eb723f..9a941c921418e873932a490040823eb9e04c364d 100644 (file)
@@ -2,12 +2,13 @@ package org.collectionspace.services.client;
 
 import javax.ws.rs.core.Response;
 
-import org.collectionspace.services.intake.Intake;
-import org.collectionspace.services.intake.IntakeList;
+import org.collectionspace.services.intake.IntakesCommonList;
 
 import org.jboss.resteasy.client.ProxyFactory;
 import org.jboss.resteasy.plugins.providers.RegisterBuiltin;
 import org.jboss.resteasy.client.ClientResponse;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
 import org.jboss.resteasy.spi.ResteasyProviderFactory;
 
 /**
@@ -51,7 +52,7 @@ public class IntakeClient extends BaseServiceClient {
      * @return
      * @see org.collectionspace.hello.client.IntakeProxy#getIntake()
      */
-    public ClientResponse<IntakeList> readList() {
+    public ClientResponse<IntakesCommonList> readList() {
         return intakeProxy.readList();
     }
 
@@ -60,7 +61,8 @@ public class IntakeClient extends BaseServiceClient {
      * @return
      * @see org.collectionspace.hello.client.IntakeProxy#getIntake(java.lang.String)
      */
-    public ClientResponse<Intake> read(String csid) {
+
+    public ClientResponse<MultipartInput> read(String csid) {
         return intakeProxy.read(csid);
     }
 
@@ -69,8 +71,8 @@ public class IntakeClient extends BaseServiceClient {
      * @return
      * @see org.collectionspace.hello.client.IntakeProxy#createIntake(org.collectionspace.hello.Intake)
      */
-    public ClientResponse<Response> create(Intake intake) {
-        return intakeProxy.create(intake);
+    public ClientResponse<Response> create(MultipartOutput multipart) {
+        return intakeProxy.create(multipart);
     }
 
     /**
@@ -79,8 +81,9 @@ public class IntakeClient extends BaseServiceClient {
      * @return
      * @see org.collectionspace.hello.client.IntakeProxy#updateIntake(java.lang.Long, org.collectionspace.hello.Intake)
      */
-    public ClientResponse<Intake> update(String csid, Intake intake) {
-        return intakeProxy.update(csid, intake);
+    public ClientResponse<MultipartInput> update(String csid, MultipartOutput multipart) {
+        return intakeProxy.update(csid, multipart);
+
     }
 
     /**
index 40baeef75363bc5e8b5c5e26ebe1563864f5422a..fdf0e2cf7969a062fd0e057bedea0105a1b194fd 100644 (file)
@@ -10,37 +10,39 @@ import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.Response;
 
-import org.collectionspace.services.intake.Intake;
-import org.collectionspace.services.intake.IntakeList;
+import org.collectionspace.services.intake.IntakesCommonList;
 import org.jboss.resteasy.client.ClientResponse;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
 
 /**
  * @version $Revision:$
  */
 @Path("/intakes/")
-@Produces({"application/xml"})
-@Consumes({"application/xml"})
+@Produces({"multipart/mixed"})
+@Consumes({"multipart/mixed"})
 public interface IntakeProxy {
 
     @GET
-    ClientResponse<IntakeList> readList();
+    @Produces({"application/xml"})
+    ClientResponse<IntakesCommonList> readList();
 
     //(C)reate
     @POST
-    ClientResponse<Response> create(Intake co);
+    ClientResponse<Response> create(MultipartOutput multipart);
 
     //(R)ead
     @GET
     @Path("/{csid}")
-    ClientResponse<Intake> read(@PathParam("csid") String csid);
+    ClientResponse<MultipartInput> read(@PathParam("csid") String csid);
 
     //(U)pdate
     @PUT
     @Path("/{csid}")
-    ClientResponse<Intake> update(@PathParam("csid") String csid, Intake co);
+    ClientResponse<MultipartInput> update(@PathParam("csid") String csid, MultipartOutput multipart);
 
     //(D)elete
     @DELETE
     @Path("/{csid}")
     ClientResponse<Response> delete(@PathParam("csid") String csid);
-}
\ No newline at end of file
+}
index 28c937a9ada2410a117fd99d18a007666663e6c2..3b069e03d39631f3d66662e41af0b32d6464cbf8 100644 (file)
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
- package org.collectionspace.services.client.test;
+package org.collectionspace.services.client.test;
 
 import java.util.List;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
 
 import org.collectionspace.services.client.IntakeClient;
-import org.collectionspace.services.client.test.ServiceRequestType;
-import org.collectionspace.services.intake.Intake;
-import org.collectionspace.services.intake.IntakeList;
+import org.collectionspace.services.intake.IntakesCommon;
+import org.collectionspace.services.intake.IntakesCommonList;
 
 import org.jboss.resteasy.client.ClientResponse;
 
+import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
+import org.jboss.resteasy.plugins.providers.multipart.OutputPart;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
 /**
  * IntakeServiceTest, carries out tests against a
  * deployed and running Intake Service.
- * 
+ *
  * $LastChangedRevision$
  * $LastChangedDate$
  */
@@ -52,13 +52,10 @@ public class IntakeServiceTest extends AbstractServiceTest {
     final String SERVICE_PATH_COMPONENT = "intakes";
     private String knownResourceId = null;
 
-
     // ---------------------------------------------------------------
     // CRUD tests : CREATE tests
     // ---------------------------------------------------------------
-
     // Success outcomes
-    
     @Override
     @Test
     public void create() {
@@ -70,8 +67,10 @@ public class IntakeServiceTest extends AbstractServiceTest {
 
         // Submit the request to the service and store the response.
         String identifier = createIdentifier();
-        Intake intake = createIntakeInstance(identifier);
-        ClientResponse<Response> res = client.create(intake);
+
+        MultipartOutput multipart = createIntakeInstance(identifier);
+        ClientResponse<Response> res = client.create(multipart);
+
         int statusCode = res.getStatus();
 
         // Check the status code of the response: does it match
@@ -82,12 +81,13 @@ public class IntakeServiceTest extends AbstractServiceTest {
         // Does it exactly match the expected status code?
         verbose("create: status = " + statusCode);
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
 
-        // Store the ID returned from this create operation for
-        // additional tests below.
+        // Store the ID returned from this create operation
+        // for additional tests below.
         knownResourceId = extractId(res);
+        verbose("create: knownResourceId=" + knownResourceId);
     }
 
     @Override
@@ -99,298 +99,316 @@ public class IntakeServiceTest extends AbstractServiceTest {
     }
 
     // Failure outcomes
-
     // Placeholders until the three tests below can be uncommented.
     // See Issue CSPACE-401.
-    public void createWithEmptyEntityBody() {}
-    public void createWithMalformedXml() {}
-    public void createWithWrongXmlSchema() {}
+    public void createWithEmptyEntityBody() {
+    }
+
+    public void createWithMalformedXml() {
+    }
+
+    public void createWithWrongXmlSchema() {
+    }
 
-/*
+    /*
     @Override
     @Test(dependsOnMethods = {"create", "testSubmitRequest"})
     public void createWithEmptyEntityBody() {
-    
-        // Perform setup.
-        setupCreateWithEmptyEntityBody();
 
-        // Submit the request to the service and store the response.
-        String method = REQUEST_TYPE.httpMethodName();
-        String url = getServiceRootURL();
-        String mediaType = MediaType.APPLICATION_XML;
-        final String entity = "";
-        int statusCode = submitRequest(method, url, mediaType, entity);
-        
-        // Check the status code of the response: does it match
-        // the expected response(s)?
-        verbose("createWithEmptyEntityBody url=" + url + " status=" + statusCode);
-        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
-        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+    // Perform setup.
+    setupCreateWithEmptyEntityBody();
+
+    // Submit the request to the service and store the response.
+    String method = REQUEST_TYPE.httpMethodName();
+    String url = getServiceRootURL();
+    String mediaType = MediaType.APPLICATION_XML;
+    final String entity = "";
+    int statusCode = submitRequest(method, url, mediaType, entity);
+
+    // Check the status code of the response: does it match
+    // the expected response(s)?
+    verbose("createWithEmptyEntityBody url=" + url + " status=" + statusCode);
+    Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+    invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+    Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
     }
 
     @Override
     @Test(dependsOnMethods = {"create", "testSubmitRequest"})
     public void createWithMalformedXml() {
-    
-        // Perform setup.
-        setupCreateWithMalformedXml();
 
-        // Submit the request to the service and store the response.
-        String method = REQUEST_TYPE.httpMethodName();
-        String url = getServiceRootURL();
-        String mediaType = MediaType.APPLICATION_XML;
-        final String entity = MALFORMED_XML_DATA; // Constant from base class.
-        int statusCode = submitRequest(method, url, mediaType, entity);
-        
-        // Check the status code of the response: does it match
-        // the expected response(s)?
-        verbose("createWithMalformedXml url=" + url + " status=" + statusCode);
-        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
-        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+    // Perform setup.
+    setupCreateWithMalformedXml();
+
+    // Submit the request to the service and store the response.
+    String method = REQUEST_TYPE.httpMethodName();
+    String url = getServiceRootURL();
+    String mediaType = MediaType.APPLICATION_XML;
+    final String entity = MALFORMED_XML_DATA; // Constant from base class.
+    int statusCode = submitRequest(method, url, mediaType, entity);
+
+    // Check the status code of the response: does it match
+    // the expected response(s)?
+    verbose("createWithMalformedXml url=" + url + " status=" + statusCode);
+    Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+    invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+    Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
     }
 
     @Override
     @Test(dependsOnMethods = {"create", "testSubmitRequest"})
     public void createWithWrongXmlSchema() {
-    
-        // Perform setup.
-        setupCreateWithWrongXmlSchema();
-     
-        // Submit the request to the service and store the response.
-        String method = REQUEST_TYPE.httpMethodName();
-        String url = getServiceRootURL();
-        String mediaType = MediaType.APPLICATION_XML;
-        final String entity = WRONG_XML_SCHEMA_DATA;
-        int statusCode = submitRequest(method, url, mediaType, entity);
-        
-        // Check the status code of the response: does it match
-        // the expected response(s)?
-        verbose("createWithWrongSchema url=" + url + " status=" + statusCode);
-        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
-        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
-    }
-*/
 
+    // Perform setup.
+    setupCreateWithWrongXmlSchema();
+
+    // Submit the request to the service and store the response.
+    String method = REQUEST_TYPE.httpMethodName();
+    String url = getServiceRootURL();
+    String mediaType = MediaType.APPLICATION_XML;
+    final String entity = WRONG_XML_SCHEMA_DATA;
+    int statusCode = submitRequest(method, url, mediaType, entity);
+
+    // Check the status code of the response: does it match
+    // the expected response(s)?
+    verbose("createWithWrongSchema url=" + url + " status=" + statusCode);
+    Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+    invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+    Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+    }
+     */
     // ---------------------------------------------------------------
     // CRUD tests : READ tests
     // ---------------------------------------------------------------
-
     // Success outcomes
-
     @Override
     @Test(dependsOnMethods = {"create"})
     public void read() {
-    
+
         // Perform setup.
         setupRead();
 
         // Submit the request to the service and store the response.
-        ClientResponse<Intake> res = client.read(knownResourceId);
+        ClientResponse<MultipartInput> res = client.read(knownResourceId);
         int statusCode = res.getStatus();
-            
+
         // Check the status code of the response: does it match
         // the expected response(s)?
         verbose("read: status = " + statusCode);
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+        //FIXME: remove the following try catch once Aron fixes signatures
+        try{
+            MultipartInput input = (MultipartInput) res.getEntity();
+            IntakesCommon intake = (IntakesCommon) extractPart(input,
+                    getCommonPartName(), IntakesCommon.class);
+            Assert.assertNotNull(intake);
+        }catch(Exception e){
+            throw new RuntimeException(e);
+        }
     }
 
     // Failure outcomes
-
     @Override
     @Test(dependsOnMethods = {"read"})
     public void readNonExistent() {
 
         // Perform setup.
         setupReadNonExistent();
-        
+
         // Submit the request to the service and store the response.
-        ClientResponse<Intake> res = client.read(NON_EXISTENT_ID);
+        ClientResponse<MultipartInput> res = client.read(NON_EXISTENT_ID);
         int statusCode = res.getStatus();
 
         // Check the status code of the response: does it match
         // the expected response(s)?
         verbose("readNonExistent: status = " + res.getStatus());
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
     }
 
-
     // ---------------------------------------------------------------
     // CRUD tests : READ_LIST tests
     // ---------------------------------------------------------------
-
     // Success outcomes
-
     @Override
-    @Test(dependsOnMethods = {"createList"})
+    @Test(dependsOnMethods = {"read"})
     public void readList() {
-    
+
         // Perform setup.
         setupReadList();
 
         // Submit the request to the service and store the response.
-        ClientResponse<IntakeList> res = client.readList();
-        IntakeList list = res.getEntity();
+        ClientResponse<IntakesCommonList> res = client.readList();
+        IntakesCommonList list = res.getEntity();
         int statusCode = res.getStatus();
 
         // Check the status code of the response: does it match
         // the expected response(s)?
         verbose("readList: status = " + res.getStatus());
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
 
         // Optionally output additional data about list members for debugging.
         boolean iterateThroughList = false;
-        if (iterateThroughList && logger.isDebugEnabled()) {
-            List<IntakeList.IntakeListItem> items =
-                list.getIntakeListItem();
+        if(iterateThroughList && logger.isDebugEnabled()){
+            List<IntakesCommonList.IntakeListItem> items =
+                    list.getIntakeListItem();
             int i = 0;
-            for(IntakeList.IntakeListItem item : items){
+            for(IntakesCommonList.IntakeListItem item : items){
                 verbose("readList: list-item[" + i + "] csid=" +
-                    item.getCsid());
+                        item.getCsid());
                 verbose("readList: list-item[" + i + "] objectNumber=" +
-                    item.getEntryNumber());
+                        item.getEntryNumber());
                 verbose("readList: list-item[" + i + "] URI=" +
-                    item.getUri());
+                        item.getUri());
                 i++;
             }
         }
-        
+
     }
 
     // Failure outcomes
-    
     // None at present.
-
-
     // ---------------------------------------------------------------
     // CRUD tests : UPDATE tests
     // ---------------------------------------------------------------
-
     // Success outcomes
-
     @Override
-    @Test(dependsOnMethods = {"create"})
+    @Test(dependsOnMethods = {"read"})
     public void update() {
-    
+
         // Perform setup.
         setupUpdate();
 
-        // Retrieve an existing resource that we can update.
-        ClientResponse<Intake> res = client.read(knownResourceId);
-        verbose("read: status = " + res.getStatus());
-        Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
-        Intake intake = res.getEntity();
-        verbose("Got object to update with ID: " + knownResourceId,
-                intake, Intake.class);
-
-        // Update the content of this resource.
-        intake.setEntryNumber("updated-" + intake.getEntryNumber());
-        intake.setEntryDate("updated-" + intake.getEntryDate());
-    
-        // Submit the request to the service and store the response.
-        res = client.update(knownResourceId, intake);
-        int statusCode = res.getStatus();
-        Intake updatedObject = res.getEntity();
-
-        // Check the status code of the response: does it match
-        // the expected response(s)?
-        verbose("update: status = " + res.getStatus());
-        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
-        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
-        
-        // Check the contents of the response: does it match
-        // what was submitted?
-        verbose("update: ", updatedObject, Intake.class);
-        Assert.assertEquals(updatedObject.getEntryDate(), 
-            intake.getEntryDate(), 
-            "Data in updated object did not match submitted data.");
+        try{ //ideally, just remove try-catch and let the exception bubble up
+            // Retrieve an existing resource that we can update.
+            ClientResponse<MultipartInput> res =
+                    client.read(knownResourceId);
+            verbose("update: read status = " + res.getStatus());
+            Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
+
+            verbose("got object to update with ID: " + knownResourceId);
+            MultipartInput input = (MultipartInput) res.getEntity();
+            IntakesCommon intake = (IntakesCommon) extractPart(input,
+                    getCommonPartName(), IntakesCommon.class);
+            Assert.assertNotNull(intake);
+
+            // Update the content of this resource.
+            // Update the content of this resource.
+            intake.setEntryNumber("updated-" + intake.getEntryNumber());
+            intake.setEntryDate("updated-" + intake.getEntryDate());
+            verbose("to be updated object", intake, IntakesCommon.class);
+            // Submit the request to the service and store the response.
+            MultipartOutput output = new MultipartOutput();
+            OutputPart commonPart = output.addPart(intake, MediaType.APPLICATION_XML_TYPE);
+            commonPart.getHeaders().add("label", getCommonPartName());
+
+            res = client.update(knownResourceId, output);
+            int statusCode = res.getStatus();
+            // Check the status code of the response: does it match the expected response(s)?
+            verbose("update: status = " + res.getStatus());
+            Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+                    invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+            Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+
+
+            input = (MultipartInput) res.getEntity();
+            IntakesCommon updatedIntake =
+                    (IntakesCommon) extractPart(input,
+                    getCommonPartName(), IntakesCommon.class);
+            Assert.assertNotNull(updatedIntake);
+
+            Assert.assertEquals(updatedIntake.getEntryDate(),
+                    intake.getEntryDate(),
+                    "Data in updated object did not match submitted data.");
+        }catch(Exception e){
+            e.printStackTrace();
+        }
     }
 
     // Failure outcomes
-
     // Placeholders until the three tests below can be uncommented.
     // See Issue CSPACE-401.
-    public void updateWithEmptyEntityBody() {}
-    public void updateWithMalformedXml() {}
-    public void updateWithWrongXmlSchema() {}
+    public void updateWithEmptyEntityBody() {
+    }
+
+    public void updateWithMalformedXml() {
+    }
+
+    public void updateWithWrongXmlSchema() {
+    }
 
-/*
+    /*
     @Override
     @Test(dependsOnMethods = {"create", "update", "testSubmitRequest"})
     public void updateWithEmptyEntityBody() {
-    
-        // Perform setup.
-        setupUpdateWithEmptyEntityBody();
 
-        // Submit the request to the service and store the response.
-        String method = REQUEST_TYPE.httpMethodName();
-        String url = getResourceURL(knownResourceId);
-        String mediaType = MediaType.APPLICATION_XML;
-        final String entity = "";
-        int statusCode = submitRequest(method, url, mediaType, entity);
-        
-        // Check the status code of the response: does it match
-        // the expected response(s)?
-        verbose("updateWithEmptyEntityBody url=" + url + " status=" + statusCode);
-        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
-        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+    // Perform setup.
+    setupUpdateWithEmptyEntityBody();
+
+    // Submit the request to the service and store the response.
+    String method = REQUEST_TYPE.httpMethodName();
+    String url = getResourceURL(knownResourceId);
+    String mediaType = MediaType.APPLICATION_XML;
+    final String entity = "";
+    int statusCode = submitRequest(method, url, mediaType, entity);
+
+    // Check the status code of the response: does it match
+    // the expected response(s)?
+    verbose("updateWithEmptyEntityBody url=" + url + " status=" + statusCode);
+    Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+    invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+    Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
     }
 
     @Override
     @Test(dependsOnMethods = {"create", "update", "testSubmitRequest"})
     public void updateWithMalformedXml() {
 
-        // Perform setup.
-        setupUpdateWithMalformedXml();
-
-        // Submit the request to the service and store the response.
-        String method = REQUEST_TYPE.httpMethodName();
-        String url = getResourceURL(knownResourceId);
-        String mediaType = MediaType.APPLICATION_XML;
-        final String entity = MALFORMED_XML_DATA;
-        int statusCode = submitRequest(method, url, mediaType, entity);
-        
-        // Check the status code of the response: does it match
-        // the expected response(s)?
-        verbose("updateWithMalformedXml: url=" + url + " status=" + statusCode);
-        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
-        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+    // Perform setup.
+    setupUpdateWithMalformedXml();
+
+    // Submit the request to the service and store the response.
+    String method = REQUEST_TYPE.httpMethodName();
+    String url = getResourceURL(knownResourceId);
+    String mediaType = MediaType.APPLICATION_XML;
+    final String entity = MALFORMED_XML_DATA;
+    int statusCode = submitRequest(method, url, mediaType, entity);
+
+    // Check the status code of the response: does it match
+    // the expected response(s)?
+    verbose("updateWithMalformedXml: url=" + url + " status=" + statusCode);
+    Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+    invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+    Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
     }
 
     @Override
     @Test(dependsOnMethods = {"create", "update", "testSubmitRequest"})
     public void updateWithWrongXmlSchema() {
-    
-        // Perform setup.
-        setupUpdateWithWrongXmlSchema();
-        
-        // Submit the request to the service and store the response.
-        String method = REQUEST_TYPE.httpMethodName();
-        String url = getResourceURL(knownResourceId);
-        String mediaType = MediaType.APPLICATION_XML;
-        final String entity = WRONG_XML_SCHEMA_DATA;
-        int statusCode = submitRequest(method, url, mediaType, entity);
-        
-        // Check the status code of the response: does it match
-        // the expected response(s)?
-        verbose("updateWithWrongSchema: url=" + url + " status=" + statusCode);
-        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
-        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
-    }
-*/
 
+    // Perform setup.
+    setupUpdateWithWrongXmlSchema();
+
+    // Submit the request to the service and store the response.
+    String method = REQUEST_TYPE.httpMethodName();
+    String url = getResourceURL(knownResourceId);
+    String mediaType = MediaType.APPLICATION_XML;
+    final String entity = WRONG_XML_SCHEMA_DATA;
+    int statusCode = submitRequest(method, url, mediaType, entity);
+
+    // Check the status code of the response: does it match
+    // the expected response(s)?
+    verbose("updateWithWrongSchema: url=" + url + " status=" + statusCode);
+    Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+    invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+    Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+    }
+     */
     @Override
     @Test(dependsOnMethods = {"update", "testSubmitRequest"})
     public void updateNonExistent() {
@@ -401,28 +419,27 @@ public class IntakeServiceTest extends AbstractServiceTest {
         // Submit the request to the service and store the response.
         // Note: The ID used in this 'create' call may be arbitrary.
         // The only relevant ID may be the one used in update(), below.
-        Intake intake = createIntakeInstance(NON_EXISTENT_ID);
-        ClientResponse<Intake> res =
-          client.update(NON_EXISTENT_ID, intake);
+
+        // The only relevant ID may be the one used in update(), below.
+        MultipartOutput multipart = createIntakeInstance(NON_EXISTENT_ID);
+        ClientResponse<MultipartInput> res =
+                client.update(NON_EXISTENT_ID, multipart);
         int statusCode = res.getStatus();
 
         // Check the status code of the response: does it match
         // the expected response(s)?
         verbose("updateNonExistent: status = " + res.getStatus());
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
     }
 
     // ---------------------------------------------------------------
     // CRUD tests : DELETE tests
     // ---------------------------------------------------------------
-
     // Success outcomes
-
     @Override
-    @Test(dependsOnMethods = 
-        {"create", "read", "update"})
+    @Test(dependsOnMethods = {"create", "readList", "testSubmitRequest", "update"})
     public void delete() {
 
         // Perform setup.
@@ -436,12 +453,11 @@ public class IntakeServiceTest extends AbstractServiceTest {
         // the expected response(s)?
         verbose("delete: status = " + res.getStatus());
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
     }
 
     // Failure outcomes
-
     @Override
     @Test(dependsOnMethods = {"delete"})
     public void deleteNonExistent() {
@@ -457,15 +473,13 @@ public class IntakeServiceTest extends AbstractServiceTest {
         // the expected response(s)?
         verbose("deleteNonExistent: status = " + res.getStatus());
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
     }
 
-
     // ---------------------------------------------------------------
     // Utility tests : tests of code used in tests above
     // ---------------------------------------------------------------
-
     /**
      * Tests the code for manually submitting data that is used by several
      * of the methods above.
@@ -480,36 +494,38 @@ public class IntakeServiceTest extends AbstractServiceTest {
         String method = ServiceRequestType.READ.httpMethodName();
         String url = getResourceURL(knownResourceId);
         int statusCode = submitRequest(method, url);
-        
+
         // Check the status code of the response: does it match
         // the expected response(s)?
         verbose("testSubmitRequest: url=" + url + " status=" + statusCode);
         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
 
-    }          
+    }
 
     // ---------------------------------------------------------------
     // Utility methods used by tests above
     // ---------------------------------------------------------------
-
     @Override
     public String getServicePathComponent() {
         return SERVICE_PATH_COMPONENT;
     }
-    
-    private Intake createIntakeInstance(String identifier) {
-        Intake intake =
-            createIntakeInstance(
+
+    private MultipartOutput createIntakeInstance(String identifier) {
+        return createIntakeInstance(
                 "entryNumber-" + identifier,
                 "entryDate-" + identifier);
-        return intake;
     }
-    
-    private Intake createIntakeInstance(String entryNumber, String entryDate) {
-        Intake intake = new Intake();
+
+    private MultipartOutput createIntakeInstance(String entryNumber, String entryDate) {
+        IntakesCommon intake = new IntakesCommon();
         intake.setEntryNumber(entryNumber);
         intake.setEntryDate(entryDate);
-        return intake;
-    }
+        MultipartOutput multipart = new MultipartOutput();
+        OutputPart commonPart = multipart.addPart(intake, MediaType.APPLICATION_XML_TYPE);
+        commonPart.getHeaders().add("label", getCommonPartName());
+
+        verbose("to be created, intake common ", intake, IntakesCommon.class);
 
+        return multipart;
+    }
 }
index d2528a04469a19eba466db4e11411bcb720d8930..8dce3b89ce95a9259fbe3fcc06013fd766ab06e3 100644 (file)
@@ -56,8 +56,8 @@
                     <dependency>
                         <groupId>com.sun.xml.bind</groupId>
                         <artifactId>jaxb-impl</artifactId>
-                        <version>2.1.2</version>
-                    </dependency>
+                        <version>2.1.9</version>
+                     </dependency>
                 </dependencies>
                 <configuration>
                     <args>
similarity index 95%
rename from services/intake/jaxb/src/main/resources/intake.xsd
rename to services/intake/jaxb/src/main/resources/intakes-common.xsd
index a65b93c3b2ebe87ddc1ed8666538045e173089d7..485eafa756f6c6f0f8f64cd57fd1b6dde4c0a4d2 100644 (file)
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <xs:schema 
   xmlns:xs="http://www.w3.org/2001/XMLSchema"
-  xmlns:ns="http://collectionspace.org/intake"
-  xmlns="http://collectionspace.org/intake"
-  targetNamespace="http://services.collectionspace.org/intake"
+  xmlns:ns="http://collectionspace.org/services/intake"
+  xmlns="http://collectionspace.org/services/intake"
+  targetNamespace="http://collectionspace.org/services/intake"
   version="0.1"
 >
 
@@ -12,7 +12,7 @@
 <!-- See http://wiki.collectionspace.org/display/collectionspace/Intake+Schema -->    
     
     <!-- intake  -->
-    <xs:element name="intake">
+    <xs:element name="intakes-common">
         <xs:complexType>
             <xs:sequence>
                 <xs:element name="csid" type="xs:string" />
@@ -87,7 +87,7 @@
     </xs:element>
     
     <!-- intake records, as in nuxeo repository -->
-    <xs:element name="intake-list">
+    <xs:element name="intakes-common-list">
         <xs:complexType>
             <xs:sequence>
                 <xs:element name="intake-list-item" maxOccurs="unbounded">
diff --git a/services/intake/service/profiles.xml b/services/intake/service/profiles.xml
new file mode 100644 (file)
index 0000000..347b9df
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<profilesXml xmlns="http://maven.apache.org/PROFILES/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/PROFILES/1.0.0 http://maven.apache.org/xsd/profiles-1.0.0.xsd">
+</profilesXml>
\ No newline at end of file
index d7189ccd8ce8c5ba88e05d055d845400b2ff86cf..3a1dd56e3a69303d6892d085b86f892c39086300 100644 (file)
@@ -36,53 +36,62 @@ 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.intake.IntakeList.*;
+import org.collectionspace.services.common.AbstractCollectionSpaceResource;
+import org.collectionspace.services.intake.IntakesCommonList.*;
 
-import org.collectionspace.services.intake.nuxeo.IntakeConstants;
 import org.collectionspace.services.intake.nuxeo.IntakeHandlerFactory;
-import org.collectionspace.services.common.NuxeoClientType;
+import org.collectionspace.services.common.ClientType;
 import org.collectionspace.services.common.ServiceMain;
+import org.collectionspace.services.common.context.ServiceContext;
 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.plugins.providers.multipart.MultipartInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
 import org.jboss.resteasy.util.HttpResponseCodes;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @Path("/intakes")
-@Consumes("application/xml")
-@Produces("application/xml")
-public class IntakeResource {
+@Consumes("multipart/mixed")
+@Produces("multipart/mixed")
+public class IntakeResource extends AbstractCollectionSpaceResource {
 
-    public final static String INTAKE_SERVICE_NAME = "intakes";
+    private final static String serviceName = "intakes";
     final Logger logger = LoggerFactory.getLogger(IntakeResource.class);
     //FIXME retrieve client type from configuration
-    final static NuxeoClientType CLIENT_TYPE = ServiceMain.getInstance().getNuxeoClientType();
+    final static ClientType CLIENT_TYPE = ServiceMain.getInstance().getClientType();
 
     public IntakeResource() {
         // do nothing
     }
 
-    @POST
-    public Response createIntake(
-            Intake intakeObject) {
+    @Override
+    public String getServiceName() {
+        return serviceName;
+    }
 
-        String csid = null;
-        try{
-            RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
-            RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
-            IntakeHandlerFactory handlerFactory = IntakeHandlerFactory.getInstance();
-            DocumentHandler handler = (DocumentHandler) handlerFactory.getHandler(CLIENT_TYPE.toString());
-            handler.setCommonObject(intakeObject);
-            csid = client.create(INTAKE_SERVICE_NAME, handler);
-            intakeObject.setCsid(csid);
-            if(logger.isDebugEnabled()){
-                verbose("createIntake: ", intakeObject);
+    @Override
+    public DocumentHandler createDocumentHandler(ServiceContext ctx) throws Exception {
+        DocumentHandler docHandler = IntakeHandlerFactory.getInstance().getHandler(
+                ctx.getRepositoryClientType().toString());
+        docHandler.setServiceContext(ctx);
+        if(ctx.getInput() != null){
+            Object obj = ctx.getInputPart(ctx.getCommonPartLabel(), IntakesCommon.class);
+            if(obj != null){
+                docHandler.setCommonPart((IntakesCommon) obj);
             }
+        }
+        return docHandler;
+    }
+
+    @POST
+    public Response createIntake(MultipartInput input) {
+        try{
+            ServiceContext ctx = createServiceContext(input);
+            DocumentHandler handler = createDocumentHandler(ctx);
+            String csid = getRepositoryClient(ctx).create(ctx, handler);
+            //intakeObject.setCsid(csid);
             UriBuilder path = UriBuilder.fromResource(IntakeResource.class);
             path.path("" + csid);
             Response response = Response.created(path.build()).build();
@@ -99,10 +108,10 @@ public class IntakeResource {
 
     @GET
     @Path("{csid}")
-    public Intake getIntake(
+    public MultipartOutput getIntake(
             @PathParam("csid") String csid) {
         if(logger.isDebugEnabled()){
-            verbose("getIntake with csid=" + csid);
+            logger.debug("getIntake with csid=" + csid);
         }
         if(csid == null || "".equals(csid)){
             logger.error("getIntake: missing csid!");
@@ -111,14 +120,12 @@ public class IntakeResource {
                     "text/plain").build();
             throw new WebApplicationException(response);
         }
-        Intake intakeObject = null;
+        MultipartOutput result = null;
         try{
-            RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
-            RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
-            IntakeHandlerFactory handlerFactory = IntakeHandlerFactory.getInstance();
-            DocumentHandler handler = (DocumentHandler) handlerFactory.getHandler(CLIENT_TYPE.toString());
-            client.get(csid, handler);
-            intakeObject = (Intake) handler.getCommonObject();
+            ServiceContext ctx = createServiceContext(null);
+            DocumentHandler handler = createDocumentHandler(ctx);
+            getRepositoryClient(ctx).get(ctx, csid, handler);
+            result = ctx.getOutput();
         }catch(DocumentNotFoundException dnfe){
             if(logger.isDebugEnabled()){
                 logger.debug("getIntake", dnfe);
@@ -135,29 +142,24 @@ public class IntakeResource {
                     Response.Status.INTERNAL_SERVER_ERROR).entity("Get failed").type("text/plain").build();
             throw new WebApplicationException(response);
         }
-
-        if(intakeObject == null){
+        if(result == null){
             Response response = Response.status(Response.Status.NOT_FOUND).entity(
                     "Get failed, the requested Intake CSID:" + csid + ": was not found.").type(
                     "text/plain").build();
             throw new WebApplicationException(response);
         }
-        if(logger.isDebugEnabled()){
-            verbose("getIntake: ", intakeObject);
-        }
-        return intakeObject;
+        return result;
     }
 
     @GET
-    public IntakeList getIntakeList(@Context UriInfo ui) {
-        IntakeList intakeObjectList = new IntakeList();
+    @Produces("application/xml")
+    public IntakesCommonList getIntakeList(@Context UriInfo ui) {
+        IntakesCommonList intakeObjectList = new IntakesCommonList();
         try{
-            RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
-            RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
-            IntakeHandlerFactory handlerFactory = IntakeHandlerFactory.getInstance();
-            DocumentHandler handler = (DocumentHandler) handlerFactory.getHandler(CLIENT_TYPE.toString());
-            client.getAll(INTAKE_SERVICE_NAME, handler);
-            intakeObjectList = (IntakeList) handler.getCommonObjectList();
+            ServiceContext ctx = createServiceContext(null);
+            DocumentHandler handler = createDocumentHandler(ctx);
+            getRepositoryClient(ctx).getAll(ctx, handler);
+            intakeObjectList = (IntakesCommonList) handler.getCommonPartList();
         }catch(Exception e){
             if(logger.isDebugEnabled()){
                 logger.debug("Caught exception in getIntakeList", e);
@@ -171,11 +173,11 @@ public class IntakeResource {
 
     @PUT
     @Path("{csid}")
-    public Intake updateIntake(
+    public MultipartOutput updateIntake(
             @PathParam("csid") String csid,
-            Intake theUpdate) {
+            MultipartInput theUpdate) {
         if(logger.isDebugEnabled()){
-            verbose("updateIntake with csid=" + csid);
+            logger.debug("updateIntake with csid=" + csid);
         }
         if(csid == null || "".equals(csid)){
             logger.error("updateIntake: missing csid!");
@@ -184,16 +186,12 @@ public class IntakeResource {
                     "text/plain").build();
             throw new WebApplicationException(response);
         }
-        if(logger.isDebugEnabled()){
-            verbose("updateIntake with input: ", theUpdate);
-        }
+        MultipartOutput result = null;
         try{
-            RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
-            RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
-            IntakeHandlerFactory handlerFactory = IntakeHandlerFactory.getInstance();
-            DocumentHandler handler = (DocumentHandler) handlerFactory.getHandler(CLIENT_TYPE.toString());
-            handler.setCommonObject(theUpdate);
-            client.update(csid, handler);
+            ServiceContext ctx = createServiceContext(theUpdate);
+            DocumentHandler handler = createDocumentHandler(ctx);
+            getRepositoryClient(ctx).update(ctx, csid, handler);
+            result = ctx.getOutput();
         }catch(DocumentNotFoundException dnfe){
             if(logger.isDebugEnabled()){
                 logger.debug("caugth exception in updateIntake", dnfe);
@@ -207,7 +205,7 @@ public class IntakeResource {
                     Response.Status.INTERNAL_SERVER_ERROR).entity("Update failed").type("text/plain").build();
             throw new WebApplicationException(response);
         }
-        return theUpdate;
+        return result;
     }
 
     @DELETE
@@ -215,7 +213,7 @@ public class IntakeResource {
     public Response deleteIntake(@PathParam("csid") String csid) {
 
         if(logger.isDebugEnabled()){
-            verbose("deleteIntake with csid=" + csid);
+            logger.debug("deleteIntake with csid=" + csid);
         }
         if(csid == null || "".equals(csid)){
             logger.error("deleteIntake: missing csid!");
@@ -225,9 +223,8 @@ public class IntakeResource {
             throw new WebApplicationException(response);
         }
         try{
-            RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
-            RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
-            client.delete(csid);
+            ServiceContext ctx = createServiceContext(null);
+            getRepositoryClient(ctx).delete(ctx, csid);
             return Response.status(HttpResponseCodes.SC_OK).build();
         }catch(DocumentNotFoundException dnfe){
             if(logger.isDebugEnabled()){
@@ -244,23 +241,4 @@ public class IntakeResource {
         }
 
     }
-
-    private void verbose(String msg, Intake intakeObject) {
-        try{
-            verbose(msg);
-            JAXBContext jc = JAXBContext.newInstance(
-                    Intake.class);
-
-            Marshaller m = jc.createMarshaller();
-            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
-            m.marshal(intakeObject, System.out);
-        }catch(Exception e){
-            e.printStackTrace();
-        }
-
-    }
-
-    private void verbose(String msg) {
-        System.out.println("IntakeResource. " + msg);
-    }
 }
diff --git a/services/intake/service/src/main/java/org/collectionspace/services/intake/IntakeService.java b/services/intake/service/src/main/java/org/collectionspace/services/intake/IntakeService.java
deleted file mode 100644 (file)
index f74ff48..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/**\r
- * \r
- */\r
-package org.collectionspace.services.intake;\r
-\r
-import java.io.IOException;\r
-import org.dom4j.Document;\r
-import org.dom4j.DocumentException;\r
-\r
-import org.collectionspace.services.intake.Intake;\r
-\r
-/**\r
- * @author remillet\r
- * \r
- */\r
-public interface IntakeService {\r
-\r
-       public final static String INTAKE_SCHEMA_NAME = "intake";\r
-\r
-       // Create\r
-       Document postIntake(Intake co)\r
-                       throws DocumentException, IOException;\r
-\r
-       // Read single object\r
-       Document getIntake(String csid) throws DocumentException,\r
-                       IOException;\r
-\r
-       // Read a list of objects\r
-       Document getIntakeList() throws DocumentException, IOException;\r
-\r
-       // Update\r
-       Document putIntake(String csid, Intake theUpdate)\r
-                       throws DocumentException, IOException;\r
-\r
-       // Delete\r
-       Document deleteIntake(String csid) throws DocumentException,\r
-                       IOException;\r
-}\r
diff --git a/services/intake/service/src/main/java/org/collectionspace/services/intake/IntakeServiceNuxeoImpl.java b/services/intake/service/src/main/java/org/collectionspace/services/intake/IntakeServiceNuxeoImpl.java
deleted file mode 100644 (file)
index 0034326..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-/**\r
- * \r
- */\r
-package org.collectionspace.services.intake;\r
-\r
-import org.collectionspace.services.*;\r
-import java.io.ByteArrayInputStream;\r
-import java.io.IOException;\r
-import java.util.ArrayList;\r
-import java.util.Arrays;\r
-import java.util.HashMap;\r
-import java.util.List;\r
-import java.util.Map;\r
-\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
-\r
-import org.dom4j.Document;\r
-import org.dom4j.DocumentException;\r
-import org.dom4j.io.SAXReader;\r
-import org.restlet.resource.Representation;\r
-\r
-/**\r
- * @author remillet\r
- * \r
- */\r
-public class IntakeServiceNuxeoImpl extends\r
-               CollectionSpaceServiceNuxeoImpl implements IntakeService {\r
-\r
-       final static String INTAKE_NUXEO_DOCTYPE = "Intake";\r
-       final static String INTAKE_NUXEO_SCHEMA_NAME = "intake";\r
-       final static String INTAKE_NUXEO_DC_TITLE = "CollectionSpace-Intake";\r
-\r
-       // replace WORKSPACE_UID for resource workspace\r
-       static String CS_INTAKE_WORKSPACE_UID = "c04210c4-9426-475f-b4ee-aa3d6aa4b97c";\r
-\r
-       public Document deleteIntake(String csid)\r
-                       throws DocumentException, IOException {\r
-\r
-               Document result = null;\r
-               \r
-//             NuxeoRESTClient nxClient = getClient();\r
-//             List<String> pathParams = new ArrayList<String>();\r
-//             Map<String, String> queryParams = new HashMap<String, String>();\r
-//\r
-//             pathParams.add("default");\r
-//             pathParams.add(csid);\r
-//             pathParams.add("deleteDocumentRestlet");\r
-//             Representation res = nxClient.get(pathParams, queryParams);\r
-//             SAXReader reader = new SAXReader();\r
-//             result = reader.read(res.getStream());\r
-               \r
-               return result;\r
-       }\r
-\r
-       public Document getIntake(String csid) throws DocumentException,\r
-                       IOException {\r
-               Document result = null;\r
-               \r
-//             List<String> pathParams = new ArrayList<String>();\r
-//             Map<String, String> queryParams = new HashMap<String, String>();\r
-//\r
-//             pathParams.add("default");\r
-//             pathParams.add(csid);\r
-//             pathParams.add("export");\r
-//             queryParams.put("format", "XML");\r
-//\r
-//             NuxeoRESTClient nxClient = getClient();\r
-//             Representation res = nxClient.get(pathParams, queryParams);\r
-//\r
-//             SAXReader reader = new SAXReader();\r
-//             result = reader.read(res.getStream());\r
-\r
-               return result;\r
-       }\r
-\r
-       public Document getIntakeList() throws DocumentException,\r
-                       IOException {\r
-               Document result = null;\r
-\r
-//             NuxeoRESTClient nxClient = getClient();\r
-//             List<String> pathParams = new ArrayList<String>();\r
-//             Map<String, String> queryParams = new HashMap<String, String>();\r
-//             pathParams = Arrays.asList("default",\r
-//                             CS_INTAKE_WORKSPACE_UID, "browse");\r
-//             Representation res = nxClient.get(pathParams, queryParams);\r
-//             SAXReader reader = new SAXReader();\r
-//             result = reader.read(res.getStream());\r
-\r
-               return result;\r
-       }\r
-\r
-       public Document postIntake(Intake co)\r
-                       throws DocumentException, IOException {\r
-               Document result = null;\r
-               \r
-//             NuxeoRESTClient nxClient = getClient();\r
-//\r
-//             List<String> pathParams = new ArrayList<String>();\r
-//             Map<String, String> queryParams = new HashMap<String, String>();\r
-//             pathParams.add("default");\r
-//             pathParams.add(CS_INTAKE_WORKSPACE_UID);\r
-//             pathParams.add("createDocument");\r
-//             queryParams.put("docType", INTAKE_NUXEO_DOCTYPE);\r
-//\r
-//             // a default title for the Dublin Core schema\r
-//             queryParams.put("dublincore:title", INTAKE_NUXEO_DC_TITLE);\r
-//\r
-//             // Intake core values\r
-//             queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-//                             + IntakeJAXBSchema.CURRENT_OWNER, co\r
-//                             .getCurrentOwner());\r
-//             queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-//                             + IntakeJAXBSchema.DEPOSITOR, co.getDepositor());\r
-//             queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-//                             + IntakeJAXBSchema.DEPOSITORS_REQUIREMENTS, co\r
-//                             .getDepositorsRequirements());\r
-//             queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-//                             + IntakeJAXBSchema.ENTRY_DATE, co.getEntryDate());\r
-//             queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-//                             + IntakeJAXBSchema.ENTRY_METHOD, co\r
-//                             .getEntryMethod());\r
-//             queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-//                             + IntakeJAXBSchema.ENTRY_NOTE, co.getEntryNote());\r
-//             queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-//                             + IntakeJAXBSchema.ENTRY_NUMBER, co\r
-//                             .getEntryNumber());\r
-//             queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-//                             + IntakeJAXBSchema.ENTRY_REASON, co.getEntryReason());\r
-//             queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-//                             + IntakeJAXBSchema.PACKING_NOTE, co.getPackingNote());\r
-//             queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-//                             + IntakeJAXBSchema.RETURN_DATE, co.getReturnDate());\r
-//\r
-//             ByteArrayInputStream bais = new ByteArrayInputStream(new byte[0]);\r
-//             Representation res = nxClient.post(pathParams, queryParams, bais);\r
-//\r
-//             SAXReader reader = new SAXReader();\r
-//             result = reader.read(res.getStream());\r
-\r
-               return result;\r
-       }\r
-\r
-       public Document putIntake(String csid, Intake theUpdate)\r
-                       throws DocumentException, IOException {\r
-               Document result = null;\r
-               \r
-//             List<String> pathParams = new ArrayList<String>();\r
-//             Map<String, String> queryParams = new HashMap<String, String>();\r
-//             pathParams.add("default");\r
-//             pathParams.add(csid);\r
-//             pathParams.add("updateDocumentRestlet");\r
-//\r
-//             // todo: intelligent merge needed\r
-//             if (theUpdate.getCurrentOwner() != null) {\r
-//                     queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-//                                     + IntakeJAXBSchema.CURRENT_OWNER, theUpdate.getCurrentOwner());\r
-//             }\r
-//\r
-//             if (theUpdate.getDepositor() != null) {\r
-//                     queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-//                                     + IntakeJAXBSchema.DEPOSITOR, theUpdate.getDepositor());\r
-//             }\r
-//\r
-//             if (theUpdate.getDepositorsRequirements() != null) {\r
-//                     queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-//                                     + IntakeJAXBSchema.DEPOSITORS_REQUIREMENTS, theUpdate.getDepositorsRequirements());\r
-//             }\r
-//\r
-//             if (theUpdate.getEntryDate() != null) {\r
-//                     queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-//                                     + IntakeJAXBSchema.ENTRY_DATE, theUpdate.getEntryDate());\r
-//             }\r
-//\r
-//             if (theUpdate.getEntryMethod() != null) {\r
-//                     queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-//                                     + IntakeJAXBSchema.ENTRY_METHOD, theUpdate.getEntryMethod());\r
-//             }\r
-//\r
-//             if (theUpdate.getEntryNote() != null) {\r
-//                     queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-//                                     + IntakeJAXBSchema.ENTRY_NOTE, theUpdate.getEntryNote());\r
-//             }\r
-//\r
-//             if (theUpdate.getEntryNumber() != null) {\r
-//                     queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-//                                     + IntakeJAXBSchema.ENTRY_NUMBER, theUpdate.getEntryNumber());\r
-//             }\r
-//\r
-//             if (theUpdate.getEntryReason() != null) {\r
-//                     queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-//                                     + IntakeJAXBSchema.ENTRY_REASON, theUpdate.getEntryReason());\r
-//             }\r
-//\r
-//             if (theUpdate.getPackingNote() != null) {\r
-//                     queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-//                                     + IntakeJAXBSchema.PACKING_NOTE, theUpdate.getPackingNote());\r
-//             }\r
-//\r
-//             if (theUpdate.getReturnDate() != null) {\r
-//                     queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-//                                     + IntakeJAXBSchema.RETURN_DATE, theUpdate.getReturnDate());\r
-//             }\r
-//\r
-//             NuxeoRESTClient nxClient = getClient();\r
-//             Representation res = nxClient.get(pathParams, queryParams);\r
-//             SAXReader reader = new SAXReader();\r
-//             result = reader.read(res.getStream());\r
-\r
-               return result;\r
-       }\r
-\r
-}\r
index 0d0c55355ee9105edd082f15d7201769a02cdad4..71f44b007be6a6aec660104b63c07570c119cfd0 100644 (file)
@@ -28,11 +28,10 @@ import java.util.List;
 
 import org.collectionspace.services.IntakeJAXBSchema;
 import org.collectionspace.services.common.repository.DocumentWrapper;
-import org.collectionspace.services.intake.Intake;
-import org.collectionspace.services.intake.IntakeList;
-import org.collectionspace.services.intake.IntakeList.IntakeListItem;
+import org.collectionspace.services.intake.IntakesCommon;
+import org.collectionspace.services.intake.IntakesCommonList;
+import org.collectionspace.services.intake.IntakesCommonList.IntakeListItem;
 import org.collectionspace.services.nuxeo.client.java.DocumentModelHandler;
-import org.collectionspace.services.intake.nuxeo.IntakeConstants;
 
 import org.nuxeo.ecm.core.api.DocumentModel;
 import org.nuxeo.ecm.core.api.DocumentModelList;
@@ -46,19 +45,19 @@ import org.slf4j.LoggerFactory;
  * $LastChangedDate: $
  */
 public class IntakeDocumentModelHandler
-        extends DocumentModelHandler<Intake, IntakeList> {
+        extends DocumentModelHandler<IntakesCommon, IntakesCommonList> {
 
     private final Logger logger = LoggerFactory.getLogger(IntakeDocumentModelHandler.class);
     /**
      * intake is used to stash JAXB object to use when handle is called
      * for Action.CREATE, Action.UPDATE or Action.GET
      */
-    private Intake intake;
+    private IntakesCommon intake;
     /**
      * intakeList is stashed when handle is called
      * for ACTION.GET_ALL
      */
-    private IntakeList intakeList;
+    private IntakesCommonList intakeList;
 
     @Override
     public void prepare(Action action) throws Exception {
@@ -66,148 +65,54 @@ public class IntakeDocumentModelHandler
     }
 
     /**
-     * getCommonObject get associated intake
+     * getCommonPart get associated intake
      * @return
      */
     @Override
-    public Intake getCommonObject() {
+    public IntakesCommon getCommonPart() {
         return intake;
     }
 
     /**
-     * setCommonObject set associated intake
+     * setCommonPart set associated intake
      * @param intake
      */
     @Override
-    public void setCommonObject(Intake intake) {
+    public void setCommonPart(IntakesCommon intake) {
         this.intake = intake;
     }
 
     /**
-     * getIntakeList get associated intake (for index/GET_ALL)
+     * getCommonPartList get associated intake (for index/GET_ALL)
      * @return
      */
     @Override
-    public IntakeList getCommonObjectList() {
+    public IntakesCommonList getCommonPartList() {
         return intakeList;
     }
 
     @Override
-    public void setCommonObjectList(IntakeList intakeList) {
+    public void setCommonPartList(IntakesCommonList intakeList) {
         this.intakeList = intakeList;
     }
 
     @Override
-    public Intake extractCommonObject(DocumentWrapper wrapDoc)
+    public IntakesCommon extractCommonPart(DocumentWrapper wrapDoc)
             throws Exception {
-        DocumentModel docModel = (DocumentModel) wrapDoc.getWrappedObject();
-        Intake intakeObject = new Intake();
-
-        //FIXME property get should be dynamically set using schema inspection
-        //so it does not require hard coding
-
-        // intake core values
-        intakeObject.setCurrentOwner((String)docModel.getPropertyValue(
-                getQProperty(IntakeJAXBSchema.CURRENT_OWNER)));
-
-        intakeObject.setDepositor((String)docModel.getPropertyValue(getQProperty(
-                IntakeJAXBSchema.DEPOSITOR)));
-
-        intakeObject.setDepositorsRequirements((String)docModel.getPropertyValue(getQProperty(
-                IntakeJAXBSchema.DEPOSITORS_REQUIREMENTS)));
-
-        intakeObject.setEntryDate((String)docModel.getPropertyValue(getQProperty(
-                IntakeJAXBSchema.ENTRY_DATE)));
-
-        intakeObject.setEntryMethod((String)docModel.getPropertyValue(getQProperty(
-                IntakeJAXBSchema.ENTRY_METHOD)));
-
-        intakeObject.setEntryNote((String)docModel.getPropertyValue(getQProperty(
-                IntakeJAXBSchema.ENTRY_NOTE)));
-
-        intakeObject.setEntryNumber((String)docModel.getPropertyValue(getQProperty(
-                IntakeJAXBSchema.ENTRY_NUMBER)));
-
-        intakeObject.setEntryReason((String)docModel.getPropertyValue(getQProperty(
-                IntakeJAXBSchema.ENTRY_REASON)));
-
-        intakeObject.setPackingNote((String)docModel.getPropertyValue(getQProperty(
-                IntakeJAXBSchema.PACKING_NOTE)));
-
-        intakeObject.setReturnDate((String)docModel.getPropertyValue(getQProperty(
-                IntakeJAXBSchema.RETURN_DATE)));
-
-        return intakeObject;
+        throw new UnsupportedOperationException();
     }
 
     @Override
-    public void fillCommonObject(Intake intakeObject, 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", IntakeConstants.NUXEO_DC_TITLE);
-
-        // intake core values
-        if(intakeObject.getCurrentOwner() != null){
-            docModel.setPropertyValue(getQProperty(
-                    IntakeJAXBSchema.CURRENT_OWNER), intakeObject.getCurrentOwner());
-        }
-
-        if(intakeObject.getDepositor() != null){
-            docModel.setPropertyValue(getQProperty(
-                    IntakeJAXBSchema.DEPOSITOR), intakeObject.getDepositor());
-        }
-
-        if(intakeObject.getDepositorsRequirements() != null){
-            docModel.setPropertyValue(getQProperty(
-                    IntakeJAXBSchema.DEPOSITORS_REQUIREMENTS), intakeObject.getDepositorsRequirements());
-        }
-
-        if(intakeObject.getEntryDate() != null){
-            docModel.setPropertyValue(getQProperty(
-                    IntakeJAXBSchema.ENTRY_DATE), intakeObject.getEntryDate());
-        }
-
-        if(intakeObject.getEntryMethod() != null){
-            docModel.setPropertyValue(getQProperty(
-                    IntakeJAXBSchema.ENTRY_METHOD), intakeObject.getEntryMethod());
-        }
-
-        if(intakeObject.getEntryNote() != null){
-            docModel.setPropertyValue(getQProperty(
-                    IntakeJAXBSchema.ENTRY_NOTE), intakeObject.getEntryNote());
-        }
-
-        if(intakeObject.getEntryNumber() != null){
-            docModel.setPropertyValue(getQProperty(
-                    IntakeJAXBSchema.ENTRY_NUMBER), intakeObject.getEntryNumber());
-        }
-
-        if(intakeObject.getEntryReason() != null){
-            docModel.setPropertyValue(getQProperty(
-                    IntakeJAXBSchema.ENTRY_REASON), intakeObject.getEntryReason());
-        }
-
-        if(intakeObject.getPackingNote() != null){
-            docModel.setPropertyValue(getQProperty(
-                    IntakeJAXBSchema.PACKING_NOTE), intakeObject.getPackingNote());
-        }
-
-        if(intakeObject.getReturnDate() != null){
-            docModel.setPropertyValue(getQProperty(
-                    IntakeJAXBSchema.RETURN_DATE), intakeObject.getReturnDate());
-        }
-
+    public void fillCommonPart(IntakesCommon intakeObject, DocumentWrapper wrapDoc) throws Exception {
+        throw new UnsupportedOperationException();
     }
 
     @Override
-    public IntakeList extractCommonObjectList(DocumentWrapper wrapDoc) throws Exception {
+    public IntakesCommonList extractCommonPartList(DocumentWrapper wrapDoc) throws Exception {
         DocumentModelList docList = (DocumentModelList) wrapDoc.getWrappedObject();
 
-        IntakeList coList = new IntakeList();
-        List<IntakeList.IntakeListItem> list = coList.getIntakeListItem();
+        IntakesCommonList coList = new IntakesCommonList();
+        List<IntakesCommonList.IntakeListItem> list = coList.getIntakeListItem();
 
         //FIXME: iterating over a long list of documents is not a long term
         //strategy...need to change to more efficient iterating in future
@@ -215,11 +120,10 @@ public class IntakeDocumentModelHandler
         while(iter.hasNext()){
             DocumentModel docModel = iter.next();
             IntakeListItem ilistItem = new IntakeListItem();
-            ilistItem.setEntryNumber((String)docModel.getPropertyValue(
-                    getQProperty(IntakeJAXBSchema.ENTRY_NUMBER)));
-            //need fully qualified context for URI
+            ilistItem.setEntryNumber((String) docModel.getProperty(getServiceContext().getCommonPartLabel(),
+                    IntakeJAXBSchema.ENTRY_NUMBER));
             String id = docModel.getId();
-            ilistItem.setUri("/intakes/" + id);
+            ilistItem.setUri(getServiceContextPath() + id);
             ilistItem.setCsid(id);
             list.add(ilistItem);
         }
@@ -227,24 +131,22 @@ public class IntakeDocumentModelHandler
         return coList;
     }
 
-    @Override
-    public void fillCommonObjectList(IntakeList obj, DocumentWrapper wrapDoc) throws Exception {
-        throw new UnsupportedOperationException();
-    }
 
     /* (non-Javadoc)
      * @see org.collectionspace.services.nuxeo.client.java.DocumentModelHandler#getDocumentType()
      */
+    @Override
     public String getDocumentType() {
-       return IntakeConstants.NUXEO_DOCTYPE;
+        return IntakeConstants.NUXEO_DOCTYPE;
     }
-    
+
     /**
      * getQProperty converts the given property to qualified schema property
      * @param prop
      * @return
      */
-    private String getQProperty(String prop) {
+    @Override
+    public String getQProperty(String prop) {
         return IntakeConstants.NUXEO_SCHEMA_NAME + ":" + prop;
     }
 }
index d5f07828e42d7bcc45ab32dc93247a1000f5af50..aaa4374e142c225eb4d4d787f4e7d2b96169a74a 100644 (file)
@@ -23,7 +23,7 @@
  */
 package org.collectionspace.services.intake.nuxeo;
 
-import org.collectionspace.services.common.NuxeoClientType;
+import org.collectionspace.services.common.ClientType;
 import org.collectionspace.services.common.repository.DocumentHandler;
 
 /**
@@ -45,9 +45,9 @@ public class IntakeHandlerFactory {
     }
 
     public DocumentHandler getHandler(String clientType) {
-        if(NuxeoClientType.JAVA.toString().equals(clientType)){
+        if(ClientType.JAVA.toString().equals(clientType)){
             return new IntakeDocumentModelHandler();
-        } else if(NuxeoClientType.REST.toString().equals(clientType)) {
+        } else if(ClientType.REST.toString().equals(clientType)) {
             return new IntakeRepresenationHandler();
         }
         throw new IllegalArgumentException("Not supported client=" + clientType);
index 1723126f6b52b588cbe14126cb1e90d893d90be3..628114c5205737b380627d3a78ae2838dd93324a 100644 (file)
@@ -29,9 +29,9 @@ import java.util.Map;
 
 import org.collectionspace.services.IntakeJAXBSchema;
 import org.collectionspace.services.common.repository.DocumentWrapper;
-import org.collectionspace.services.intake.Intake;
-import org.collectionspace.services.intake.IntakeList;
-import org.collectionspace.services.intake.IntakeList.IntakeListItem;
+import org.collectionspace.services.intake.IntakesCommon;
+import org.collectionspace.services.intake.IntakesCommonList;
+import org.collectionspace.services.intake.IntakesCommonList.IntakeListItem;
 import org.collectionspace.services.nuxeo.client.rest.RepresentationHandler;
 import org.dom4j.Document;
 import org.dom4j.Element;
@@ -45,19 +45,19 @@ import org.slf4j.LoggerFactory;
  * $LastChangedDate: $
  */
 public class IntakeRepresenationHandler
-        extends RepresentationHandler<Intake, IntakeList> {
+        extends RepresentationHandler<IntakesCommon, IntakesCommonList> {
 
     private final Logger logger = LoggerFactory.getLogger(IntakeRepresenationHandler.class);
     /**
      * intakeObj is used to stash JAXB object to use when handle is called
      * for Action.CREATE, Action.UPDATE or Action.GET
      */
-    private Intake intake;
+    private IntakesCommon intake;
     /**
      * intakeListObject is stashed when handle is called
      * for ACTION.GET_ALL
      */
-    private IntakeList intakeList;
+    private IntakesCommonList intakeList;
 
     @Override
     public void prepare(Action action) throws Exception {
@@ -70,7 +70,7 @@ public class IntakeRepresenationHandler
 
     private void prepare() {
         Map<String, String> queryParams = getQueryParams();
-        Intake intakeObject = getCommonObject();
+        IntakesCommon intakeObject = getCommonPart();
         if(intakeObject.getCurrentOwner() != null){
             queryParams.put(IntakeConstants.NUXEO_SCHEMA_NAME + ":" +
                     IntakeJAXBSchema.CURRENT_OWNER, intakeObject.getCurrentOwner());
@@ -123,10 +123,10 @@ public class IntakeRepresenationHandler
     }
 
     @Override
-    public Intake extractCommonObject(DocumentWrapper wrapDoc)
+    public IntakesCommon extractCommonPart(DocumentWrapper wrapDoc)
             throws Exception {
         Document document = (Document) wrapDoc.getWrappedObject();
-        Intake intakeObj = new Intake();
+        IntakesCommon intakeObj = new IntakesCommon();
 
         //FIXME property get should be dynamically set using schema inspection
         //so it does not require hard coding
@@ -191,19 +191,19 @@ public class IntakeRepresenationHandler
     }
 
     @Override
-    public void fillCommonObject(Intake co, DocumentWrapper wrapDoc)
+    public void fillCommonPart(IntakesCommon co, DocumentWrapper wrapDoc)
             throws Exception {
         //Nuxeo REST takes create/update through queryParams, nothing to do here
     }
 
     @Override
-    public IntakeList extractCommonObjectList(DocumentWrapper wrapDoc) throws Exception {
+    public IntakesCommonList extractCommonPartList(DocumentWrapper wrapDoc) throws Exception {
         Document document = (Document) wrapDoc.getWrappedObject();
         if(logger.isDebugEnabled()){
             logger.debug(document.asXML());
         }
-        IntakeList intakeListObject = new IntakeList();
-        List<IntakeList.IntakeListItem> list = intakeListObject.getIntakeListItem();
+        IntakesCommonList intakeListObject = new IntakesCommonList();
+        List<IntakesCommonList.IntakeListItem> list = intakeListObject.getIntakeListItem();
         Element root = document.getRootElement();
         for(Iterator i = root.elementIterator(); i.hasNext();){
 
@@ -222,45 +222,42 @@ public class IntakeRepresenationHandler
         return intakeListObject;
     }
 
-    @Override
-    public void fillCommonObjectList(IntakeList obj, DocumentWrapper wrapDoc)
-            throws Exception {
-        throw new UnsupportedOperationException();
-    }
 
     @Override
-    public Intake getCommonObject() {
+    public IntakesCommon getCommonPart() {
         return intake;
     }
 
     @Override
-    public void setCommonObject(Intake obj) {
+    public void setCommonPart(IntakesCommon obj) {
         this.intake = obj;
     }
 
     @Override
-    public IntakeList getCommonObjectList() {
+    public IntakesCommonList getCommonPartList() {
         return intakeList;
     }
 
     @Override
-    public void setCommonObjectList(IntakeList obj) {
+    public void setCommonPartList(IntakesCommonList obj) {
         this.intakeList = obj;
     }
 
     /* (non-Javadoc)
      * @see org.collectionspace.services.nuxeo.client.java.DocumentModelHandler#getDocumentType()
      */
+    @Override
     public String getDocumentType() {
-       return IntakeConstants.NUXEO_DOCTYPE;
+        return IntakeConstants.NUXEO_DOCTYPE;
     }
-    
+
     /**
      * getQProperty converts the given property to qualified schema property
      * @param prop
      * @return
      */
-    private String getQProperty(String prop) {
+    @Override
+    public String getQProperty(String prop) {
         return IntakeConstants.NUXEO_SCHEMA_NAME + ":" + prop;
     }
 }
index 14f912774797fcbdab43a8fd598fc8b7d36185dc..ec406fe07e78cc2c01ad920ded871c0c034c17d3 100644 (file)
@@ -18,8 +18,8 @@
         <!-- add modules below in the order based on dependencies -->\r
         <module>common</module>\r
         <module>authentication</module>\r
-        <module>relation</module>\r
-        <module>query</module>\r
+        <!--module>relation</module-->\r
+        <!--module>query</module-->\r
         <module>acquisition</module>\r
         <module>vocabulary</module>\r
         <module>id</module>\r
@@ -27,8 +27,8 @@
         <module>intake</module>\r
         <module>JaxRsServiceProvider</module>\r
         <module>client</module>\r
-        <module>sdk</module>\r
-        <module>IntegrationTests</module>\r
+        <!--module>sdk</module-->\r
+        <!--module>IntegrationTests</module-->\r
     </modules>\r
 \r
     <repositories> </repositories>\r
             <dependency>\r
                 <groupId>org.jboss.resteasy</groupId>\r
                 <artifactId>jaxrs-api</artifactId>\r
-                <version>1.0.2.GA</version>\r
+                <version>1.1.GA</version>\r
             </dependency>\r
             <dependency>\r
                 <groupId>net.java.dev.jaxb2-commons</groupId>\r
             <dependency>\r
                 <groupId>org.jboss.resteasy</groupId>\r
                 <artifactId>resteasy-jaxrs</artifactId>\r
-                <version>1.0.2.GA</version>\r
+                <version>1.1.GA</version>\r
             </dependency>\r
             <dependency>\r
                 <groupId>commons-httpclient</groupId>\r
             <dependency>\r
                 <groupId>com.sun.xml.bind</groupId>\r
                 <artifactId>jaxb-impl</artifactId>\r
-                <version>2.1.7</version>\r
+                <version>2.1.9</version>\r
             </dependency>\r
             <dependency>\r
                 <groupId>org.slf4j</groupId>\r
index 2ec1700ec9aa38816eac450c49ba9685bceff7dd..4dfc50536132fb682c4edba817837d7d2aa6211f 100644 (file)
@@ -16,7 +16,7 @@
  * http://www.collectionspace.org
  * http://wiki.collectionspace.org
  *
- * Copyright © 2009 {Contributing Institution}
+ * Copyright  2009 {Contributing Institution}
  *
  * Licensed under the Educational Community License (ECL), Version 2.0.
  * You may not use this file except in compliance with this License.
@@ -44,45 +44,45 @@ import javax.ws.rs.core.UriInfo;
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.Marshaller;
 
-import org.collectionspace.services.relation.RelationList.RelationListItem;
 
-import org.collectionspace.services.common.CollectionSpaceResource;
-import org.collectionspace.services.relation.nuxeo.RelationNuxeoConstants;
-import org.collectionspace.services.relation.nuxeo.RelationHandlerFactory;
-import org.collectionspace.services.common.CollectionSpaceHandlerFactory;
+import org.collectionspace.services.common.AbstractCollectionSpaceResource;
 import org.collectionspace.services.common.NuxeoClientType;
-import org.collectionspace.services.common.ServiceMain;
+import org.collectionspace.services.common.context.ServiceContext;
 import org.collectionspace.services.common.relation.RelationsManager;
 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("/relations")
-@Consumes("application/xml")
-@Produces("application/xml")
-public class NewRelationResource extends CollectionSpaceResource {
+@Consumes("multipart/mixed")
+@Produces("multipart/mixed")
+public class NewRelationResource extends AbstractCollectionSpaceResource {
 
-       public final static String SERVICE_NAME = "relations";
+       public final static String serviceName = "relations";
        final Logger logger = LoggerFactory.getLogger(NewRelationResource.class);
-       // FIXME retrieve client type from configuration
-//     final static NuxeoClientType CLIENT_TYPE = ServiceMain.getInstance()
-//                     .getNuxeoClientType();
        
-       protected String getClientType() {
-               return ServiceMain.getInstance().getNuxeoClientType().toString();
-       }
-       
-       protected RepositoryClientFactory getDefaultClientFactory() {
-               return RepositoryClientFactory.getInstance();
-       }
-       
-       protected CollectionSpaceHandlerFactory getDefaultHandlerFactory() {
-               return RelationHandlerFactory.getInstance();
-       }
+
+    @Override
+    public String getServiceName() {
+        return serviceName;
+    }
+
+    @Override
+    public DocumentHandler createDocumentHandler(ServiceContext ctx) throws Exception {
+        DocumentHandler docHandler = RelationHandlerFactory.getInstance().getHandler(
+                ctx.getRepositoryClientType().toString());
+        docHandler.setServiceContext(ctx);
+        if(ctx.getInput() != null){
+            Object obj = ctx.getInputPart(ctx.getCommonPartLabel(), CollectionobjectsCommon.class);
+            if(obj != null){
+                docHandler.setCommonPart((CollectionobjectsCommon) obj);
+            }
+        }
+        return docHandler;
+    }
+
        
 //     public NewRelationResource() {
 //     }
index 2b7551eb9effafad39800f490e042d2bd5588a18..4e16054049f5d286af56f80da76d4da1c44e7720 100644 (file)
@@ -11,8 +11,8 @@ import org.testng.Assert;
 import org.jboss.resteasy.client.ClientResponse;\r
 \r
 import org.collectionspace.services.client.CollectionObjectClient;\r
-import org.collectionspace.services.collectionobject.CollectionObject;\r
-import org.collectionspace.services.collectionobject.CollectionObjectList;\r
+import org.collectionspace.services.collectionobject.CollectionobjectsCommon;\r
+import org.collectionspace.services.collectionobject.CollectionobjectsCommonList;\r
 \r
 public class Sample {\r
 \r
@@ -25,15 +25,15 @@ public class Sample {
                String csid = createCollectionObject();\r
                System.out.println("Created a new collection object with CSID=" + csid);\r
                \r
-               CollectionObject co = readCollectionObject(csid);\r
+               CollectionobjectsCommon co = readCollectionObject(csid);\r
                System.out.println("Got a collection object with CSID=" + csid);\r
        }\r
        \r
        static String createCollectionObject() {\r
                String result = null;\r
 \r
-               CollectionObject co = new CollectionObject();\r
-               co.setObjectName("Keiko CollectionObject");\r
+               CollectionobjectsCommon co = new CollectionobjectsCommon();\r
+               co.setObjectName("Keiko CollectionobjectsCommon");\r
                \r
            ClientResponse<Response> response = collectionObjectClient.create(co);\r
            Assert.assertEquals(response.getStatus(), Response.Status.CREATED.getStatusCode());\r
@@ -42,10 +42,10 @@ public class Sample {
            return result;\r
        }\r
        \r
-       static CollectionObject readCollectionObject(String csid) {\r
-               CollectionObject result = null;\r
+       static CollectionobjectsCommon readCollectionObject(String csid) {\r
+               CollectionobjectsCommon result = null;\r
                \r
-               ClientResponse<CollectionObject> response = collectionObjectClient.read(csid);\r
+               ClientResponse<CollectionobjectsCommon> response = collectionObjectClient.read(csid);\r
                Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode());\r
                result = response.getEntity();\r
                \r