]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-5025: Adding 'prepare' 'handle' 'complete' phases to RepositoryClient delete...
authorRichard Millet <remillet@berkeley.edu>
Fri, 20 Apr 2012 19:27:18 +0000 (12:27 -0700)
committerRichard Millet <remillet@berkeley.edu>
Fri, 20 Apr 2012 19:27:18 +0000 (12:27 -0700)
Signed-off-by: Richard Millet <remillet@berkeley.edu>
31 files changed:
services/IntegrationTests/pom.xml
services/IntegrationTests/src/test/java/org/collectionspace/services/IntegrationTests/test/RelationIntegrationTest.java
services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityResource.java
services/client/src/main/java/org/collectionspace/services/client/test/AbstractServiceTestImpl.java
services/client/src/main/java/org/collectionspace/services/client/workflow/WorkflowClient.java
services/common/src/main/java/org/collectionspace/services/common/AbstractMultiPartCollectionSpaceResourceImpl.java
services/common/src/main/java/org/collectionspace/services/common/ResourceBase.java
services/common/src/main/java/org/collectionspace/services/common/document/AbstractDocumentHandlerImpl.java
services/common/src/main/java/org/collectionspace/services/common/document/DocumentHandler.java
services/common/src/main/java/org/collectionspace/services/common/storage/StorageClient.java
services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaDocumentHandler.java
services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java
services/common/src/main/java/org/collectionspace/services/common/workflow/service/nuxeo/WorkflowDocumentModelHandler.java
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RemoteDocumentModelHandlerImpl.java
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryJavaClientImpl.java
services/concept/service/src/main/java/org/collectionspace/services/concept/nuxeo/ConceptValidatorHandler.java
services/contact/service/src/main/java/org/collectionspace/services/contact/AuthorityResourceWithContacts.java
services/dimension/3rdparty/nuxeo-platform-cs-dimension/pom.xml
services/dimension/client/pom.xml
services/dimension/client/src/test/java/org/collectionspace/services/client/test/DimensionXmlReplayTest.java
services/dimension/service/src/main/java/org/collectionspace/services/dimension/nuxeo/DimensionDocumentModelHandler.java
services/location/service/src/main/java/org/collectionspace/services/location/nuxeo/LocationValidatorHandler.java
services/organization/service/src/main/java/org/collectionspace/services/organization/nuxeo/OrgAuthorityValidatorHandler.java
services/organization/service/src/main/java/org/collectionspace/services/organization/nuxeo/OrganizationValidatorHandler.java
services/person/service/src/main/java/org/collectionspace/services/person/nuxeo/PersonAuthorityValidatorHandler.java
services/person/service/src/main/java/org/collectionspace/services/person/nuxeo/PersonValidatorHandler.java
services/place/service/src/main/java/org/collectionspace/services/place/nuxeo/PlaceValidatorHandler.java
services/relation/service/src/main/java/org/collectionspace/services/relation/nuxeo/RelationDocumentModelHandler.java
services/taxonomy/service/src/main/java/org/collectionspace/services/taxonomy/nuxeo/TaxonValidatorHandler.java
services/vocabulary/service/src/main/java/org/collectionspace/services/vocabulary/nuxeo/VocabularyItemValidatorHandler.java
services/vocabulary/service/src/main/java/org/collectionspace/services/vocabulary/nuxeo/VocabularyValidatorHandler.java

index de513d3fc9b704a34911e0ad44a6978031643821..c9720b6c19ec4fe442e4164a3ebcdd2ac033f755 100644 (file)
             <artifactId>org.collectionspace.services.intake.client</artifactId>\r
             <version>${project.version}</version>\r
         </dependency>\r
+        <dependency>\r
+            <groupId>org.collectionspace.services</groupId>\r
+            <artifactId>org.collectionspace.services.dimension.jaxb</artifactId>\r
+            <version>${project.version}</version>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.collectionspace.services</groupId>\r
+            <artifactId>org.collectionspace.services.dimension.client</artifactId>\r
+            <version>${project.version}</version>\r
+        </dependency>\r
         <dependency>\r
             <groupId>org.collectionspace.services</groupId>\r
             <artifactId>org.collectionspace.services.relation.client</artifactId>\r
index fbc73e5d9642a7b420914db39bcb251c100833b2..1e7a46faaa9157ec334c708a667704dabd543e16 100644 (file)
  */
 package org.collectionspace.services.IntegrationTests.test;
 
+import java.io.StringWriter;
+import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.List;
 
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
 
 import org.testng.Assert;
 import org.testng.annotations.Test;
@@ -37,6 +41,8 @@ import org.slf4j.LoggerFactory;
 import org.jboss.resteasy.client.ClientResponse;
 
 import org.collectionspace.services.client.CollectionObjectClient;
+import org.collectionspace.services.client.DimensionClient;
+import org.collectionspace.services.client.DimensionFactory;
 import org.collectionspace.services.client.PayloadOutputPart;
 import org.collectionspace.services.client.PoxPayloadIn;
 import org.collectionspace.services.client.PoxPayloadOut;
@@ -46,6 +52,8 @@ import org.collectionspace.services.client.IntakeClient;
 import org.collectionspace.services.intake.IntakesCommon;
 
 import org.collectionspace.services.client.RelationClient;
+import org.collectionspace.services.client.workflow.WorkflowClient;
+import org.collectionspace.services.dimension.DimensionsCommon;
 import org.collectionspace.services.relation.RelationsCommon;
 import org.collectionspace.services.relation.RelationsCommonList;
 import org.collectionspace.services.relation.RelationshipType;
