</test>\r
\r
<!-- Test with a soft-deleted related Movement record -->\r
- <test ID="softDeleteMovement2">\r
+ \r
+ <test ID="softDeleteMovement4">\r
<method>PUT</method>\r
<uri>/cspace-services/movements/${createMovement4.CSID}/workflow/delete</uri>\r
<expectedCodes>200</expectedCodes>\r
<expectedCodes>200</expectedCodes>\r
</test>\r
\r
+ <!-- Test with a soft-deleted CollectionObject record -->\r
+\r
+ <!-- After deleting Movement record 2 outright, the computedCurrentLocation -->\r
+ <!-- value should then be drawn from the currentLocation value of Movement record 1, -->\r
+ <!-- the next most-recent Movement record. -->\r
+ <test ID="deleteMovement2">\r
+ <method>DELETE</method>\r
+ <uri>/cspace-services/movements/${createMovement2.CSID}</uri>\r
+ <expectedCodes>200</expectedCodes>\r
+ </test>\r
+ \r
+ <!-- However, now we soft-delete the CollectionObject record itself. -->\r
+ <test ID="softDeleteCollectionObject">\r
+ <method>PUT</method>\r
+ <uri>/cspace-services/collectionobjects/${createCollectionObject.CSID}/workflow/delete</uri>\r
+ <expectedCodes>200</expectedCodes>\r
+ <filename>relation/res/workflowState.res.xml</filename>\r
+ <vars>\r
+ <var ID="workflowState">deleted</var>\r
+ </vars>\r
+ </test>\r
+ \r
+ <test ID="invokeBatchAfterSoftDeletingCollectionObject" auth="test" autoDeletePOSTS="false">\r
+ <method>POST</method>\r
+ <uri>/cspace-services/batch/${createBatchRecord.CSID}</uri>\r
+ <filename>batch/batch-invoke-updateobjloc-single.xml</filename>\r
+ <vars>\r
+ <var ID="collectionObjectCSID">${createCollectionObject.CSID}</var>\r
+ </vars>\r
+ <expectedCodes>200</expectedCodes>\r
+ </test>\r
+ \r
+ <!-- On re-reading the CollectionObject, its computedCurrentLocation -->\r
+ <!-- value should remain at its value prior to its having been soft-deleted. -->\r
+ <test ID="readUpdatedCollectionObjectRecordAfterSoftDeletion">\r
+ <method>GET</method>\r
+ <uri>/cspace-services/collectionobjects/${createCollectionObject.CSID}</uri>\r
+ <filename>batch/updateobjloc.xml</filename>\r
+ <response>\r
+ <expected level="ADDOK" />\r
+ <filename>batch/res/collectionobject.res.xml</filename>\r
+ <vars>\r
+ <var ID="computedCurrentLocationValue">${createMovement2.currentLocation}</var>\r
+ </vars>\r
+ </response>\r
+ <expectedCodes>200</expectedCodes>\r
+ </test>\r
+ \r
</testGroup>\r
\r
<testGroup ID="invocationModeModeList" autoDeletePOSTS="true">\r
import java.util.List;
import java.util.Set;
import javax.ws.rs.core.PathSegment;
+import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import org.collectionspace.services.batch.AbstractBatchInvocable;
import org.collectionspace.services.client.AbstractCommonListUtils;
import org.collectionspace.services.client.CollectionObjectClient;
import org.collectionspace.services.client.MovementClient;
-import org.collectionspace.services.client.workflow.WorkflowClient;
import org.collectionspace.services.client.PoxPayloadOut;
+import org.collectionspace.services.client.workflow.WorkflowClient;
import org.collectionspace.services.common.ResourceBase;
import org.collectionspace.services.common.ResourceMap;
import org.collectionspace.services.common.api.Tools;
-import org.collectionspace.services.common.invocable.InvocationContext;
import org.collectionspace.services.common.invocable.InvocationResults;
import org.collectionspace.services.jaxb.AbstractCommonList;
import org.dom4j.DocumentException;
public class UpdateObjectLocationBatchJob extends AbstractBatchInvocable {
// FIXME: Where appropriate, get from existing constants rather than local declarations
- private final static String COLLECTIONOBJECTS_COMMON_SCHEMA_NAME = "collectionobjects_common";
private final static String CSID_ELEMENT_NAME = "csid";
private final static String CURRENT_LOCATION_ELEMENT_NAME = "currentLocation";
+ private final static String LIFECYCLE_STATE_ELEMENT_NAME = "currentLifeCycleState";
private final static String LOCATION_DATE_ELEMENT_NAME = "locationDate";
private final static String OBJECT_NUMBER_ELEMENT_NAME = "objectNumber";
+ private final static String WORKFLOW_COMMON_SCHEMA_NAME = "workflow_common";
+ private final static String WORKFLOW_COMMON_NAMESPACE_PREFIX = "ns2";
+ private final static String WORKFLOW_COMMON_NAMESPACE_URI =
+ "http://collectionspace.org/services/workflow";
+ private final static Namespace WORKFLOW_COMMON_NAMESPACE =
+ Namespace.getNamespace(
+ WORKFLOW_COMMON_NAMESPACE_PREFIX,
+ WORKFLOW_COMMON_NAMESPACE_URI);
+ private final static String COLLECTIONOBJECTS_COMMON_SCHEMA_NAME = "collectionobjects_common";
private final static String COLLECTIONOBJECTS_COMMON_NAMESPACE_PREFIX = "ns2";
private final static String COLLECTIONOBJECTS_COMMON_NAMESPACE_URI =
"http://collectionspace.org/services/collectionobject";
Namespace.getNamespace(
COLLECTIONOBJECTS_COMMON_NAMESPACE_PREFIX,
COLLECTIONOBJECTS_COMMON_NAMESPACE_URI);
+ private final static String NONDELETED_QUERY_COMPONENT =
+ "&" + WorkflowClient.WORKFLOW_QUERY_NONDELETED + "=false";
+ private PoxPayloadOut payloadOut;
private final String CLASSNAME = this.getClass().getSimpleName();
private final Logger logger = LoggerFactory.getLogger(this.getClass());
// #################################################################
// Other convenience methods
// #################################################################
-
protected UriInfo createRelatedRecordsUriInfo(String query) throws URISyntaxException {
URI uri = new URI(null, null, null, query, null);
return createUriInfo(uri.getRawQuery());
return value;
}
+ private boolean isRecordDeleted(ResourceBase resource, String collectionObjectCsid) throws URISyntaxException, DocumentException {
+ boolean isDeleted = false;
+ byte[] workflowResponse = resource.getWorkflow(createUriInfo(), collectionObjectCsid);
+ if (workflowResponse != null) {
+ payloadOut = new PoxPayloadOut(workflowResponse);
+ String workflowState =
+ getFieldElementValue(payloadOut, WORKFLOW_COMMON_SCHEMA_NAME,
+ WORKFLOW_COMMON_NAMESPACE, LIFECYCLE_STATE_ELEMENT_NAME);
+ if (Tools.notBlank(workflowState) && workflowState.contentEquals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
+ isDeleted = true;
+ }
+ }
+ return isDeleted;
+ }
+
private InvocationResults updateComputedCurrentLocations(List<String> csids) {
ResourceMap resourcemap = getResourceMap();
String computedCurrentLocation;
String objectNumber;
String movementCsid;
+ PoxPayloadOut payloadOut;
+ String queryString;
int numAffected = 0;
try {
// For each CollectionObject record
for (String collectionObjectCsid : csids) {
- if (recordIsDeleted(collectionObjectCsid)) {
+ // Skip over soft-deleted CollectionObject records
+ if (isRecordDeleted(collectionObjectResource, collectionObjectCsid)) {
+ if (logger.isTraceEnabled()) {
+ logger.trace("Skipping soft-deleted CollectionObject record with CSID " + collectionObjectCsid);
+ }
continue;
}
// Get movement records related to this record where the CollectionObject
// record is the subject of the relation
- // FIXME: Get query string(s) from constant(s)
- String queryString = "rtObj=" + collectionObjectCsid
- + "&" + WorkflowClient.WORKFLOW_QUERY_NONDELETED + "=false";
+ // FIXME: Get query string(s) from constant(s), where appropriate
+ queryString = "rtObj=" + collectionObjectCsid + NONDELETED_QUERY_COMPONENT;
UriInfo uriInfo = createRelatedRecordsUriInfo(queryString);
AbstractCommonList relatedMovements = movementResource.getList(uriInfo);
if (logger.isTraceEnabled()) {
logger.trace("Identified " + relatedMovements.getTotalItems()
- + " Movement records related to the object CollectionObject record " + collectionObjectCsid);
+ + " Movement record(s) related to the object CollectionObject record " + collectionObjectCsid);
}
// Get movement records related to this record where the CollectionObject
// record is the object of the relation
- // FIXME: Get query string(s) from constant(s)
- queryString = "rtSbj=" + collectionObjectCsid
- + "&" + WorkflowClient.WORKFLOW_QUERY_NONDELETED + "=false";
+ // FIXME: Get query string(s) from constant(s), where appropriate
+ queryString = "rtSbj=" + collectionObjectCsid + NONDELETED_QUERY_COMPONENT;
uriInfo = createRelatedRecordsUriInfo(queryString);
AbstractCommonList reverseRelatedMovements = movementResource.getList(uriInfo);
if (logger.isTraceEnabled()) {
logger.trace("Identified " + reverseRelatedMovements.getTotalItems()
- + " Movement records related to the subject CollectionObject record " + collectionObjectCsid);
+ + " Movement record(s) related to the subject CollectionObject record " + collectionObjectCsid);
}
if ((relatedMovements.getTotalItems() == 0) && reverseRelatedMovements.getTotalItems() == 0) {
// Merge the two lists of related movement records
relatedMovements.getListItem().addAll(reverseRelatedMovements.getListItem());
+
+ if (logger.isTraceEnabled()) {
+ logger.trace("Identified a total of " + relatedMovements.getListItem().size()
+ + " Movement record(s) related to the subject CollectionObject record " + collectionObjectCsid);
+ }
// Get the latest movement record from among those, and extract
// its current location value
return getResults();
}
- logger.info("Updated computedCurrentLocation values in " + numAffected + " CollectionObject records.");
+ logger.info("Updated computedCurrentLocation values in " + numAffected + " CollectionObject record(s).");
getResults().setNumAffected(numAffected);
return getResults();
}
-
- private boolean recordIsDeleted(String collectionObjectCsid) {
- return false;
- // throw new UnsupportedOperationException("Not yet implemented");
- }
}