]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-5727: Further steps to make this event listener/handler more easily extensible...
authorAron Roberts <aron@socrates.berkeley.edu>
Fri, 14 Dec 2012 01:49:04 +0000 (17:49 -0800)
committerAron Roberts <aron@socrates.berkeley.edu>
Fri, 14 Dec 2012 01:49:04 +0000 (17:49 -0800)
3rdparty/nuxeo/nuxeo-platform-listener/updateobjectlocationonmove/src/main/java/org/collectionspace/services/listener/AbstractUpdateObjectLocationValues.java
3rdparty/nuxeo/nuxeo-platform-listener/updateobjectlocationonmove/src/main/java/org/collectionspace/services/listener/UpdateObjectLocationOnMove.java

index 1df44ebcda1f4ae61605390ef52a8c1cc2b2939b..2dc54ebc9bb2b44b285183fa517cd314a8f10270 100644 (file)
@@ -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<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
@@ -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
index ba33300893617f76bad25cbac82a388cc7df2d64..80ead39adb1a48134a81f56ad8ec8097d957b836 100644 (file)
@@ -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