private final static String MOVEMENT_DOCTYPE = MovementConstants.NUXEO_DOCTYPE;
private final static String LOCATION_DATE_PROPERTY = "locationDate"; // FIXME: Get from external constant
protected final static String CURRENT_LOCATION_PROPERTY = "currentLocation"; // FIXME: Get from external constant
+ protected final static String COLLECTIONSPACE_CORE_SCHEMA = "collectionspace_core"; // FIXME: Get from external constant
+ protected final static String CREATED_AT_PROPERTY = "createdAt"; // FIXME: Get from external constant
private final static String ACTIVE_DOCUMENT_WHERE_CLAUSE_FRAGMENT =
"AND (ecm:currentLifeCycleState <> 'deleted') "
+ "AND ecm:isProxy = 0 "
// Iterate through related movement records, to find the related
// Movement record with the most recent location date.
GregorianCalendar mostRecentLocationDate = EARLIEST_COMPARISON_DATE;
+ // Note: the following value is used to compare any two records, rather
+ // than to identify the most recent value so far encountered. Thus, it may
+ // occasionally be set backward or forward in time, within the loop below.
+ GregorianCalendar comparisonCreationDate = EARLIEST_COMPARISON_DATE;
DocumentModel movementDocModel;
Set<String> alreadyProcessedMovementCsids = new HashSet<>();
String relatedMovementCsid;
}
GregorianCalendar locationDate =
(GregorianCalendar) movementDocModel.getProperty(MOVEMENTS_COMMON_SCHEMA, LOCATION_DATE_PROPERTY);
+ // If the current Movement record lacks a location date, it cannot
+ // be established as the most recent Movement record; skip over it.
if (locationDate == null) {
continue;
}
+ GregorianCalendar creationDate =
+ (GregorianCalendar) movementDocModel.getProperty(COLLECTIONSPACE_CORE_SCHEMA, CREATED_AT_PROPERTY);
if (locationDate.after(mostRecentLocationDate)) {
mostRecentLocationDate = locationDate;
+ if (creationDate != null) {
+ comparisonCreationDate = creationDate;
+ }
mostRecentMovementDocModel = movementDocModel;
+ // If the current Movement record's location date is identical
+ // to that of the (at this time) most recent Movement record, then
+ // instead compare the two records using their creation date values
+ } else if (locationDate.compareTo(mostRecentLocationDate) == 0) {
+ if (creationDate != null && creationDate.after(comparisonCreationDate)) {
+ // The most recent location date value doesn't need to be
+ // updated here, as the two records' values are identical
+ comparisonCreationDate = creationDate;
+ mostRecentMovementDocModel = movementDocModel;
+ }
}
}
return mostRecentMovementDocModel;
<expectedCodes>200</expectedCodes>
</test>
- <test ID="readCollectionObject1AfterMovement3BlankCurrentLocationUpdate">
+ <test ID="readCollectionObject1AfterMovement3NonBlankCurrentLocationUpdate">
<method>GET</method>
<uri>/cspace-services/collectionobjects/${createCollectionObject1.CSID}</uri>
<response>
<expectedCodes>200</expectedCodes>
</test>
- </testGroup>
-
- <!-- Some of the following tests pertain to CSPACE-5793, not yet -->
- <!-- resolved as of this writing. - ADR 2013-02-14 -->
-
- <testGroup ID="TestsStillUnderDevelopment">
+ <!-- CSPACE-6019: A Movement with a later creation timestamp is -->
+ <!-- deemed to have taken place later than a Movement with an earlier -->
+ <!-- creation timestamp, if both have identical location dates. -->
- <test ID="deleteRelationBetweenCollectionObject1AndMovement4">
- <method>DELETE</method>
- <uri>/cspace-services/relations/${relateCollectionObject1ToMovement4.CSID}</uri>
+ <test ID="createMovement6">
+ <method>POST</method>
+ <uri>/cspace-services/movements</uri>
+ <filename>listener/movement.xml</filename>
+ <vars>
+ <var ID="currentLocation">urn:cspace:core.collectionspace.org:locationauthorities:name(offsite_sla):item:name(Spokane1358215545524)'Spokane, WA, USA'</var>
+ <var ID="locationDate">${updateMovement3WithNonBlankCurrentLocation.locationDate}</var> <!-- Identical to Movement 3 -->
+ </vars>
+ <expectedCodes>201</expectedCodes>
+ </test>
+ <test ID="readMovement6">
+ <method>GET</method>
+ <uri>/cspace-services/movements/${createMovement6.CSID}</uri>
+ <response>
+ <expected level="ADDOK" />
+ <filename>listener/res/movement.res.xml</filename>
+ <vars>
+ <var ID="currentLocationValue">${createMovement6.currentLocation}</var>
+ <var ID="locationDateValue">${updateMovement3WithNonBlankCurrentLocation.got("//locationDate")}</var>
+ </vars>
+ </response>
<expectedCodes>200</expectedCodes>
</test>
- <test ID="readCollectionObject1AfterRelationDelete">
+ <test ID="relateCollectionObject1ToMovement6">
+ <method>POST</method>
+ <uri>/cspace-services/relations</uri>
+ <filename>listener/relation.xml</filename>
+ <vars>
+ <var ID="subjectCsid">${createCollectionObject1.CSID}</var>
+ <var ID="subjectDocumentType">CollectionObject</var>
+ <var ID="objectCsid">${createMovement6.CSID}</var>
+ <var ID="objectDocumentType">Movement</var>
+ </vars>
+ <expectedCodes>201</expectedCodes>
+ </test>
+
+ <!-- See comment on updateMovement1 for an explanation of why this -->
+ <!-- update is needed, after creating a new relation -->
+ <test ID="updateMovement6">
+ <method>PUT</method>
+ <uri>/cspace-services/movements/${createMovement6.CSID}</uri>
+ <filename>listener/movement.xml</filename>
+ <vars>
+ <var ID="currentLocation">${createMovement6.currentLocation}</var>
+ <var ID="locationDate">${createMovement6.locationDate}</var>
+ </vars>
+ <expectedCodes>200</expectedCodes>
+ </test>
+
+ <test ID="readCollectionObject1AfterBeingRelatedToMovement6">
<method>GET</method>
<uri>/cspace-services/collectionobjects/${createCollectionObject1.CSID}</uri>
<response>
<expected level="ADDOK" />
<filename>listener/res/collectionobject.res.xml</filename>
<vars>
- <var ID="computedCurrentLocationValue">${createMovement3.currentLocation}</var>
+ <var ID="computedCurrentLocationValue">${createMovement6.currentLocation}</var>
</vars>
</response>
<expectedCodes>200</expectedCodes>
</test>
- <test ID="softDeleteMovement3">
- <method>PUT</method>
- <uri>/cspace-services/movements/${createMovement3.CSID}/workflow/delete</uri>
+ </testGroup>
+
+ <!-- Some of the following tests pertain to CSPACE-5793, not yet -->
+ <!-- resolved as of this writing. - ADR 2013-02-14 -->
+
+ <testGroup ID="TestsStillUnderDevelopment">
+
+ <test ID="deleteRelationBetweenCollectionObject1AndMovement3">
+ <method>DELETE</method>
+ <uri>/cspace-services/relations/${relateCollectionObject1ToMovement3.CSID}</uri>
<expectedCodes>200</expectedCodes>
- <!-- XmlReplay appears to require a filename on PUT. -->
- <!-- If not present, throws "java.io.FileNotFoundException: File '' does not exist" -->
- <!-- The contents of that file, sent in the PUT payload, will be ignored by the services. -->
- <!-- Note that the filename below is in a different module than -->
- <!-- the present XmlReplay control file. -->
- <filename>relation/res/workflowState.res.xml</filename>
- <vars>
- <var ID="workflowState">deleted</var>
- </vars>
</test>
- <test ID="readCollectionObject1AfterMovement3SoftDelete">
+ <test ID="readCollectionObject1AfterRelationDelete">
<method>GET</method>
<uri>/cspace-services/collectionobjects/${createCollectionObject1.CSID}</uri>
<response>