]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-3900 More support for invoking Batch processes. Added ResourceMap to injectabl...
authorPatrick Schmitz <pschmitz@berkeley.edu>
Thu, 26 May 2011 07:05:27 +0000 (07:05 +0000)
committerPatrick Schmitz <pschmitz@berkeley.edu>
Thu, 26 May 2011 07:05:27 +0000 (07:05 +0000)
19 files changed:
services/IntegrationTests/src/test/resources/test-data/xmlreplay/batch/batch.xml [new file with mode: 0644]
services/IntegrationTests/src/test/resources/test-data/xmlreplay/batch/batch1.xml [new file with mode: 0644]
services/IntegrationTests/src/test/resources/test-data/xmlreplay/batch/batch1InvContext.xml [new file with mode: 0644]
services/IntegrationTests/src/test/resources/test-data/xmlreplay/batch/collObj1.xml [new file with mode: 0644]
services/JaxRsServiceProvider/src/main/java/org/collectionspace/services/jaxrs/CSpaceResteasyBootstrap.java [new file with mode: 0644]
services/JaxRsServiceProvider/src/main/java/org/collectionspace/services/jaxrs/CollectionSpaceJaxRsApplication.java
services/JaxRsServiceProvider/src/main/webapp/WEB-INF/web.xml
services/batch/jaxb/src/main/java/org/collectionspace/services/BatchJAXBSchema.java
services/batch/service/pom.xml
services/batch/service/src/main/java/org/collectionspace/services/batch/BatchInvocable.java [new file with mode: 0644]
services/batch/service/src/main/java/org/collectionspace/services/batch/BatchResource.java
services/batch/service/src/main/java/org/collectionspace/services/batch/nuxeo/BatchValidatorHandler.java
services/batch/service/src/main/java/org/collectionspace/services/batch/nuxeo/CreateAndLinkLoanOutBatchJob.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/common/ResourceMap.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/common/ResourceMapHolder.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/common/ResourceMapImpl.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/common/invocable/Invocable.java [new file with mode: 0644]
services/jaxb/src/main/resources/invocationContext.xsd [new file with mode: 0644]
services/jaxb/src/main/resources/invocationResults.xsd [new file with mode: 0644]

