From: Aron Roberts Date: Fri, 14 Dec 2012 01:49:04 +0000 (-0800) Subject: CSPACE-5727: Further steps to make this event listener/handler more easily extensible... X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=b2e39839b7e5d1b2fae772e9257ab9c1d89e719a;p=tmp%2Fjakarta-migration.git CSPACE-5727: Further steps to make this event listener/handler more easily extensible for implementers who just want to set additional field values, like a movable storage location (crate) value. --- diff --git a/3rdparty/nuxeo/nuxeo-platform-listener/updateobjectlocationonmove/src/main/java/org/collectionspace/services/listener/AbstractUpdateObjectLocationValues.java b/3rdparty/nuxeo/nuxeo-platform-listener/updateobjectlocationonmove/src/main/java/org/collectionspace/services/listener/AbstractUpdateObjectLocationValues.java index 1df44ebcd..2dc54ebc9 100644 --- a/3rdparty/nuxeo/nuxeo-platform-listener/updateobjectlocationonmove/src/main/java/org/collectionspace/services/listener/AbstractUpdateObjectLocationValues.java +++ b/3rdparty/nuxeo/nuxeo-platform-listener/updateobjectlocationonmove/src/main/java/org/collectionspace/services/listener/AbstractUpdateObjectLocationValues.java @@ -36,10 +36,10 @@ public abstract class AbstractUpdateObjectLocationValues implements EventListene 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 " @@ -176,14 +176,33 @@ public abstract class AbstractUpdateObjectLocationValues implements EventListene } } - // 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, @@ -269,7 +288,8 @@ public abstract class AbstractUpdateObjectLocationValues implements EventListene } // 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. @@ -285,17 +305,20 @@ public abstract class AbstractUpdateObjectLocationValues implements EventListene + "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 @@ -317,30 +340,28 @@ public abstract class AbstractUpdateObjectLocationValues implements EventListene 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 alreadyProcessedMovementCsids = new HashSet(); - 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 @@ -348,15 +369,15 @@ public abstract class AbstractUpdateObjectLocationValues implements EventListene // 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; } @@ -377,13 +398,10 @@ public abstract class AbstractUpdateObjectLocationValues implements EventListene } 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; } /** @@ -417,6 +435,14 @@ public abstract class AbstractUpdateObjectLocationValues implements EventListene // 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 diff --git a/3rdparty/nuxeo/nuxeo-platform-listener/updateobjectlocationonmove/src/main/java/org/collectionspace/services/listener/UpdateObjectLocationOnMove.java b/3rdparty/nuxeo/nuxeo-platform-listener/updateobjectlocationonmove/src/main/java/org/collectionspace/services/listener/UpdateObjectLocationOnMove.java index ba3330089..80ead39ad 100644 --- a/3rdparty/nuxeo/nuxeo-platform-listener/updateobjectlocationonmove/src/main/java/org/collectionspace/services/listener/UpdateObjectLocationOnMove.java +++ b/3rdparty/nuxeo/nuxeo-platform-listener/updateobjectlocationonmove/src/main/java/org/collectionspace/services/listener/UpdateObjectLocationOnMove.java @@ -1,13 +1,10 @@ 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 { @@ -15,77 +12,72 @@ public class UpdateObjectLocationOnMove extends AbstractUpdateObjectLocationValu // 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