protected final static String COLLECTIONOBJECTS_COMMON_SCHEMA = "collectionobjects_common"; // FIXME: Get from external constant
private final static String COLLECTIONOBJECT_DOCTYPE = "CollectionObject"; // FIXME: Get from external constant
protected final static String COMPUTED_CURRENT_LOCATION_PROPERTY = "computedCurrentLocation"; // FIXME: Create and then get from external constant
- private final static String MOVEMENTS_COMMON_SCHEMA = "movements_common"; // FIXME: Get from external constant
+ protected final static String MOVEMENTS_COMMON_SCHEMA = "movements_common"; // FIXME: Get from external constant
private final static String MOVEMENT_DOCTYPE = MovementConstants.NUXEO_DOCTYPE;
private final static String LOCATION_DATE_PROPERTY = "locationDate"; // FIXME: Get from external constant
- private final static String CURRENT_LOCATION_PROPERTY = "currentLocation"; // FIXME: Get from external constant
+ protected final static String CURRENT_LOCATION_PROPERTY = "currentLocation"; // FIXME: Get from external constant
private final static String ACTIVE_DOCUMENT_WHERE_CLAUSE_FRAGMENT =
"AND (ecm:currentLifeCycleState <> 'deleted') "
+ "AND ecm:isProxy = 0 "
}
}
- // Iterate through the list of CollectionObject CSIDs found
- // and update their location value(s).
+ // Iterate through the list of CollectionObject CSIDs found,
+ // obtain their most recently associated Movement, and update
+ // their relevant field value(s) accordingly.
+ DocumentModel collectionObjectDocModel;
+ DocumentModel mostRecentMovementDocModel;
for (String collectionObjectCsid : collectionObjectCsids) {
if (logger.isTraceEnabled()) {
logger.trace("CollectionObject CSID=" + collectionObjectCsid);
}
- updateAllLocationValues(coreSession, collectionObjectCsid);
+ // Verify that the CollectionObject is retrievable.
+ collectionObjectDocModel = getDocModelFromCsid(coreSession, collectionObjectCsid);
+ if (collectionObjectDocModel == null) {
+ continue;
+ }
+ // Verify that the CollectionObject record is active.
+ if (!isActiveDocument(collectionObjectDocModel)) {
+ continue;
+ }
+ mostRecentMovementDocModel = getMostRecentMovement(coreSession, collectionObjectCsid);
+ if (mostRecentMovementDocModel == null) {
+ continue;
+ }
+ collectionObjectDocModel =
+ updateCollectionObjectValuesFromMovement(collectionObjectDocModel, mostRecentMovementDocModel);
+ coreSession.saveDocument(collectionObjectDocModel);
}
+
}
// FIXME: Generic methods like many of those below might be split off,
}
// FIXME: A quick first pass, using an only partly query-based technique for
- // getting the current location, augmented by procedural code.
+ // getting the most recent Movement record related to a CollectionObject,
+ // augmented by procedural code.
//
// Should be replaced by a more performant method, based entirely, or nearly so,
// on a query.
+ "ORDER BY DOC.collectionspace_core:updatedAt DESC";
*/
/**
- * Returns the computed current location for a CollectionObject.
+ * Returns the most recent Movement record related to a CollectionObject.
+ *
+ * This method currently returns the related Movement record with the latest
+ * (i.e. most recent in time) Location Date field value.
*
* @param session a repository session.
* @param collectionObjectCsid a CollectionObject identifier (CSID)
* @throws ClientException
- * @return the computed current location for the CollectionObject identified
- * by the supplied CSID.
+ * @return the most recent Movement record related to the CollectionObject
+ * identified by the supplied CSID.
*/
- protected static String computeCurrentLocation(CoreSession session, String collectionObjectCsid)
+ protected static DocumentModel getMostRecentMovement(CoreSession session, String collectionObjectCsid)
throws ClientException {
- String computedCurrentLocation = "";
+ DocumentModel mostRecentMovementDocModel = null;
// Get Relation records for Movements related to this CollectionObject.
//
// Some values below are hard-coded for readability, rather than
DocumentModelList relationDocModels = session.query(query);
if (relationDocModels == null || relationDocModels.isEmpty()) {
logger.warn("Unexpectedly found no relations to Movement records to/from to this CollectionObject record.");
- return computedCurrentLocation;
+ return mostRecentMovementDocModel;
} else {
if (logger.isTraceEnabled()) {
logger.trace("Found " + relationDocModels.size() + " relations to Movement records to/from this CollectionObject record.");
}
}
- // Iterate through related movement records, to get the CollectionObject's
- // computed current location from the related Movement record with the
- // most recent location date.
+ // Iterate through related movement records, to find the related
+ // Movement record with the most recent location date.
GregorianCalendar mostRecentLocationDate = EARLIEST_COMPARISON_DATE;
DocumentModel movementDocModel = null;
Set<String> alreadyProcessedMovementCsids = new HashSet<String>();
- String relMovementCsid = "";
- String location = "";
+ String relatedMovementCsid = "";
for (DocumentModel relationDocModel : relationDocModels) {
// Due to the 'OR' operator in the query above, related Movement
// record CSIDs may reside in either the subject or object CSID fields
// of the relation record. Whichever CSID value doesn't match the
// CollectionObject's CSID is inferred to be the related Movement record's CSID.
- relMovementCsid = (String) relationDocModel.getProperty(RELATIONS_COMMON_SCHEMA, SUBJECT_CSID_PROPERTY);
- if (relMovementCsid.equals(collectionObjectCsid)) {
- relMovementCsid = (String) relationDocModel.getProperty(RELATIONS_COMMON_SCHEMA, OBJECT_CSID_PROPERTY);
+ relatedMovementCsid = (String) relationDocModel.getProperty(RELATIONS_COMMON_SCHEMA, SUBJECT_CSID_PROPERTY);
+ if (relatedMovementCsid.equals(collectionObjectCsid)) {
+ relatedMovementCsid = (String) relationDocModel.getProperty(RELATIONS_COMMON_SCHEMA, OBJECT_CSID_PROPERTY);
}
- if (Tools.isBlank(relMovementCsid)) {
+ if (Tools.isBlank(relatedMovementCsid)) {
continue;
}
// Because of the OR clause used in the query above, there may be
// reference the same Movement record, as either the subject
// or object of a relation to the same CollectionObject record;
// we need to filter out those duplicates.
- if (alreadyProcessedMovementCsids.contains(relMovementCsid)) {
+ if (alreadyProcessedMovementCsids.contains(relatedMovementCsid)) {
continue;
} else {
- alreadyProcessedMovementCsids.add(relMovementCsid);
+ alreadyProcessedMovementCsids.add(relatedMovementCsid);
}
if (logger.isTraceEnabled()) {
- logger.trace("Movement CSID=" + relMovementCsid);
+ logger.trace("Movement CSID=" + relatedMovementCsid);
}
- movementDocModel = getDocModelFromCsid(session, relMovementCsid);
+ movementDocModel = getDocModelFromCsid(session, relatedMovementCsid);
if (movementDocModel == null) {
continue;
}
}
if (locationDate.after(mostRecentLocationDate)) {
mostRecentLocationDate = locationDate;
- location = (String) movementDocModel.getProperty(MOVEMENTS_COMMON_SCHEMA, CURRENT_LOCATION_PROPERTY);
- if (Tools.notBlank(location)) {
- computedCurrentLocation = location;
- }
+ mostRecentMovementDocModel = movementDocModel;
}
}
- return computedCurrentLocation;
+ return mostRecentMovementDocModel;
}
/**
// Can be extended by sub-classes to update different/multiple values;
// e.g. values for moveable locations ("crates").
- protected abstract void updateAllLocationValues(CoreSession coreSession, String collectionObjectCsid)
+ /**
+ * Updates a CollectionObject record with selected values from a Movement record.
+ *
+ * @param collectionObjectDocModel a document model for a CollectionObject record.
+ * @param movementDocModel a document model for a Movement record.
+ * @throws ClientException
+ */
+ protected abstract DocumentModel updateCollectionObjectValuesFromMovement(DocumentModel collectionObjectDocModel,
+ DocumentModel movementDocModel)
throws ClientException;
}
\ No newline at end of file
package org.collectionspace.services.listener;
-import java.util.HashMap;
-import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.collectionspace.services.common.api.RefNameUtils;
import org.collectionspace.services.common.api.Tools;
import org.nuxeo.ecm.core.api.ClientException;
-import org.nuxeo.ecm.core.api.CoreSession;
import org.nuxeo.ecm.core.api.DocumentModel;
public class UpdateObjectLocationOnMove extends AbstractUpdateObjectLocationValues {
// FIXME: We might experiment here with using log4j instead of Apache Commons Logging;
// am using the latter to follow Ray's pattern for now
private final Log logger = LogFactory.getLog(UpdateObjectLocationOnMove.class);
-
+
@Override
- protected void updateAllLocationValues(CoreSession coreSession, String collectionObjectCsid)
- throws ClientException {
- updateCurrentLocationValue(coreSession, collectionObjectCsid);
+ protected DocumentModel updateCollectionObjectValuesFromMovement(DocumentModel collectionObjectDocModel,
+ DocumentModel movementDocModel) throws ClientException {
+
+ collectionObjectDocModel = updateComputedCurrentLocationValue(collectionObjectDocModel, movementDocModel);
+ // This method can be overridden and extended by adding or removing method
+ // calls here, to update a custom set of values in the CollectionObject
+ // record by pulling in values from the related Movement record.
+ return collectionObjectDocModel;
}
- private void updateCurrentLocationValue(CoreSession coreSession, String collectionObjectCsid)
+ protected DocumentModel updateComputedCurrentLocationValue(DocumentModel collectionObjectDocModel,
+ DocumentModel movementDocModel)
throws ClientException {
- DocumentModel collectionObjectDocModel;
- String computedCurrentLocationRefName;
- collectionObjectDocModel = getDocModelFromCsid(coreSession, collectionObjectCsid);
- if (collectionObjectDocModel == null) {
- return;
- }
- // Verify that the CollectionObject record is active.
- if (!isActiveDocument(collectionObjectDocModel)) {
- return;
- }
- // Obtain the computed current location of that CollectionObject.
- computedCurrentLocationRefName = computeCurrentLocation(coreSession, collectionObjectCsid);
- if (logger.isTraceEnabled()) {
- logger.trace("computedCurrentLocation refName=" + computedCurrentLocationRefName);
- }
+
+ // Get the current location value from the Movement.
+ String currentLocationRefName =
+ (String) movementDocModel.getProperty(MOVEMENTS_COMMON_SCHEMA, CURRENT_LOCATION_PROPERTY);
// Check that the value returned, which is expected to be a
- // reference (refName) to a storage location authority term,
- // is, at a minimum:
- // * Non-null and non-blank. (We need to verify this assumption; can a
- // CollectionObject's computed current location value ever meaningfully
- // be 'un-set' by returning it to a null value?)
+ // reference (refName) to an authority term (such as a storage
+ // location or organization term) is, at a minimum:
+ //
+ // * Non-null and non-blank.
+ // (Note: we need to verify this assumption; can a CollectionObject's
+ // computed current location value ever meaningfully be 'un-set'
+ // by returning it to a null value?)
+ //
// * Capable of being successfully parsed by an authority item parser;
// that is, returning a non-null parse result.
- if ((Tools.isBlank(computedCurrentLocationRefName)
- || (RefNameUtils.parseAuthorityTermInfo(computedCurrentLocationRefName) == null))) {
- logger.warn("Could not parse computed current location refName '" + computedCurrentLocationRefName + "'");
- return;
+ if ((Tools.isBlank(currentLocationRefName)
+ || (RefNameUtils.parseAuthorityTermInfo(currentLocationRefName) == null))) {
+ logger.warn("Could not parse current location refName '" + currentLocationRefName + "'");
+ return collectionObjectDocModel;
} else {
if (logger.isTraceEnabled()) {
- logger.trace("computed current location refName passes basic validation tests.");
+ logger.trace("current location refName passes basic validation tests.");
+ logger.trace("currentLocation refName=" + currentLocationRefName);
}
}
-
// If the value returned from the function passes validation,
- // compare it to the value in the computedCurrentLocation
- // field of that CollectionObject.
+ // compare it to the value in the computed current location
+ // field of the CollectionObject.
String existingComputedCurrentLocationRefName =
- (String) collectionObjectDocModel.getProperty(COLLECTIONOBJECTS_COMMON_SCHEMA, COMPUTED_CURRENT_LOCATION_PROPERTY);
+ (String) collectionObjectDocModel.getProperty(COLLECTIONOBJECTS_COMMON_SCHEMA,
+ COMPUTED_CURRENT_LOCATION_PROPERTY);
if (logger.isTraceEnabled()) {
logger.trace("Existing computedCurrentLocation refName=" + existingComputedCurrentLocationRefName);
}
+
// If the CollectionObject lacks a computed current location value,
- // or if the new computed value differs from its existing value ...
+ // or if the new value differs from its existing value ...
if (Tools.isBlank(existingComputedCurrentLocationRefName)
- || (!computedCurrentLocationRefName.equals(existingComputedCurrentLocationRefName))) {
+ || (!currentLocationRefName.equals(existingComputedCurrentLocationRefName))) {
if (logger.isTraceEnabled()) {
logger.trace("computedCurrentLocation refName requires updating.");
}
- // ... update that value and then save the updated CollectionObject.
- collectionObjectDocModel.setProperty(COLLECTIONOBJECTS_COMMON_SCHEMA, COMPUTED_CURRENT_LOCATION_PROPERTY, computedCurrentLocationRefName);
- coreSession.saveDocument(collectionObjectDocModel);
- if (logger.isTraceEnabled()) {
- String afterUpdateComputedCurrentLocationRefName =
- (String) collectionObjectDocModel.getProperty(COLLECTIONOBJECTS_COMMON_SCHEMA, COMPUTED_CURRENT_LOCATION_PROPERTY);
- logger.trace("Following update, new computedCurrentLocation refName value=" + afterUpdateComputedCurrentLocationRefName);
-
- }
+ // ... update that value.
+ collectionObjectDocModel.setProperty(COLLECTIONOBJECTS_COMMON_SCHEMA,
+ COMPUTED_CURRENT_LOCATION_PROPERTY, currentLocationRefName);
} else {
if (logger.isTraceEnabled()) {
logger.trace("computedCurrentLocation refName does NOT require updating.");
}
}
+ return collectionObjectDocModel;
}
}
\ No newline at end of file