diff --git a/services/IntegrationTests/src/test/resources/test-data/xmlreplay/batch/batch.xml b/services/IntegrationTests/src/test/resources/test-data/xmlreplay/batch/batch.xml
new file mode 100644 (file)
index 0000000..cce9951
--- /dev/null
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<xmlReplay>\r
+    <auths>\r
+        <!-- IMPORTANT: THESE ARE STICKY :: THEY STICK AROUND UNTIL RESET, IN EXEC ORDER OF THIS FILE. -->\r
+        <auth ID="admin@collectionspace.org">YWRtaW5AY29sbGVjdGlvbnNwYWNlLm9yZzpBZG1pbmlzdHJhdG9y</auth>\r
+        <auth ID="testAdministator">YWRtaW5AY29sbGVjdGlvbnNwYWNlLm9yZzpBZG1pbmlzdHJhdG9y</auth>\r
+    </auths>\r
+   \r
+    <testGroup ID="primary" autoDeletePOSTS="false">\r
+       <test ID="ba1"  auth="test">\r
+             <method>POST</method>\r
+             <uri>/cspace-services/batch/</uri>\r
+             <filename>batch/batch1.xml</filename>\r
+         </test>\r
+       <test ID="ba2"  auth="test">\r
+             <method>POST</method>\r
+             <uri>/cspace-services/collectionobjects/</uri>\r
+             <filename>batch/collObj1.xml</filename>\r
+         </test>\r
+       <test ID="ba3"  auth="test">\r
+             <method>POST</method>\r
+             <uri>/cspace-services/batch/${ba1.CSID}</uri>\r
+             <filename>batch/batch1InvContext.xml</filename>\r
+             <vars>\r
+                <var ID="CollObj1">${ba2.CSID}</var>\r
+             </vars>\r
+                        </test>\r
+     </testGroup>       \r
+\r
+     <testGroup ID="cleanup" autoDeletePOSTS="true">\r
+         <test ID="cl1"  auth="test">\r
+             <method>DELETE</method>\r
+             <uri>/cspace-services/batch/${ba1.CSID}</uri>\r
+         </test>\r
+         <test ID="cl2"  auth="test">\r
+             <method>DELETE</method>\r
+             <uri>/cspace-services/collectionobjects/${ba2.CSID}</uri>\r
+         </test>\r
+                        </testGroup>\r
+    \r
+\r
+</xmlReplay>\r
diff --git a/services/IntegrationTests/src/test/resources/test-data/xmlreplay/batch/batch1.xml b/services/IntegrationTests/src/test/resources/test-data/xmlreplay/batch/batch1.xml
new file mode 100644 (file)
index 0000000..e68dd18
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r
+<document name="batch">\r
+       <ns2:batch_common\r
+       xmlns:ns2="http://collectionspace.org/services/batch"\r
+       xmlns:ns3="http://collectionspace.org/services/jaxb">\r
+               <name>TestCreateAndLinkLoanOutBatchJob</name>\r
+               <notes>This should be interesting</notes>\r
+               <forDocType>CollectionObject</forDocType>\r
+               <forSingleDoc>true</forSingleDoc>\r
+               <createsNewFocus>true</createsNewFocus>\r
+               <className>org.collectionspace.services.batch.nuxeo.CreateAndLinkLoanOutBatchJob</className>\r
+       </ns2:batch_common>\r
+</document>\r
diff --git a/services/IntegrationTests/src/test/resources/test-data/xmlreplay/batch/batch1InvContext.xml b/services/IntegrationTests/src/test/resources/test-data/xmlreplay/batch/batch1InvContext.xml
new file mode 100644 (file)
index 0000000..fb3ac7b
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r
+<ns2:invocationContext\r
+xmlns:ns2="http://collectionspace.org/services/common/invocable"\r
+xmlns:ns3="http://collectionspace.org/services/jaxb">\r
+  <mode>single</mode>\r
+       <docType>CollectionObject</docType>\r
+       <singleCSID>${CollObj1}</singleCSID>\r
+</ns2:invocationContext>\r
+\r
+\r
diff --git a/services/IntegrationTests/src/test/resources/test-data/xmlreplay/batch/collObj1.xml b/services/IntegrationTests/src/test/resources/test-data/xmlreplay/batch/collObj1.xml
new file mode 100644 (file)
index 0000000..3d16f56
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document name="collectionobjects">
+<ns2:collectionobjects_common xmlns:ns2="http://collectionspace.org/services/collectionobject">
+  <objectNumber>objectNumber</objectNumber>
+  <otherNumber>XXX</otherNumber>
+  <otherNumberType>otherNumberType</otherNumberType>
+</ns2:collectionobjects_common> 
+</document>
+
diff --git a/services/JaxRsServiceProvider/src/main/java/org/collectionspace/services/jaxrs/CSpaceResteasyBootstrap.java b/services/JaxRsServiceProvider/src/main/java/org/collectionspace/services/jaxrs/CSpaceResteasyBootstrap.java
new file mode 100644 (file)
index 0000000..15dac1c
--- /dev/null
@@ -0,0 +1,19 @@
+package org.collectionspace.services.jaxrs;\r
+\r
+import javax.servlet.ServletContextEvent;\r
+\r
+import org.jboss.resteasy.core.Dispatcher;\r
+import org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap;\r
+import org.collectionspace.services.common.ResourceMap;\r
+\r
+public class CSpaceResteasyBootstrap extends ResteasyBootstrap {\r
+       \r
+       public void  contextInitialized(ServletContextEvent event) {\r
+               super.contextInitialized(event);\r
+               CollectionSpaceJaxRsApplication app = \r
+                       (CollectionSpaceJaxRsApplication)deployment.getApplication();\r
+               Dispatcher disp = deployment.getDispatcher();\r
+               disp.getDefaultContextObjects().put(ResourceMap.class, app.getResourceMap());\r
+       }\r
+\r
+}\r
index 8f41d889e481025f2c1b452098d5e25a0bc5f1b8..a8d309c629b25f186605291ad64f00b5a5e50507 100644 (file)
@@ -51,13 +51,22 @@ import org.collectionspace.services.workflow.WorkflowResource;
 //import org.collectionspace.services.query.QueryResource;
 
 import javax.ws.rs.core.Application;
+import javax.ws.rs.core.Context;
+
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Set;
 
 //import org.collectionspace.services.common.FileUtils;
 import org.collectionspace.services.authorization.PermissionResource;
 import org.collectionspace.services.authorization.RoleResource;