@@ -65,9 +73,209 @@ public class RelationIntegrationTest extends CollectionSpaceIntegrationTest {
        private CollectionObjectClient collectionObjectClient = new CollectionObjectClient();
        private RelationClient relationClient = new RelationClient();
        private IntakeClient intakeClient = new IntakeClient();
+       private DimensionClient dimensionClient = new DimensionClient();
        
        private static final int OBJECTS_TO_INTAKE = 1;
        
+       
+    /**
+     * Object as xml string.
+     *
+     * @param o the o
+     * @param clazz the clazz
+     * @return the string
+     */
+    static protected String objectAsXmlString(Object o, Class<?> clazz) {
+        StringWriter sw = new StringWriter();
+        try {
+            JAXBContext jc = JAXBContext.newInstance(clazz);
+            Marshaller m = jc.createMarshaller();
+            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
+                    Boolean.TRUE);
+            m.marshal(o, sw);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return sw.toString();
+    }
+       
+    private PoxPayloadOut createDimensionInstance(String commonPartName, String dimensionType, String dimensionValue, String entryDate) {
+        DimensionsCommon dimensionsCommon = new DimensionsCommon();
+        dimensionsCommon.setDimension(dimensionType);
+        dimensionsCommon.setValue(new BigDecimal(dimensionValue));
+        dimensionsCommon.setValueDate(entryDate);
+        PoxPayloadOut multipart = DimensionFactory.createDimensionInstance(
+                commonPartName, dimensionsCommon);
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("to be created, dimension common");
+            logger.debug(objectAsXmlString(dimensionsCommon,
+                    DimensionsCommon.class));
+        }
+
+        return multipart;
+    }
+       
+    protected PoxPayloadOut createDimensionInstance(String identifier) {
+       DimensionClient client = new DimensionClient();
+       return createDimensionInstance(client.getCommonPartName(), identifier);
+    }
+    
+    /**
+     * Creates the dimension instance.
+     *
+     * @param identifier the identifier
+     * @return the multipart output
+     */
+    protected PoxPayloadOut createDimensionInstance(String commonPartName, String identifier) {
+        final String DIMENSION_VALUE = "78.306";
+       
+        return createDimensionInstance(commonPartName, 
+                "dimensionType-" + identifier,
+                DIMENSION_VALUE,
+                "entryDate-" + identifier);
+    }
+    
+       @Test void deleteCollectionObjectRelationshipToLockedDimension() {
+               //
+               // First create a CollectionObject
+               //
+               CollectionobjectsCommon co = new CollectionobjectsCommon();
+               fillCollectionObject(co, createIdentifier());
+               
+               // Next, create a part object
+               PoxPayloadOut multipart = new PoxPayloadOut(CollectionObjectClient.SERVICE_PAYLOAD_NAME);
+               PayloadOutputPart commonPart = multipart.addPart(co, MediaType.APPLICATION_XML_TYPE);
+               commonPart.setLabel(collectionObjectClient.getCommonPartName());
+               
+               // Make the create call and check the response
+               ClientResponse<Response> response = collectionObjectClient.create(multipart);
+               String collectionObjectCsid = null;
+               try {
+                       Assert.assertEquals(response.getStatus(), Response.Status.CREATED
+                                       .getStatusCode());
+                       collectionObjectCsid = extractId(response);
+               } finally {
+                       response.releaseConnection();
+               }
+               
+               //Next, create a Dimension record to relate the collection object to
+           multipart = this.createDimensionInstance(createIdentifier());
+           // Make the call to create and check the response
+           response = dimensionClient.create(multipart);
+           String dimensionCsid = null;
+           try {
+                   Assert.assertEquals(response.getStatus(), Response.Status.CREATED.getStatusCode());
+                   dimensionCsid = extractId(response);
+           } finally {
+               response.releaseConnection();
+           }
+           
+           // Relate the two entities, by creating a new relation object
+           RelationsCommon relation = new RelationsCommon();
+           fillRelation(relation, collectionObjectCsid, CollectionobjectsCommon.class.getSimpleName(),
+                       dimensionCsid, DimensionsCommon.class.getSimpleName(),
+                       "collectionobject-dimension");
+           // Create the part and fill it with the relation object
+           multipart = new PoxPayloadOut(RelationClient.SERVICE_PAYLOAD_NAME);
+           commonPart = multipart.addPart(relation, MediaType.APPLICATION_XML_TYPE);
+           commonPart.setLabel(relationClient.getCommonPartName());
+
+           // Create the relationship
+           response = relationClient.create(multipart);
+           @SuppressWarnings("unused")
+               String relationCsid = null;
+           try {
+                   Assert.assertEquals(response.getStatus(), Response.Status.CREATED.getStatusCode());
+                   relationCsid = extractId(response);
+           } finally {
+               response.releaseConnection();
+           }
+           
+           // Now lock the dimension record.
+           
+               @SuppressWarnings("unused")
+               ClientResponse<String> workflowResponse = dimensionClient.updateWorkflowWithTransition(dimensionCsid, WorkflowClient.WORKFLOWTRANSITION_LOCK);
+           System.out.println("Locked dimension record with CSID=" + dimensionCsid);
+           
+           // Finally, try to delete the relationship
+           
+           // Try to delete the relationship -should fail because we don't allow delete if one of the sides is locked.
+           response = relationClient.delete(relationCsid);
+           try {
+                   Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode());
+           } finally {
+               response.releaseConnection();
+           }
+           
+           // Also, try to soft-delete.  This should also fail.
+               workflowResponse = dimensionClient.updateWorkflowWithTransition(dimensionCsid, WorkflowClient.WORKFLOWTRANSITION_DELETE);
+           System.out.println("Locked dimension record with CSID=" + dimensionCsid);
+       }
+    
+       
+       @Test void releteCollectionObjectToLockedDimension() {
+               //
+               // First create a CollectionObject
+               //
+               CollectionobjectsCommon co = new CollectionobjectsCommon();
+               fillCollectionObject(co, createIdentifier());
+               
+               // Next, create a part object
+               PoxPayloadOut multipart = new PoxPayloadOut(CollectionObjectClient.SERVICE_PAYLOAD_NAME);
+               PayloadOutputPart commonPart = multipart.addPart(co, MediaType.APPLICATION_XML_TYPE);
+               commonPart.setLabel(collectionObjectClient.getCommonPartName());
+               
+               // Make the create call and check the response
+               ClientResponse<Response> response = collectionObjectClient.create(multipart);
+               String collectionObjectCsid = null;
+               try {
+                       Assert.assertEquals(response.getStatus(), Response.Status.CREATED
+                                       .getStatusCode());
+                       collectionObjectCsid = extractId(response);
+               } finally {
+                       response.releaseConnection();
+               }
+               
+               //Next, create a Dimension record to relate the collection object to
+           multipart = this.createDimensionInstance(createIdentifier());
+           // Make the call to create and check the response
+           response = dimensionClient.create(multipart);
+           String dimensionCsid = null;
+           try {
+                   Assert.assertEquals(response.getStatus(), Response.Status.CREATED.getStatusCode());
+                   dimensionCsid = extractId(response);
+           } finally {
+               response.releaseConnection();
+           }
+           
+           @SuppressWarnings("unused")
+               ClientResponse<String> workflowResponse = dimensionClient.updateWorkflowWithTransition(dimensionCsid, WorkflowClient.WORKFLOWTRANSITION_LOCK);
+           System.out.println("Locked dimension record with CSID=" + dimensionCsid);
+           
+           // Lastly, relate the two entities, by creating a new relation object
+           RelationsCommon relation = new RelationsCommon();
+           fillRelation(relation, collectionObjectCsid, CollectionobjectsCommon.class.getSimpleName(),
+                       dimensionCsid, DimensionsCommon.class.getSimpleName(),
+                       "collectionobject-dimension");
+           // Create the part and fill it with the relation object
+           multipart = new PoxPayloadOut(RelationClient.SERVICE_PAYLOAD_NAME);
+           commonPart = multipart.addPart(relation, MediaType.APPLICATION_XML_TYPE);
+           commonPart.setLabel(relationClient.getCommonPartName());
+
+           // Make the call to crate
+           ClientResponse<Response> relationresponse = relationClient.create(multipart);
+           @SuppressWarnings("unused")
+               String relationCsid = null;
+           try {
+                   Assert.assertEquals(relationresponse.getStatus(), Response.Status.BAD_REQUEST.getStatusCode());
+                   relationCsid = extractId(response);
+           } finally {
+               relationresponse.releaseConnection();
+           }
+           
+       }
+       
        @Test
        public void relateCollectionObjectToIntake() {
                //
index bf47c2dae4fd1ea035cd591d4471210e92484a0e..b1c400f1ec72523fff55e9e7c0be7a0c0010845b 100644 (file)
@@ -32,14 +32,12 @@ import org.collectionspace.services.common.ResourceBase;
 import org.collectionspace.services.common.ResourceMap;
 import org.collectionspace.services.common.ServiceMain;
 import org.collectionspace.services.common.ServiceMessages;
-import org.collectionspace.services.common.XmlTools;
 import org.collectionspace.services.common.api.RefName;
 import org.collectionspace.services.common.api.Tools;
 import org.collectionspace.services.common.authorityref.AuthorityRefDocList;
 import org.collectionspace.services.common.authorityref.AuthorityRefList;
 import org.collectionspace.services.common.context.JaxRsContext;
 import org.collectionspace.services.common.context.MultipartServiceContext;
-import org.collectionspace.services.common.context.MultipartServiceContextImpl;
 import org.collectionspace.services.common.context.RemoteServiceContext;
 import org.collectionspace.services.common.context.ServiceBindingUtils;
 import org.collectionspace.services.common.context.ServiceContext;
@@ -49,7 +47,6 @@ import org.collectionspace.services.common.document.DocumentHandler;
 import org.collectionspace.services.common.document.DocumentNotFoundException;
 import org.collectionspace.services.common.document.DocumentWrapper;
 import org.collectionspace.services.common.query.QueryManager;
-import org.collectionspace.services.common.repository.RepositoryClient;
 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils;
 import org.collectionspace.services.common.vocabulary.nuxeo.AuthorityDocumentModelHandler;
 import org.collectionspace.services.common.vocabulary.nuxeo.AuthorityItemDocumentModelHandler;
@@ -58,11 +55,7 @@ import org.collectionspace.services.config.ClientType;
 import org.collectionspace.services.jaxb.AbstractCommonList;
 import org.collectionspace.services.lifecycle.TransitionDef;
 import org.collectionspace.services.nuxeo.client.java.DocumentModelHandler;
-import org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl;
 import org.collectionspace.services.nuxeo.client.java.RepositoryJavaClientImpl;
-import org.collectionspace.services.relation.RelationResource;
-import org.collectionspace.services.relation.RelationsCommonList;
-import org.collectionspace.services.relation.RelationshipType;
 import org.collectionspace.services.workflow.WorkflowCommon;
 import org.jboss.resteasy.util.HttpResponseCodes;
 import org.nuxeo.ecm.core.api.DocumentModel;
@@ -494,7 +487,8 @@ public abstract class AuthorityResource<AuthCommon, AuthItemHandler>
         try {
             ensureCSID(csid, ServiceMessages.DELETE_FAILED, "Authority.csid");
             ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext();
-            getRepositoryClient(ctx).delete(ctx, csid);
+            DocumentHandler handler = createDocumentHandler(ctx);
+            getRepositoryClient(ctx).delete(ctx, csid, handler);
             return Response.status(HttpResponseCodes.SC_OK).build();
         } catch (Exception e) {
             throw bigReThrow(e, ServiceMessages.DELETE_FAILED, csid);
@@ -551,6 +545,8 @@ public abstract class AuthorityResource<AuthCommon, AuthItemHandler>
         return result.getBytes();
     }
 
+    //FIXME: This method is almost identical to the method org.collectionspace.services.common.updateWorkflowWithTransition() so
+    // they should be consolidated -be DRY (don't repeat yourself).
     @PUT
     @Path("{csid}/items/{itemcsid}" + WorkflowClient.SERVICE_PATH + "/{transition}")
     public byte[] updateItemWorkflowWithTransition(
@@ -558,23 +554,34 @@ public abstract class AuthorityResource<AuthCommon, AuthItemHandler>
             @PathParam("itemcsid") String itemcsid,
             @PathParam("transition") String transition) {
         PoxPayloadOut result = null;
+        
         try {
+               //
+               // Create an empty workflow_commons input part and set it into a new "workflow" sub-resource context
                PoxPayloadIn input = new PoxPayloadIn(WorkflowClient.SERVICE_PAYLOAD_NAME, new WorkflowCommon(), 
                                WorkflowClient.SERVICE_COMMONPART_NAME);
+            MultipartServiceContext ctx = (MultipartServiceContext) createServiceContext(WorkflowClient.SERVICE_NAME, input);
 
+            // Create a service context and document handler for the parent resource.
             ServiceContext<PoxPayloadIn, PoxPayloadOut> parentCtx = createServiceContext(getItemServiceName());
-            String parentWorkspaceName = parentCtx.getRepositoryWorkspaceName();
+            DocumentHandler parentDocHandler = this.createDocumentHandler(parentCtx);
+            ctx.setProperty(WorkflowClient.PARENT_DOCHANDLER, parentDocHandler); //added as a context param for the workflow document handler -it will call the parent's dochandler "prepareForWorkflowTranstion" method
 
+            // When looking for the document, we need to use the parent's workspace name -not the "workflow" workspace name
+            String parentWorkspaceName = parentCtx.getRepositoryWorkspaceName();
+            ctx.setRespositoryWorkspaceName(parentWorkspaceName); //find the document in the parent's workspace
+            
+               // Get the type of transition we're being asked to make and store it as a context parameter -used by the workflow document handler
             TransitionDef transitionDef = getTransitionDef(parentCtx, transition);
-            MultipartServiceContext ctx = (MultipartServiceContext) createServiceContext(WorkflowClient.SERVICE_NAME, input);
             ctx.setProperty(WorkflowClient.TRANSITION_ID, transitionDef);
+            
             WorkflowDocumentModelHandler handler = createWorkflowDocumentHandler(ctx);
-            ctx.setRespositoryWorkspaceName(parentWorkspaceName); //find the document in the parent's workspace
             getRepositoryClient(ctx).update(ctx, itemcsid, handler);
             result = ctx.getOutput();
         } catch (Exception e) {
             throw bigReThrow(e, ServiceMessages.UPDATE_FAILED + WorkflowClient.SERVICE_PAYLOAD_NAME, csid);
         }
+        
         return result.getBytes();
     }
 
@@ -879,7 +886,8 @@ public abstract class AuthorityResource<AuthCommon, AuthItemHandler>
             // try {
             // Note that we have to create the service context for the Items, not the main service
             ServiceContext ctx = createServiceContext(getItemServiceName());
-            getRepositoryClient(ctx).delete(ctx, itemcsid);
+            DocumentHandler handler = createDocumentHandler(ctx);
+            getRepositoryClient(ctx).delete(ctx, itemcsid, handler);
             return Response.status(HttpResponseCodes.SC_OK).build();
         } catch (Exception e) {
             throw bigReThrow(e, ServiceMessages.DELETE_FAILED + "  itemcsid: " + itemcsid + " parentcsid:" + parentcsid);
index 7e3c1fb5961865e9f62fe560da6359adfd1d7bb0..c3d5b510df9c8df2fab71efd4477dbbe06e18a85 100644 (file)
@@ -1065,7 +1065,8 @@ public abstract class AbstractServiceTestImpl<CLT, CPT, REQUEST_TYPE, RESPONSE_T
         }
     }
 
