1 package org.collectionspace.services.batch.nuxeo;
3 import java.util.ArrayList;
6 import javax.ws.rs.core.Response;
8 import org.collectionspace.services.batch.BatchInvocable;
9 import org.collectionspace.services.client.CollectionSpaceClientUtils;
10 import org.collectionspace.services.common.NuxeoBasedResource;
11 import org.collectionspace.services.common.ResourceMap;
12 import org.collectionspace.services.common.api.GregorianCalendarDateTimeUtils;
13 import org.collectionspace.services.common.context.ServiceContext;
14 import org.collectionspace.services.common.invocable.InvocationContext;
15 import org.collectionspace.services.common.invocable.InvocationResults;
16 import org.collectionspace.services.client.LoanoutClient;
17 import org.collectionspace.services.client.RelationClient;
19 public class CreateAndLinkLoanOutBatchJob implements BatchInvocable {
21 private static ArrayList<String> invocationModes = null;
22 private InvocationContext invocationCtx;
23 private ServiceContext ctx;
24 private int completionStatus;
25 private ResourceMap resourceMap;
26 private InvocationResults results;
27 private InvocationError errorInfo;
28 private final String RELATION_TYPE = "affects";
29 private final String LOAN_DOCTYPE = "LoanOut";
30 private final String RELATION_PREDICATE_DISP = "affects";
31 protected final int CREATED_STATUS = Response.Status.CREATED.getStatusCode();
32 protected final int BAD_REQUEST_STATUS = Response.Status.BAD_REQUEST.getStatusCode();
33 protected final int INT_ERROR_STATUS = Response.Status.INTERNAL_SERVER_ERROR.getStatusCode();
35 public CreateAndLinkLoanOutBatchJob() {
36 CreateAndLinkLoanOutBatchJob.setupClassStatics();
38 completionStatus = STATUS_UNSTARTED;
40 results = new InvocationResults();
44 private static void setupClassStatics() {
45 if(invocationModes == null ) {
46 invocationModes = new ArrayList<String>(1);
47 invocationModes.add(INVOCATION_MODE_SINGLE);
48 invocationModes.add(INVOCATION_MODE_LIST);
53 * @return a set of modes that this plugin can support on invocation. Must be non-empty.
55 public List<String> getSupportedInvocationModes() {
56 return CreateAndLinkLoanOutBatchJob.invocationModes;
60 public void setServiceContext(ServiceContext context) {
65 public ServiceContext getServiceContext() {
70 public InvocationContext getInvocationContext() {
75 * Sets the invocation context for the batch job. Called before run().
76 * @param context an instance of InvocationContext.
79 public void setInvocationContext(InvocationContext context) {
80 this.invocationCtx = context;
84 * Sets the invocation context for the batch job. Called before run().
85 * @param invocationCtx an instance of InvocationContext.
87 public void setResourceMap(ResourceMap resourceMap) {
88 this.resourceMap = resourceMap;
92 * The main work logic of the batch job. Will be called after setContext.
95 completionStatus = STATUS_MIN_PROGRESS;
98 // First, create the Loanout
99 if(createLoan() != STATUS_ERROR) {
100 if(INVOCATION_MODE_SINGLE.equalsIgnoreCase(invocationCtx.getMode())) {
101 if(createRelation(results.getPrimaryURICreated(),
102 invocationCtx.getSingleCSID()) != STATUS_ERROR) {
103 results.setNumAffected(1);
104 results.setUserNote("CreateAndLinkLoanOutBatchJob created new Loanout: "
105 +results.getPrimaryURICreated()+" with a link to the passed "+invocationCtx.getDocType());
106 completionStatus = STATUS_COMPLETE;
108 } else if(INVOCATION_MODE_LIST.equalsIgnoreCase(invocationCtx.getMode())) {
109 InvocationContext.ListCSIDs listWrapper = invocationCtx.getListCSIDs();
110 List<String> csids = listWrapper.getCsid();
111 if(csids.size()==0) {
112 completionStatus = STATUS_ERROR;
113 errorInfo = new InvocationError(BAD_REQUEST_STATUS,
114 "CreateAndLinkLoanOutBatchJob: no CSIDs in list of documents!");
115 results.setUserNote(errorInfo.getMessage());
117 String loanCSID = results.getPrimaryURICreated();
119 for(String csid:csids) {
120 if(createRelation(loanCSID, csid) == STATUS_ERROR) {
126 if(completionStatus!=STATUS_ERROR) {
127 results.setNumAffected(nCreated);
128 results.setUserNote("CreateAndLinkLoanOutBatchJob created new Loanout: "
129 +results.getPrimaryURICreated()+" with "+nCreated+" link(s) to "+invocationCtx.getDocType());
130 completionStatus = STATUS_COMPLETE;
134 } catch(Exception e) {
135 completionStatus = STATUS_ERROR;
136 errorInfo = new InvocationError(INT_ERROR_STATUS,
137 "CreateAndLinkLoanOutBatchJob problem creating new Loanout: "+e.getLocalizedMessage());
138 results.setUserNote(errorInfo.getMessage());
142 private int createLoan() {
143 String newLoanNumber = "NewLoan-"+ GregorianCalendarDateTimeUtils.timestampUTC();
145 String loanoutPayload = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
146 +"<document name=\"loansout\">"
147 +"<ns2:loansout_common xmlns:ns2=\"http://collectionspace.org/services/loanout\""
148 +" xmlns:ns3=\"http://collectionspace.org/services/jaxb\">"
149 +"<loanOutNumber>"+newLoanNumber+"</loanOutNumber>"
150 +"</ns2:loansout_common></document>";
152 // First, create the Loanout
153 // We fetch the resource class by service name
154 NuxeoBasedResource resource = (NuxeoBasedResource) resourceMap.get( LoanoutClient.SERVICE_NAME);
155 Response response = resource.create(resourceMap, null, loanoutPayload);
156 if(response.getStatus() != CREATED_STATUS) {
157 completionStatus = STATUS_ERROR;
158 errorInfo = new InvocationError(INT_ERROR_STATUS,
159 "CreateAndLinkLoanOutBatchJob problem creating new Loanout!");
160 results.setUserNote(errorInfo.getMessage());
162 String newId = CollectionSpaceClientUtils.extractId(response);
163 results.setPrimaryURICreated(newId);
165 return completionStatus;
168 private int createRelation(String loanCSID, String toCSID) {
169 // Now, create the relation that links the input object to the loanout
170 String relationPayload = "<document name=\"relations\">"
171 + "<ns2:relations_common xmlns:ns2=\"http://collectionspace.org/services/relation\""
172 + " xmlns:ns3=\"http://collectionspace.org/services/jaxb\">"
173 + "<subjectCsid>"+loanCSID+"</subjectCsid>"
174 + "<subjectDocumentType>"+LOAN_DOCTYPE+"</subjectDocumentType>"
175 + "<objectCsid>"+toCSID+"</objectCsid>"
176 + "<objectDocumentType>"+invocationCtx.getDocType()+"</objectDocumentType>"
177 + "<relationshipType>"+RELATION_TYPE+"</relationshipType>"
178 + "<predicateDisplayName>"+RELATION_PREDICATE_DISP+"</predicateDisplayName>"
179 + "</ns2:relations_common></document>";
180 NuxeoBasedResource resource = (NuxeoBasedResource) resourceMap.get(RelationClient.SERVICE_NAME);
181 Response response = resource.create(resourceMap, null, relationPayload);
182 if(response.getStatus() != CREATED_STATUS) {
183 completionStatus = STATUS_ERROR;
184 errorInfo = new InvocationError(INT_ERROR_STATUS,
185 "CreateAndLinkLoanOutBatchJob problem creating new relation!");
186 results.setUserNote(errorInfo.getMessage());
188 return completionStatus;
192 * @return one of the STATUS_* constants, or a value from 1-99 to indicate progress.
193 * Implementations need not support partial completion (progress) values, and can transition
194 * from STATUS_MIN_PROGRESS to STATUS_COMPLETE.
196 public int getCompletionStatus() {
197 return completionStatus;
201 * @return information about the batch job actions and results
203 public InvocationResults getResults() {
204 if(completionStatus != STATUS_COMPLETE)
210 * @return a user-presentable note when an error occurs in batch processing. Will only
211 * be called if getCompletionStatus() returns STATUS_ERROR.
213 public InvocationError getErrorInfo() {