+import org.collectionspace.services.common.ResourceBase;
+import org.collectionspace.services.common.ResourceMap;
+import org.collectionspace.services.common.ResourceMapHolder;
+import org.collectionspace.services.common.ResourceMapImpl;
 import org.collectionspace.services.common.security.SecurityInterceptor;
+import org.jboss.resteasy.core.Dispatcher;
+import org.jboss.resteasy.spi.ResteasyProviderFactory;
 //import org.collectionspace.services.common.document.DocumentUtils;
 //import org.collectionspace.services.common.imaging.nuxeo.NuxeoImageUtils;
 //import org.collectionspace.services.common.profile.Profiler;
@@ -70,41 +79,48 @@ import org.collectionspace.services.common.security.SecurityInterceptor;
  * $LastChangedRevision$
  * $LastChangedDate$
  */
-public class CollectionSpaceJaxRsApplication extends Application {
+public class CollectionSpaceJaxRsApplication extends Application
+                                       implements ResourceMapHolder {
 
     private Set<Object> singletons = new HashSet<Object>();
     private Set<Class<?>> empty = new HashSet<Class<?>>();    
+    private ResourceMap resourceMap = new ResourceMapImpl();
 
     public CollectionSpaceJaxRsApplication() {         
        //
        // Instantiate all our JaxRS resources
        //
+       ResourceBase resource;
         singletons.add(new SecurityInterceptor());
         singletons.add(new AccountResource());
         singletons.add(new RoleResource());
         singletons.add(new PermissionResource());
+
         singletons.add(new VocabularyResource());
-        singletons.add(new ContactResource());
         singletons.add(new PersonAuthorityResource());
         singletons.add(new OrgAuthorityResource());
-        singletons.add(new CollectionObjectResource());
-        singletons.add(new GroupResource());
-        singletons.add(new IntakeResource());
-        singletons.add(new DimensionResource());
-        singletons.add(new RelationResource());
-        singletons.add(new NoteResource());
-        singletons.add(new LoaninResource());
-        singletons.add(new LoanoutResource());
-        singletons.add(new AcquisitionResource());
-        singletons.add(new ObjectExitResource());
-        singletons.add(new BatchResource());
-        singletons.add(new ImportsResource());
-        singletons.add(new MediaResource());
-        singletons.add(new BlobResource());
-        singletons.add(new MovementResource());
-        singletons.add(new ReportResource());
         singletons.add(new LocationAuthorityResource());
         singletons.add(new TaxonomyAuthorityResource());
+
+        singletons.add(new AcquisitionResource());
+        
+        addResourceToMapAndSingletons(new ContactResource());
+        addResourceToMapAndSingletons(new CollectionObjectResource());
+        addResourceToMapAndSingletons(new GroupResource());
+        addResourceToMapAndSingletons(new IntakeResource());
+        addResourceToMapAndSingletons(new DimensionResource());
+        addResourceToMapAndSingletons(new RelationResource());
+        addResourceToMapAndSingletons(new NoteResource());
+        addResourceToMapAndSingletons(new LoaninResource());
+        addResourceToMapAndSingletons(new LoanoutResource());
+        addResourceToMapAndSingletons(new ObjectExitResource());
+        addResourceToMapAndSingletons(new BatchResource());
+        addResourceToMapAndSingletons(new ImportsResource());
+        addResourceToMapAndSingletons(new MediaResource());
+        addResourceToMapAndSingletons(new BlobResource());
+        addResourceToMapAndSingletons(new MovementResource());
+        addResourceToMapAndSingletons(new ReportResource());
+
         singletons.add(new IDResource());
         /*
         singletons.add(new WorkflowResource());
@@ -113,6 +129,11 @@ public class CollectionSpaceJaxRsApplication extends Application {
 //        singletons.add(new DomainIdentifierResource());
 //        singletons.add(new PingResource());
     }
+    
+    private void addResourceToMapAndSingletons(ResourceBase resource) {
+        singletons.add(resource);
+        resourceMap.put(resource.getClass().getName(), resource);
+    }
 
     @Override
     public Set<Class<?>> getClasses() {
@@ -123,5 +144,9 @@ public class CollectionSpaceJaxRsApplication extends Application {
     public Set<Object> getSingletons() {
         return singletons;
     }
+
+    public ResourceMap getResourceMap() {
+        return resourceMap;
+    }
 }
 
index c1395cf268e570c470d72ab4c00b6554e06c1483..079bb6bc5043c548d42b99bd4490f64d6d428071 100644 (file)
@@ -82,7 +82,7 @@
 \r
     <listener>\r
         <listener-class>\r
-            org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap\r
+            org.collectionspace.services.jaxrs.CSpaceResteasyBootstrap\r
         </listener-class>\r
     </listener>\r
 \r
index 99e8176186acd4a05b8db41d1f8432d34ec1f673..122e79eb0bafcdbe5aaef5f39a31da281086650f 100644 (file)
@@ -5,5 +5,9 @@ package org.collectionspace.services;
 
 public interface BatchJAXBSchema {
     final static String BATCH_NAME = "name";
-    final static String BATCH_FORDOCTYPE = "forDocType";
+    final static String BATCH_NOTES = "notes";
+    final static String BATCH_FOR_DOC_TYPE = "forDocType";
+    final static String BATCH_FOR_SINGLE_DOC = "forSingleDoc";
+    final static String BATCH_CREATES_NEW_FOCUS = "createsNewFocus";
+    final static String BATCH_CLASS_NAME = "className";
 }
index 546385db75a1600242e3abc454136c53d0cd6993..a5726ef3101d66d0f18bc0edd05ac8f1443a08c7 100644 (file)
             <artifactId>org.collectionspace.services.common</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.collectionspace.services</groupId>
+            <artifactId>org.collectionspace.services.jaxb</artifactId>
+            <version>${project.version}</version>
+        </dependency>
         <dependency>
             <groupId>org.collectionspace.services</groupId>
             <artifactId>org.collectionspace.services.batch.client</artifactId>
diff --git a/services/batch/service/src/main/java/org/collectionspace/services/batch/BatchInvocable.java b/services/batch/service/src/main/java/org/collectionspace/services/batch/BatchInvocable.java
new file mode 100644 (file)
index 0000000..01274ea
--- /dev/null
@@ -0,0 +1,18 @@
+package org.collectionspace.services.batch;\r
+\r
+import java.util.HashMap;\r
+import java.util.Set;\r
+\r
+import org.collectionspace.services.common.ResourceBase;\r
+import org.collectionspace.services.common.ResourceMap;\r
+import org.collectionspace.services.common.invocable.Invocable;\r
+\r
+public interface BatchInvocable extends Invocable {\r
+\r
+       /**\r
+        * Sets the invocation context for the batch job. Called before run().\r
+        * @param context an instance of InvocationContext.\r
+        */\r
+       public void setResourceMap(ResourceMap resourceMap);\r
+\r
+}\r
index cdf6f6a7be1a75055fda0e97eb0a17b2a65e7237..3cf7b675177ccbe19210a0d5ac0c959354beaeba 100644 (file)
  */
 package org.collectionspace.services.batch;
 
+import java.util.List;
+
+import org.collectionspace.services.BatchJAXBSchema;
 import org.collectionspace.services.client.BatchClient;
+import org.collectionspace.services.client.PoxPayloadIn;
+import org.collectionspace.services.client.PoxPayloadOut;
 import org.collectionspace.services.common.ResourceBase;
+import org.collectionspace.services.common.ResourceMap;
+import org.collectionspace.services.common.ServiceMessages;
+import org.collectionspace.services.common.context.ServiceContext;
+import org.collectionspace.services.common.document.DocumentHandler;
+import org.collectionspace.services.common.document.DocumentWrapper;
+import org.collectionspace.services.common.document.ValidatorHandler;
+import org.collectionspace.services.common.invocable.Invocable;
+import org.collectionspace.services.common.invocable.InvocationContext;
+import org.collectionspace.services.common.invocable.InvocationResults;
+import org.jboss.resteasy.spi.ResteasyProviderFactory;
+import org.nuxeo.ecm.core.api.DocumentModel;
+import org.collectionspace.services.common.ResourceMapHolder;
 
 import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
 import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.UriInfo;
 
 @Path(BatchClient.SERVICE_PATH)
 @Produces({"application/xml"})
@@ -56,4 +78,67 @@ public class BatchResource extends ResourceBase {
         }
     }
     
+    @POST
+    @Path("{csid}")
+    public InvocationResults invokeBatchJob(
+               @Context ResourceMap resourceMap, 
+               @PathParam("csid") String csid,
+               InvocationContext invContext) {
+        try {
+            ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext();
+            DocumentHandler handler = createDocumentHandler(ctx);
+            DocumentWrapper<DocumentModel> wrapper = 
+               getRepositoryClient(ctx).getDoc(ctx, csid);
+               DocumentModel docModel = wrapper.getWrappedObject();
+               String className = 
+                       (String)docModel.getPropertyValue(BatchJAXBSchema.BATCH_CLASS_NAME);
+               className = className.trim();
+            ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+            Class<?> c = tccl.loadClass(className);
+               // enable validation assertions
+               tccl.setClassAssertionStatus(className, true);
+            if(!BatchInvocable.class.isAssignableFrom(c)) {
+               throw new RuntimeException("BatchResource: Class: "
+                               +className+" does not implement BatchInvocable!");
+            } else {
+               BatchInvocable batchInstance = (BatchInvocable)c.newInstance();
+               List<String> modes = batchInstance.getSupportedInvocationModes();
+               if(!modes.contains(invContext.getMode())) {
+                       throw new RuntimeException(
+                                       "BatchResource: Invoked with unsupported context mode: "
+                                       +invContext.getMode());
+               }
+                       String forDocType = 
+                               (String)docModel.getPropertyValue(BatchJAXBSchema.BATCH_FOR_DOC_TYPE);
+               if(!forDocType.equalsIgnoreCase(invContext.getDocType())) {
+                       throw new RuntimeException(
+                                       "BatchResource: Invoked with unsupported document type: "
+                                       +invContext.getDocType());
+               }
+               batchInstance.setInvocationContext(invContext);
+               //ResourceMapHolder csapp = (ResourceMapHolder)app;
+               if(resourceMap!=null) {
+                       batchInstance.setResourceMap(resourceMap);
+               } else {
+                       resourceMap = ResteasyProviderFactory.getContextData(ResourceMap.class);
+                       if(resourceMap!=null) {
+                               batchInstance.setResourceMap(resourceMap);
+                       } else {
+                               logger.warn("BatchResource.invoke did not get a resourceMapHolder in Context!");
+                       }
+               }
+               batchInstance.run();
+               int status = batchInstance.getCompletionStatus();
+               if(status == Invocable.STATUS_ERROR) {
+                       throw new RuntimeException(
+                                       "BatchResouce: batchProcess encountered error: "
+                                       +batchInstance.getErrorInfo());
+               }
+               InvocationResults results = batchInstance.getResults();
+               return results;
+            }
+        } catch (Exception e) {
+            throw bigReThrow(e, ServiceMessages.POST_FAILED);
+        }
+    }
 }