-    protected void updateItemLifeCycleState(String testName, String parentCsid, String itemCsid, String workflowTransition, String lifeCycleState) throws Exception {
+    @SuppressWarnings("unchecked")
+       protected void updateItemLifeCycleState(String testName, String parentCsid, String itemCsid, String workflowTransition, String lifeCycleState) throws Exception {
         //
         // Read the existing object
         //
index 31ee013a9647420ed95909ff81894981bf119f7f..abe65e4b316272ffc918e9dbf44f7a41bef23b94 100644 (file)
@@ -57,6 +57,7 @@ public class WorkflowClient extends AbstractCommonListPoxServiceClientImpl<Workf
        //
        public static final String WORKFLOW_QUERY_NONDELETED = "wf_deleted";
        public static final String WORKFLOWSTATE_QUERY = "wf_deleted";
+       public static final String PARENT_DOCHANDLER = "wf_dochandler";
 
        
        @Override
index 217cf60e8bfa715f7e6e7148f9fafcebdd62b66c..3965252904057ff081425fb331a09baede6264e0 100644 (file)
@@ -171,6 +171,10 @@ public abstract class AbstractMultiPartCollectionSpaceResourceImpl extends Abstr
     /*\r
      * JAX-RS Annotated methods\r
      */\r
+    \r
+    /*\r
+     * We should change this method.  The RepositoryClient (from call to getRepositoryClient) should support a call getWorkflowTransition() instead.\r
+     */    \r
     @GET\r
     @Path("{csid}" + WorkflowClient.SERVICE_PATH)\r
     public byte[] getWorkflow(\r
@@ -232,23 +236,40 @@ public abstract class AbstractMultiPartCollectionSpaceResourceImpl extends Abstr
        return result;\r
     }\r
     \r
+    /*\r
+     * We should change this code.  The RepositoryClient (from call to getRepositoryClient) should support a call doWorkflowTransition() instead.\r
+     */\r
+    //FIXME: This method is almost identical to the method org.collectionspace.services.common.vocabulary.updateWorkflowWithTransition() so\r
+    // they should be consolidated -be DRY (don't repeat yourself).\r
+\r
     @PUT\r
     @Path("{csid}" + WorkflowClient.SERVICE_PATH + "/" + "{transition}")\r
     public byte[] updateWorkflowWithTransition(@PathParam("csid") String csid,\r
                @PathParam("transition") String transition) {\r
         PoxPayloadOut result = null;\r
+        \r
+        \r
         try {\r
+               //\r
+               // Create an empty workflow_commons input part and set it into a new "workflow" sub-resource context\r
                PoxPayloadIn input = new PoxPayloadIn(WorkflowClient.SERVICE_PAYLOAD_NAME, new WorkflowCommon(), \r
                                WorkflowClient.SERVICE_COMMONPART_NAME);\r
+            MultipartServiceContext ctx = (MultipartServiceContext) createServiceContext(WorkflowClient.SERVICE_NAME, input);\r
                \r
+            // Create a service context and document handler for the parent resource.\r
             ServiceContext<PoxPayloadIn, PoxPayloadOut> parentCtx = createServiceContext();\r
+            DocumentHandler parentDocHandler = this.createDocumentHandler(parentCtx);      \r
+            ctx.setProperty(WorkflowClient.PARENT_DOCHANDLER, parentDocHandler); //added as a context param for the workflow document handler -it will call the parent's dochandler "prepareForWorkflowTranstion" method\r
+\r
+            // When looking for the document, we need to use the parent's workspace name -not the "workflow" workspace name\r
             String parentWorkspaceName = parentCtx.getRepositoryWorkspaceName();\r
-               \r
+            ctx.setRespositoryWorkspaceName(parentWorkspaceName); //find the document in the parent's workspace\r
+            \r
+               // Get the type of transition we're being asked to make and store it as a context parameter -used by the workflow document handler\r
             TransitionDef transitionDef = getTransitionDef(parentCtx, transition);\r
-            MultipartServiceContext ctx = (MultipartServiceContext) createServiceContext(WorkflowClient.SERVICE_NAME, input);\r
             ctx.setProperty(WorkflowClient.TRANSITION_ID, transitionDef);\r
+\r
             WorkflowDocumentModelHandler handler = createWorkflowDocumentHandler(ctx);\r
-            ctx.setRespositoryWorkspaceName(parentWorkspaceName); //find the document in the parent's workspace\r
             getRepositoryClient(ctx).update(ctx, csid, handler);\r
             result = ctx.getOutput();\r
         } catch (Exception e) {\r
index 78242c97ab2003c5f1a6b758936701af618d4e61..38f34669a74a15e2902e6648538b259b19c1c5ac 100644 (file)
@@ -173,7 +173,8 @@ public abstract class ResourceBase
      *  which handles setup of ServiceContext, and does Exception handling.  */\r
     protected Response delete(String csid, ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx)\r
             throws Exception {\r
-        getRepositoryClient(ctx).delete(ctx, csid);\r
+       DocumentHandler handler = createDocumentHandler(ctx);\r
+        getRepositoryClient(ctx).delete(ctx, csid, handler);\r
         return Response.status(HttpResponseCodes.SC_OK).build();\r
     }\r
 \r
index 060af748db2cbb7de9f1ca6893aaf3f9b35e2e80..f45e0e051f7553ea2dc4bd3844b9c40af1dad6fe 100644 (file)
@@ -148,6 +148,7 @@ public abstract class AbstractDocumentHandlerImpl<T, TL, WT, WTL>
                 break;
 
             case DELETE:
+                validate(action);
                 prepareDelete();
                 break;
 
index e85acf763af0e778d76fca57d2a28c8218744d66..fde044675a1de59820db65f468ef0023753de419 100644 (file)
@@ -20,6 +20,8 @@ package org.collectionspace.services.common.document;
 import java.util.Map;
 import org.collectionspace.services.common.context.ServiceContext;
 import org.collectionspace.services.lifecycle.Lifecycle;
+import org.collectionspace.services.lifecycle.TransitionDef;
+import org.nuxeo.ecm.core.api.DocumentModel;
 
 /**
  *
@@ -42,7 +44,7 @@ import org.collectionspace.services.lifecycle.Lifecycle;
 public interface DocumentHandler<T, TL, WT, WTL> {
 
     public enum Action {
-        CREATE, GET, GET_ALL, UPDATE, DELETE
+        CREATE, GET, GET_ALL, UPDATE, DELETE, WORKFLOW
     }
     
     public Lifecycle getLifecycle();
@@ -76,6 +78,11 @@ public interface DocumentHandler<T, TL, WT, WTL> {
      */
     public void prepare(Action action) throws Exception;
 
+    /**
+     * updateWorkflowTransition - prepare for a workflow transition
+     */
+    public void handleWorkflowTransition(DocumentWrapper<DocumentModel> wrapDoc, TransitionDef transitionDef) throws Exception;
+    
     /**
      * prepareCreate processes documents before creating document in repository
 
index 05f4d386df436e7a1313e7ea978359d5390ab371..56108ce2884efc4e61662bcda728c01b525cda1c 100644 (file)
@@ -24,6 +24,7 @@ import org.collectionspace.services.common.document.BadRequestException;
 import org.collectionspace.services.common.document.DocumentException;
 import org.collectionspace.services.common.document.DocumentHandler;
 import org.collectionspace.services.common.document.DocumentNotFoundException;
+import org.collectionspace.services.lifecycle.TransitionDef;
 
 /**
  *
@@ -123,6 +124,13 @@ public interface StorageClient {
      * @throws DocumentNotFoundException if entity not found
      * @throws DocumentException
      */
-    void update(ServiceContext ctx, String id, DocumentHandler handler) throws BadRequestException, DocumentNotFoundException, DocumentException;
+    void update(ServiceContext ctx, String id, DocumentHandler handler) 
+               throws BadRequestException, DocumentNotFoundException, DocumentException;
+
+    /*
+     * Updates the workflow state of a document
+     */
+    void doWorkflowTransition(ServiceContext ctx, String id, DocumentHandler handler, TransitionDef transitionDef) 
+               throws BadRequestException, DocumentNotFoundException, DocumentException;
 
 }
index ab9623b737385bbd6adccfcde7fc4a0befeb31da..cc495124d86e2bc3e978d1ddf00952d8d8a5913c 100644 (file)
@@ -7,6 +7,8 @@ import org.collectionspace.services.common.document.DocumentFilter;
 import org.collectionspace.services.common.document.DocumentWrapper;\r
 import org.collectionspace.services.jaxb.AbstractCommonList;\r
 import org.collectionspace.services.lifecycle.Lifecycle;\r
+import org.collectionspace.services.lifecycle.TransitionDef;\r
+import org.nuxeo.ecm.core.api.DocumentModel;\r
 \r
 public abstract class JpaDocumentHandler<T, TL, WT, WLT>\r
        extends AbstractDocumentHandlerImpl<T, TL, WT, WLT>{\r
@@ -47,4 +49,12 @@ public abstract class JpaDocumentHandler<T, TL, WT, WLT>
     public Lifecycle getLifecycle() {\r
        return getLifecycle(null); // NOTE: As of 3/2012, none of the JPA-based services support a life cycle type.\r
     }\r
+    \r
+       @Override\r
+       public void handleWorkflowTransition(\r
+                       DocumentWrapper<DocumentModel> wrapDoc, TransitionDef transitionDef)\r
+                       throws Exception {\r
+               // Do nothing.  JPA document handlers do not support workflow transitions yet.\r
+       }\r
+    \r
 }\r
index ff609dce083c4d3098dac2533e1683873ea54901..457f7ab11015722bf1572d80c7a5954424a4beb4 100644 (file)
@@ -40,6 +40,7 @@ import org.collectionspace.services.common.storage.StorageClient;
 import org.collectionspace.services.common.context.ServiceContextProperties;
 import org.collectionspace.services.common.context.ServiceContext;
 import org.collectionspace.services.common.query.QueryContext;
+import org.collectionspace.services.lifecycle.TransitionDef;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -577,4 +578,12 @@ public class JpaStorageClientImpl implements StorageClient {
             throws DocumentNotFoundException, DocumentException {
         throw new UnsupportedOperationException();
     }
+
+       @Override
+       public void doWorkflowTransition(ServiceContext ctx, String id,
+                       DocumentHandler handler, TransitionDef transitionDef)
+                       throws BadRequestException, DocumentNotFoundException,
+                       DocumentException {
+               // Do nothing.  JPA services do not support workflow.
+       }
 }
index f4d12ae6e5b2391fcd99f60f76974aec9bb172fb..6b1f83a07ee4a27a8c95805fe47e653ac2d44a43 100644 (file)
  */
 package org.collectionspace.services.common.workflow.service.nuxeo;
 
-import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
 
 import javax.ws.rs.core.MediaType;
 
-import org.collectionspace.services.client.PayloadInputPart;
-import org.collectionspace.services.client.PoxPayloadIn;
-import org.collectionspace.services.client.PoxPayloadOut;
 import org.collectionspace.services.client.workflow.WorkflowClient;
 import org.collectionspace.services.common.context.MultipartServiceContext;
 import org.collectionspace.services.common.context.ServiceContext;
 import org.collectionspace.services.common.document.DocumentWrapper;
-import org.collectionspace.services.common.document.DocumentHandler.Action;
 import org.collectionspace.services.common.workflow.jaxb.WorkflowJAXBSchema;
 import org.collectionspace.services.config.service.ObjectPartType;
 import org.collectionspace.services.lifecycle.TransitionDef;
 import org.collectionspace.services.nuxeo.client.java.DocHandlerBase;
+import org.collectionspace.services.nuxeo.client.java.DocumentModelHandler;
 import org.collectionspace.services.workflow.WorkflowCommon;
 import org.nuxeo.ecm.core.api.ClientException;
 import org.nuxeo.ecm.core.api.DocumentModel;
@@ -61,11 +57,25 @@ public class WorkflowDocumentModelHandler
      *
      * org.nuxeo.ecm.core.LifecycleCoreExtensions--lifecycle (as opposed to --types)
      */
-    private static final String TRANSITION_DELETE = "delete";
-    private static final String TRANSITION_APPROVE = "approve";
-    private static final String TRANSITION_UNDELETE = "undelete";
     private static final String TRANSITION_UNKNOWN = "unknown";
 
+    
+    @Override
+    public void handleUpdate(DocumentWrapper<DocumentModel> wrapDoc) throws Exception {
+       //
+       // First, call the parent document handler to give it a chance to handle the workflow transition -otherwise, call
+       // the super/parent handleUpdate() method.
+       //
+       ServiceContext ctx = this.getServiceContext();
+       DocumentModelHandler docHandler = (DocumentModelHandler)ctx.getProperty(WorkflowClient.PARENT_DOCHANDLER);
+       TransitionDef transitionDef =  (TransitionDef)ctx.getProperty(WorkflowClient.TRANSITION_ID);
+       docHandler.handleWorkflowTransition(wrapDoc, transitionDef);
+       //
+       // If no exception occurred, then call the super's method
+       //
+       super.handleUpdate(wrapDoc);
+    }
+    
     /*
      * Handle read (GET)
      */
index 55454ee7229360fb02d83cdce63f162cb740bb65..e00c93c7153dc4abe0a21c440e113cd56c2c0d9e 100644 (file)
@@ -38,6 +38,7 @@ import javax.xml.bind.JAXBElement;
 
 import org.collectionspace.services.authorization.AccountPermission;
 import org.collectionspace.services.jaxb.AbstractCommonList;
+import org.collectionspace.services.lifecycle.TransitionDef;
 import org.collectionspace.services.client.PayloadInputPart;
 import org.collectionspace.services.client.PayloadOutputPart;
 import org.collectionspace.services.client.PoxPayloadIn;
@@ -99,6 +100,12 @@ public abstract class   RemoteDocumentModelHandlerImpl<T, TL>
         }
     }
 
+       @Override
+       public void handleWorkflowTransition(DocumentWrapper<DocumentModel> wrapDoc, TransitionDef transitionDef)
+                       throws Exception {
+               // Do nothing by default, but children can override if they want.  The really workflow transition happens in the WorkflowDocumemtModelHandler class
+       }
+    
     /* (non-Javadoc)
      * @see org.collectionspace.services.nuxeo.client.java.DocumentModelHandler#completeUpdate(org.collectionspace.services.common.document.DocumentWrapper)
      */
index 113ea8fe6ae3e2cd2270ae596afc3274326fcfe9..c80800b91de52369ed2544faf26323bf33844029 100644 (file)
@@ -32,6 +32,7 @@ import org.collectionspace.services.common.context.ServiceContext;
 import org.collectionspace.services.common.query.QueryContext;
 import org.collectionspace.services.common.repository.RepositoryClient;
 import org.collectionspace.services.common.profile.Profiler;
+import org.collectionspace.services.lifecycle.TransitionDef;
 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
 
 import org.collectionspace.services.common.document.BadRequestException;
@@ -889,23 +890,36 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
      * @throws DocumentException
      */
     @Override
-    public void delete(ServiceContext ctx, String id) throws DocumentNotFoundException,
+    public void delete(ServiceContext ctx, String id, DocumentHandler handler) throws DocumentNotFoundException,
             DocumentException {
-
+        if (ctx == null) {
+            throw new IllegalArgumentException(
+                    "delete(ctx, ix, handler): ctx is missing");
+        }
+        if (handler == null) {
+            throw new IllegalArgumentException(
+                    "delete(ctx, ix, handler): handler is missing");
+        }
         if (logger.isDebugEnabled()) {
             logger.debug("Deleting document with CSID=" + id);
         }
         RepositoryInstance repoSession = null;
         try {
+               handler.prepare(Action.DELETE);
             repoSession = getRepositorySession();
-            DocumentRef docRef = NuxeoUtils.createPathRef(ctx, id);
+            DocumentWrapper<DocumentModel> wrapDoc = null;
             try {
+               DocumentRef docRef = NuxeoUtils.createPathRef(ctx, id);
+                   wrapDoc = new DocumentWrapperImpl<DocumentModel>(repoSession.getDocument(docRef));
+                   ((DocumentModelHandler) handler).setRepositorySession(repoSession);
+                   handler.handle(Action.DELETE, wrapDoc);
                 repoSession.removeDocument(docRef);
             } catch (ClientException ce) {
                String msg = logException(ce, "Could not find document to delete with CSID=" + id);
                 throw new DocumentNotFoundException(msg, ce);
             }
             repoSession.save();
+            handler.complete(Action.DELETE, wrapDoc);
         } catch (DocumentException de) {
             throw de;
         } catch (Exception e) {
@@ -924,9 +938,11 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
      * @see org.collectionspace.services.common.storage.StorageClient#delete(org.collectionspace.services.common.context.ServiceContext, java.lang.String, org.collectionspace.services.common.document.DocumentHandler)
      */
     @Override
-    public void delete(ServiceContext ctx, String id, DocumentHandler handler)
+    @Deprecated
+    public void delete(@SuppressWarnings("rawtypes") ServiceContext ctx, String id)
             throws DocumentNotFoundException, DocumentException {
         throw new UnsupportedOperationException();
+        // Use the other delete instead
     }
 
     @Override
@@ -1150,4 +1166,12 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
         }
     }
 
+       @Override
+       public void doWorkflowTransition(ServiceContext ctx, String id,
+                       DocumentHandler handler, TransitionDef transitionDef)
+                       throws BadRequestException, DocumentNotFoundException,
+                       DocumentException {
+               // This is a placeholder for when we change the StorageClient interface to treat workflow transitions as 1st class operations like 'get', 'create', 'update, 'delete', etc
+       }
+
 }
index 5fbe9699ca0ac5fdbc7ee8f070220e5bf5906933..222f312d97d4a749c4901e03183e9244c33bec49 100644 (file)
@@ -53,6 +53,12 @@ public class ConceptValidatorHandler implements ValidatorHandler {
         if (logger.isDebugEnabled()) {
             logger.debug("validate() action=" + action.name());
         }
+        
+        // Bail out if the validation action is for delete.
+        if (action.equals(Action.DELETE)) {
+               return;
+        }
+        
         try {
             MultipartServiceContext mctx = (MultipartServiceContext) ctx;
             ConceptsCommon concept = (ConceptsCommon) mctx.getInputPart(mctx.getCommonPartLabel(),
index 7494b590bda48002ce7008693b49967d00bbba54..cd2c047a0f7703035e8ef8b9de17ac0e3c98c009 100644 (file)
@@ -285,7 +285,8 @@ public abstract class AuthorityResourceWithContacts<AuthCommon, AuthItemHandler>
             ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = null;
             // Note that we have to create the service context for the Contact service, not the main service.
             ctx = createServiceContext(getContactServiceName());
-            getRepositoryClient(ctx).delete(ctx, csid);
+            DocumentHandler handler = createDocumentHandler(ctx);
+            getRepositoryClient(ctx).delete(ctx, csid, handler);
             return Response.status(HttpResponseCodes.SC_OK).build();
         } catch (Exception e) {
             throw bigReThrow(e, "DELETE failed, the requested Contact CSID:" + csid
index 57df41cf1915bc6cdcfbccdd2471212a1e5d165c..017de8543aab5c70249fccbf8d2ff910244dfe55 100644 (file)
@@ -19,7 +19,7 @@
                <ServiceName>dimension</ServiceName>
                <NuxeoDocTypeName>Dimension</NuxeoDocTypeName>
                <CommonSchemaName>dimensions_common</CommonSchemaName>
-               <Lifecycle>cs_default</Lifecycle>
+               <Lifecycle>cs_locking</Lifecycle>
        </properties>
     
     <build>
index 20784b837216cc79dc4b100877a2a24f10707e23..c795e589cebaa8342f4e4edd61009e3c4f8450ce 100644 (file)
             <artifactId>org.collectionspace.services.common</artifactId>\r
             <version>${project.version}</version>\r
         </dependency>\r
-        \r
+        <!-- \r
         <dependency>\r
             <groupId>org.collectionspace.services</groupId>\r
             <artifactId>org.collectionspace.services.IntegrationTests</artifactId>\r
             <version>${project.version}</version>\r
         </dependency>\r
+        -->\r
         \r
         <!-- External dependencies -->\r
         <dependency>\r
index e6828898f984ab4067e08bc1d561d05243efe7e4..3b9aefd983eb4b9b5c3b0a26e0b802d4a5351e89 100644 (file)
@@ -1,19 +1,26 @@
 package org.collectionspace.services.client.test;\r
 \r
+/*\r
+ * XMLReplay test classes shoud ***NOT*** be part of the IntegrationTests module.  Move them out into the org.collectionspace.services.client (src/main.test) module ASAP!\r
+ */\r
+\r
+/*\r
 import org.collectionspace.services.IntegrationTests.xmlreplay.ServiceResult;\r
 import org.collectionspace.services.IntegrationTests.xmlreplay.XmlReplay;\r
 import org.collectionspace.services.IntegrationTests.xmlreplay.XmlReplayTest;\r
 import org.testng.annotations.Test;\r
 \r
 import java.util.List;\r
+*/\r
 \r
 /**\r
  * User: laramie\r
  * $LastChangedRevision:  $\r
  * $LastChangedDate:  $\r
  */\r
-public class DimensionXmlReplayTest extends XmlReplayTest { \r
+public class DimensionXmlReplayTest /*extends XmlReplayTest*/ { \r
 \r
+       /*\r
     //@Test\r
     public void runMaster() throws Exception {\r
         XmlReplay replay = createXmlReplayUsingIntegrationTestsModule("../../");\r
@@ -30,5 +37,6 @@ public class DimensionXmlReplayTest extends XmlReplayTest {
         ServiceResult res = replay.runTest("dimensionTestGroup", "dimension1");\r
         logTest(res, "runOneTest");\r
     }\r
+    */\r
 \r
 }\r
index abb61f38ef12997e7f46354c30f134ccff1e9258..43b647473010607692fe83d67b2b66a54d0ed340 100644 (file)
@@ -136,5 +136,6 @@ public class DimensionDocumentModelHandler
     public String getQProperty(String prop) {
         return DimensionConstants.NUXEO_SCHEMA_NAME + ":" + prop;
     }
+
 }
 
index 5aa5ec9af2e5fb79b026731efa5d81b88acabc21..5c120d5f4554e465916aecf7bb3d823fd03a47d4 100644 (file)
@@ -53,6 +53,12 @@ public class LocationValidatorHandler implements ValidatorHandler {
         if (logger.isDebugEnabled()) {
             logger.debug("validate() action=" + action.name());
         }
+        
+        // Bail out if the validation action is for delete.
+        if (action.equals(Action.DELETE)) {
+               return;
+        }
+        
         try {
             MultipartServiceContext mctx = (MultipartServiceContext) ctx;
             LocationsCommon location = (LocationsCommon) mctx.getInputPart(mctx.getCommonPartLabel(),
index 867baf1ab8f8e773541b1bf8ab07fd29787b1732..a577588ca9bd91bb402fc8ce87ea16a026754f3e 100644 (file)
@@ -52,6 +52,12 @@ public class OrgAuthorityValidatorHandler implements ValidatorHandler {
         if (logger.isDebugEnabled()) {
             logger.debug("validate() action=" + action.name());
         }
+        
+        // Bail out if the validation action is for delete.
+        if (action.equals(Action.DELETE)) {
+               return;
+        }        
+        
         try {
             MultipartServiceContext mctx = (MultipartServiceContext) ctx;
             OrgauthoritiesCommon organizationAuth =
index 88909ebd96590e49d729fbf0e05c24cf057eba12..3c6c6a04b9aedf08271a5be750554b26a0e7cd57 100644 (file)
@@ -52,6 +52,12 @@ public class OrganizationValidatorHandler implements ValidatorHandler {
         if (logger.isDebugEnabled()) {
             logger.debug("validate() action=" + action.name());
         }
+        
+        // Bail out if the validation action is for delete.
+        if (action.equals(Action.DELETE)) {
+               return;
+        }
+        
         try {
             MultipartServiceContext mctx = (MultipartServiceContext) ctx;
             OrganizationsCommon org = (OrganizationsCommon) mctx.getInputPart(mctx.getCommonPartLabel(),
index 70e2ceeb161707d52a9a189dd3dfe7fecbd8cf7f..5cf4320a232e086667f09e73545cbbfa334f4740 100644 (file)
@@ -53,6 +53,12 @@ public class PersonAuthorityValidatorHandler implements ValidatorHandler {
         if (logger.isDebugEnabled()) {
             logger.debug("validate() action=" + action.name());
         }
+        
+        // Bail out if the validation action is for delete.
+        if (action.equals(Action.DELETE)) {
+               return;
+        }
+        
         try {
             MultipartServiceContext mctx = (MultipartServiceContext) ctx;
             PersonauthoritiesCommon personAuth =
index f84e6c06e8eb4d299ce12eef6edbfcac2b36118b..261d81d6d2137f1cd6a2882992a9e19821297705 100644 (file)
@@ -52,6 +52,12 @@ public class PersonValidatorHandler implements ValidatorHandler {
         if (logger.isDebugEnabled()) {
             logger.debug("validate() action=" + action.name());
         }
+        
+        // Bail out if the validation action is for delete.
+        if (action.equals(Action.DELETE)) {
+               return;
+        }
+        
         try {
             MultipartServiceContext mctx = (MultipartServiceContext) ctx;
             PersonsCommon person = (PersonsCommon) mctx.getInputPart(mctx.getCommonPartLabel(),
index feb798c1a86c61d445cc913e31e0e2fc22cdfe1e..bbe1f568c9187e19a2f6a8a0d9985d79b93cb296 100644 (file)
@@ -75,6 +75,12 @@ public class PlaceValidatorHandler implements ValidatorHandler {
         if(logger.isDebugEnabled()) {
             logger.debug("validate() action=" + action.name());
         }
+
+        // Bail out if the validation action is for delete.
+        if (action.equals(Action.DELETE)) {
+               return;
+        }
+        
         try {
             MultipartServiceContext mctx = (MultipartServiceContext) ctx;
             PlacesCommon place = (PlacesCommon) mctx.getInputPart(mctx.getCommonPartLabel(),
index a14a6294bb58b93d325129c27fc0c1ed22af73e0..689319ae33dfbbd6cbdb962b8862b830d1b70371 100644 (file)
@@ -25,10 +25,12 @@ package org.collectionspace.services.relation.nuxeo;
 
 import java.util.HashMap;
 import java.util.Iterator;
+import java.net.HttpURLConnection;
 
 import org.collectionspace.services.client.PoxPayloadIn;
 import org.collectionspace.services.client.PoxPayloadOut;
 import org.collectionspace.services.common.ResourceBase;
+import org.collectionspace.services.common.ServiceException;
 import org.collectionspace.services.common.ServiceMain;
 import org.collectionspace.services.common.api.RefName;
 import org.collectionspace.services.common.api.Tools;
@@ -40,6 +42,7 @@ import org.collectionspace.services.common.document.InvalidDocumentException;
 import org.collectionspace.services.common.relation.RelationJAXBSchema;
 import org.collectionspace.services.common.relation.nuxeo.RelationConstants;
 import org.collectionspace.services.common.context.ServiceContext;
+import org.collectionspace.services.lifecycle.TransitionDef;
 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
 import org.collectionspace.services.relation.RelationsCommon;
 import org.collectionspace.services.relation.RelationsCommonList;
@@ -53,12 +56,12 @@ import org.collectionspace.services.client.LocationAuthorityClient;
 import org.collectionspace.services.client.TaxonomyAuthorityClient;
 import org.collectionspace.services.client.PlaceAuthorityClient;
 import org.collectionspace.services.client.ConceptAuthorityClient;
+import org.collectionspace.services.client.workflow.WorkflowClient;
 
 import org.collectionspace.services.config.service.ServiceBindingType;
 import org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl;
 import org.collectionspace.services.nuxeo.client.java.RepositoryJavaClientImpl;
 import org.nuxeo.ecm.core.api.ClientException;
-import org.nuxeo.ecm.core.api.CoreSession;
 import org.nuxeo.ecm.core.api.DocumentModel;
 import org.nuxeo.ecm.core.api.DocumentModelList;
 import org.nuxeo.ecm.core.api.model.PropertyException;
@@ -86,6 +89,47 @@ public class RelationDocumentModelHandler
      * for ACTION.GET_ALL
      */
     private RelationsCommonList relationList;
+    
+    private static final String ERROR_TERMS_IN_WORKFLOWSTATE = "Cannot modify a relationship if either end is in the workflow state: ";
+
+    
+    private boolean subjectOrObjectInWorkflowState(DocumentWrapper<DocumentModel> wrapDoc, String workflowState) throws ServiceException {
+       boolean result = false;
+       DocumentModel relationDocModel = wrapDoc.getWrappedObject();
+       String errMsg = ERROR_TERMS_IN_WORKFLOWSTATE + workflowState;
+                       
+        RepositoryInstance repoSession = this.getRepositorySession();
+        try {
+                       DocumentModel subjectDocModel = getSubjectOrObjectDocModel(repoSession, relationDocModel, SUBJ_DOC_MODEL);
+                       DocumentModel objectDocModel = getSubjectOrObjectDocModel(repoSession, relationDocModel, OBJ_DOC_MODEL);
+                       if (subjectDocModel.getCurrentLifeCycleState().equalsIgnoreCase(workflowState) ||
+                                       objectDocModel.getCurrentLifeCycleState().equalsIgnoreCase(workflowState)) {
+                               result = true;
+                       }
+               } catch (Exception e) {
+                       if (logger.isInfoEnabled() == true) {
+                               logger.info(errMsg, e);
+                       }
+               }
+               
+       return result;
+    }
+    
+       @Override
+       /*
+        * Until we rework the RepositoryClient to handle the workflow transition (just like it does for 'create', 'get', 'update', and 'delete', this method will only check to see if the transition is allowed.  Until then,
+        * the WorkflowDocumentModelHandler class does the actual workflow transition.
+        * 
+        * @see org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl#handleWorkflowTransition(org.collectionspace.services.common.document.DocumentWrapper, org.collectionspace.services.lifecycle.TransitionDef)
+        */
+       public void handleWorkflowTransition(DocumentWrapper<DocumentModel> wrapDoc, TransitionDef transitionDef)
+                       throws Exception {
+               String workflowState = transitionDef.getDestinationState();
+               if (subjectOrObjectInWorkflowState(wrapDoc, workflowState) == true) {
+               throw new ServiceException(HttpURLConnection.HTTP_FORBIDDEN,
+                    "Cannot change a relationship if either end of it is in the workflow state: " + workflowState);
+               }
+       }
 
     @Override
     public void handleCreate(DocumentWrapper<DocumentModel> wrapDoc) throws Exception {
@@ -94,6 +138,13 @@ public class RelationDocumentModelHandler
 
         // And take care of ensuring all the values for the relation info are correct 
         populateSubjectAndObjectValues(wrapDoc);
+       
+        // both subject and object cannot be locked
+       String workflowState = WorkflowClient.WORKFLOWSTATE_LOCKED;
+       if (subjectOrObjectInWorkflowState(wrapDoc, workflowState) == true) {
+               throw new ServiceException(HttpURLConnection.HTTP_FORBIDDEN,
+                    "Cannot create a relationship if either end is in the workflow state: " + workflowState);
+       }
     }
 
     @Override
@@ -105,6 +156,18 @@ public class RelationDocumentModelHandler
         populateSubjectAndObjectValues(wrapDoc);
     }
     
+    @Override
+    public void handleDelete(DocumentWrapper<DocumentModel> wrapDoc) throws Exception {
+       String workflowState = WorkflowClient.WORKFLOWSTATE_LOCKED;
+       // both subject and object cannot be locked
+       if (subjectOrObjectInWorkflowState(wrapDoc, workflowState) == false) {
+               super.handleDelete(wrapDoc);
+       } else {
+               throw new ServiceException(HttpURLConnection.HTTP_FORBIDDEN,
+                    "Cannot delete a relationship if either end is in the workflow state: " + workflowState);
+       }
+    }
+    
     private void populateSubjectAndObjectValues(DocumentWrapper<DocumentModel> wrapDoc) throws Exception {
         // Obtain document models for the subject and object of the relation, so that
         // we ensure we have value docType, URI info. If the docModels support refNames, 
index 8a87d4f44d92f4f0356a560fd982c98845c7bd72..abc758b339af456f54a044f1814ffb789613fd82 100644 (file)
@@ -52,6 +52,12 @@ public class TaxonValidatorHandler implements ValidatorHandler {
         if (logger.isDebugEnabled()) {
             logger.debug("validate() action=" + action.name());
         }
+        
+        // Bail out if the validation action is for delete.
+        if (action.equals(Action.DELETE)) {
+               return;
+        }
+        
         try {
             MultipartServiceContext mctx = (MultipartServiceContext) ctx;
             TaxonCommon taxon = (TaxonCommon) mctx.getInputPart(mctx.getCommonPartLabel(),
index f30b652f923b6c054889690ae0acc4d54306ff8b..e51a9be115fd504b6a2f846f42aa8292fd647b79 100644 (file)
@@ -53,6 +53,12 @@ public class VocabularyItemValidatorHandler implements ValidatorHandler {
         if (logger.isDebugEnabled()) {
             logger.debug("validate() action=" + action.name());
         }
+        
+        // Bail out if the validation action is for delete.
+        if (action.equals(Action.DELETE)) {
+               return;
+        }
+        
         try {
             MultipartServiceContext mctx = (MultipartServiceContext) ctx;
             VocabularyitemsCommon vocabItem = (VocabularyitemsCommon) mctx.getInputPart(mctx.getCommonPartLabel(),
index 02b06dd1765dccdd9cdd3eaa088a82377e221749..a787372056e5e39f53e467900781930e21aa0ed7 100644 (file)
@@ -53,6 +53,12 @@ public class VocabularyValidatorHandler implements ValidatorHandler {
         if (logger.isDebugEnabled()) {
             logger.debug("validate() action=" + action.name());
         }
+        
+        // Bail out if the validation action is for delete.
+        if (action.equals(Action.DELETE)) {
+               return;
+        }
+        
         try {
             MultipartServiceContext mctx = (MultipartServiceContext) ctx;
             VocabulariesCommon vocab = (VocabulariesCommon) mctx.getInputPart(mctx.getCommonPartLabel(),