index 990094eb2f475d7b29ce8ba54dd27e3ac044c1f9..4598b146d2fc14ffdb472f7dbc65f8a5b1a520e1 100644 (file)
@@ -11,8 +11,7 @@ public class BatchValidatorHandler implements ValidatorHandler {
        public void validate(Action action, ServiceContext ctx)
                        throws InvalidDocumentException {
                // TODO Auto-generated method stub
-               System.out.println("BatchValidatorHandler executed.");
-
+               //System.out.println("BatchValidatorHandler executed.");
        }
 
 }
diff --git a/services/batch/service/src/main/java/org/collectionspace/services/batch/nuxeo/CreateAndLinkLoanOutBatchJob.java b/services/batch/service/src/main/java/org/collectionspace/services/batch/nuxeo/CreateAndLinkLoanOutBatchJob.java
new file mode 100644 (file)
index 0000000..b0f77f4
--- /dev/null
@@ -0,0 +1,101 @@
+package org.collectionspace.services.batch.nuxeo;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.collectionspace.services.batch.BatchInvocable;
+import org.collectionspace.services.common.ResourceBase;
+import org.collectionspace.services.common.ResourceMap;
+import org.collectionspace.services.common.invocable.InvocationContext;
+import org.collectionspace.services.common.invocable.InvocationResults;
+
+public class CreateAndLinkLoanOutBatchJob implements BatchInvocable {
+
+       private static ArrayList<String> invocationModes = null;
+       private InvocationContext context;
+       private int completionStatus;
+       private HashMap<String,ResourceBase> resourceMap;
+       private InvocationResults results;
+       private String errorInfo;
+       
+       public CreateAndLinkLoanOutBatchJob() {
+               CreateAndLinkLoanOutBatchJob.setupClassStatics();
+               context = null;
+               completionStatus = STATUS_UNSTARTED;
+               resourceMap = null;
+               results = new InvocationResults();
+               errorInfo = "";
+       }
+
+       private static void setupClassStatics() {
+               if(invocationModes == null ) {
+                       invocationModes = new ArrayList<String>(1);
+                       invocationModes.add(INVOCATION_MODE_SINGLE);
+               }
+       }
+
+       /**
+        * @return a set of modes that this plugin can support on invocation. Must be non-empty.
+        */
+       public List<String> getSupportedInvocationModes() {
+               return CreateAndLinkLoanOutBatchJob.invocationModes;
+       }
+       
+       /**
+        * Sets the invocation context for the batch job. Called before run().
+        * @param context an instance of InvocationContext.
+        */
+       public void setInvocationContext(InvocationContext context) {
+               this.context = context;
+       }
+
+       /**
+        * Sets the invocation context for the batch job. Called before run().
+        * @param context an instance of InvocationContext.
+        */
+       public void setResourceMap(ResourceMap resourceMap) {
+       }
+
+       /**
+        * The main work logic of the batch job. Will be called after setContext.
+        */
+       public void run() {
+               completionStatus = STATUS_UNSTARTED;
+               try {
+                       Thread.sleep(1000);
+               } catch(Exception e) {}
+               results.setPrimaryURICreated(null);
+               results.setNumAffected(0);
+               results.setUserNote("CreateAndLinkLoanOutBatchJob pretended to do work, and completed");
+               completionStatus = STATUS_COMPLETE;
+       }
+
+       /**
+        * @return one of the STATUS_* constants, or a value from 1-99 to indicate progress.
+        * Implementations need not support partial completion (progress) values, and can transition
+        * from STATUS_MIN_PROGRESS to STATUS_COMPLETE.
+        */
+       public int getCompletionStatus() {
+               return completionStatus;
+       }
+
+       /**
+        * @return information about the batch job actions and results
+        */
+       public InvocationResults getResults() {
+               if(completionStatus != STATUS_COMPLETE)
+                       return null;
+               return results;
+       }
+
+       /**
+        * @return a user-presentable note when an error occurs in batch processing. Will only
+        * be called if getCompletionStatus() returns STATUS_ERROR.
+        */
+       public String getErrorInfo() {
+               return errorInfo;
+       }
+
+
+}
diff --git a/services/common/src/main/java/org/collectionspace/services/common/ResourceMap.java b/services/common/src/main/java/org/collectionspace/services/common/ResourceMap.java
new file mode 100644 (file)
index 0000000..2f98da3
--- /dev/null
@@ -0,0 +1,7 @@
+package org.collectionspace.services.common;\r
+\r
+import java.util.Map;\r
+\r
+public interface ResourceMap extends Map<String, ResourceBase> {\r
+\r
+}\r
diff --git a/services/common/src/main/java/org/collectionspace/services/common/ResourceMapHolder.java b/services/common/src/main/java/org/collectionspace/services/common/ResourceMapHolder.java
new file mode 100644 (file)
index 0000000..7bb2986
--- /dev/null
@@ -0,0 +1,5 @@
+package org.collectionspace.services.common;\r
+\r
+public interface ResourceMapHolder {\r
+       public ResourceMap getResourceMap();\r
+}\r
diff --git a/services/common/src/main/java/org/collectionspace/services/common/ResourceMapImpl.java b/services/common/src/main/java/org/collectionspace/services/common/ResourceMapImpl.java
new file mode 100644 (file)
index 0000000..4845d99
--- /dev/null
@@ -0,0 +1,7 @@
+package org.collectionspace.services.common;\r
+\r
+import java.util.HashMap;\r
+\r
+public class ResourceMapImpl extends HashMap<String, ResourceBase> implements ResourceMap {\r
+\r
+}\r
diff --git a/services/common/src/main/java/org/collectionspace/services/common/invocable/Invocable.java b/services/common/src/main/java/org/collectionspace/services/common/invocable/Invocable.java
new file mode 100644 (file)
index 0000000..16212a8
--- /dev/null
@@ -0,0 +1,82 @@
+/**
+ *  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.invocable;
+
+import org.collectionspace.services.common.invocable.InvocationContext;
+import java.util.List;
+
+
+/**
+ * Invocation defines an interface for invocable jobs (batch, reports, exports, etc)
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ */
+public interface Invocable {
+
+       public String INVOCATION_MODE_SINGLE = "single";
+       public String INVOCATION_MODE_GROUP = "group";
+       public String INVOCATION_MODE_LIST = "list";
+       //public String INVOCATION_MODE_QUERY = "query"; NYI
+
+       public final int        STATUS_ERROR = -1;
+       public final int        STATUS_UNSTARTED = 0;
+       public final int        STATUS_MIN_PROGRESS = 1;
+       public final int        STATUS_COMPLETE = 100;
+       
+       /**
+        * @return a set of modes that this plugin can support on invocation. Must be non-empty.
+        */
+       public List<String> getSupportedInvocationModes();
+       
+       /**
+        * Sets the invocation context for the batch job. Called before run().
+        * @param context an instance of InvocationContext.
+        */
+       public void setInvocationContext(InvocationContext context);
+
+       /**
+        * The main work logic of the batch job. Will be called after setContext.
+        */
+       public void run();
+
+       /**
+        * @return one of the STATUS_* constants, or a value from 1-99 to indicate progress.
+        * Implementations need not support partial completion (progress) values, and can transition
+        * from STATUS_MIN_PROGRESS to STATUS_COMPLETE.
+        */
+       public int getCompletionStatus();
+
+       /**
+        * @return information about the batch job actions and results
+        */
+       public InvocationResults getResults();
+
+       /**
+        * @return a user-presentable note when an error occurs in batch processing. Will only
+        * be called if getCompletionStatus() returns STATUS_ERROR.
+        */
+       public String getErrorInfo();
+
+}
diff --git a/services/jaxb/src/main/resources/invocationContext.xsd b/services/jaxb/src/main/resources/invocationContext.xsd
new file mode 100644 (file)
index 0000000..0f1c0b9
--- /dev/null
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+    Invocation Context schema (XSD)
+    
+    Entity  : Invocation
+    Used for: JAXB binding between XML and Java objects
+
+    $LastChangedRevision: 2316 $
+    $LastChangedDate: 2010-06-02 16:03:51 -0700 (Wed, 02 Jun 2010) $
+-->
+<xs:schema 
+               xmlns:xs="http://www.w3.org/2001/XMLSchema" 
+               xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
+               jaxb:version="1.0" elementFormDefault="unqualified" 
+               xmlns:ns="http://collectionspace.org/services/common/invocable" 
+               xmlns="http://collectionspace.org/services/common/invocable" 
+               targetNamespace="http://collectionspace.org/services/common/invocable" version="0.1">
+       
+       <xs:element name="invocationContext">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="mode" type="xs:string"/>
+                               <xs:element name="docType" type="xs:string"/>
+                               <xs:element name="singleCSID" type="xs:string"/>
+                               <xs:element name="groupCSID" type="xs:string"/>
+                               <xs:element name="listCSIDs">
+                                       <xs:complexType>
+                                               <xs:sequence>
+                                                       <xs:element name="csids" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+                                               </xs:sequence>
+                                       </xs:complexType>
+                               </xs:element>
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+</xs:schema>
+
diff --git a/services/jaxb/src/main/resources/invocationResults.xsd b/services/jaxb/src/main/resources/invocationResults.xsd
new file mode 100644 (file)
index 0000000..7f7b732
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+    Invocation Results schema (XSD)
+    
+    Entity  : Invocation
+    Used for: JAXB binding between XML and Java objects
+
+    $LastChangedRevision: 2316 $
+    $LastChangedDate: 2010-06-02 16:03:51 -0700 (Wed, 02 Jun 2010) $
+-->
+<xs:schema 
+               xmlns:xs="http://www.w3.org/2001/XMLSchema" 
+               xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
+               jaxb:version="1.0" elementFormDefault="unqualified" 
+               xmlns:ns="http://collectionspace.org/services/common/invocable" 
+               xmlns="http://collectionspace.org/services/common/invocable" 
+               targetNamespace="http://collectionspace.org/services/common/invocable" version="0.1">
+       
+       <xs:element name="invocationResults">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="primaryURICreated" type="xs:string"/>
+                               <xs:element name="userNote" type="xs:string"/>
+                               <xs:element name="numAffected" type="xs:unsignedInt"/>
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+</xs:schema>
+