From: Aron Roberts Date: Thu, 6 Dec 2012 00:33:00 +0000 (-0800) Subject: CSPACE-5727: Added resource directory for storing CollectionObject-related SQL code... X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=5e3b5504eb2423754f9063938ba9af75e90a368a;p=tmp%2Fjakarta-migration.git CSPACE-5727: Added resource directory for storing CollectionObject-related SQL code. Initial pass at pseudocode for updating the non-normalized lastIdentifiedLocation field in CollectionObject records via an event listener, using a SQL function to obtain the value to go into that field. --- 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 39078782e..0b6b6914f 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 @@ -3,6 +3,7 @@ package org.collectionspace.services.listener; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.collectionspace.services.client.workflow.WorkflowClient; +import org.collectionspace.services.common.api.Tools; import org.collectionspace.services.movement.nuxeo.MovementConstants; import org.nuxeo.ecm.core.api.ClientException; import org.nuxeo.ecm.core.api.DocumentModel; @@ -20,7 +21,7 @@ public class UpdateObjectLocationOnMove implements EventListener { @Override public void handleEvent(Event event) throws ClientException { - logger.info("In handleEvent in UpdateObjectLocationOnMove ..."); + logger.trace("In handleEvent in UpdateObjectLocationOnMove ..."); EventContext eventContext = event.getContext(); if (eventContext == null) { @@ -28,28 +29,110 @@ public class UpdateObjectLocationOnMove implements EventListener { } DocumentEventContext docEventContext = (DocumentEventContext) eventContext; DocumentModel docModel = docEventContext.getSourceDocument(); - logger.debug("docType=" + docModel.getType()); - if (docModel.getType().startsWith(MovementConstants.NUXEO_DOCTYPE) - && isActiveDocument(docModel)) { - logger.info("A create or update event for an active Movement document was received by UpdateObjectLocationOnMove ..."); + if (isMovementDocument(docModel) && isActiveDocument(docModel)) { + logger.debug("A create or update event for an active Movement document was received by UpdateObjectLocationOnMove ..."); + + // Pseudocode: + + // Use a JDBC call to test whether a SQL function exists to + // supply the last identified location of a CollectionObject. + // If it does not, bail. + + // At the moment, that function is named lastIdentifiedLocation(), + // resides in the resources of the collectionobject.services module, + // and will be created in the database via the Ant 'create_nuxeo_db' + // target. + // + // For now, assume this function will exist in the 'nuxeo' database; + // future work to create per-tenant repositories will likely require that + // our JDBC statements connect to the appropriate tenant-specific database. + + // Get this Movement record's CSID via the document model. + + // Find every CollectionObject record related to this Movement record: + // + // Via an NXQL query, get a list of (non-deleted) relation records where: + // * This movement record's CSID is the subject CSID of the relation. + // * The object document type is a CollectionObject doctype. + + // Iterate through that list of Relation records and build a list of + // CollectionObject CSIDs, by extracting the object CSIDs of those records. + + // For each such CollectionObject: + + // Verify that the CollectionObject record is active (use isActiveDocument(), below). + + // Via a JDBC call, invoke the SQL function to supply the last + // identified location of that CollectionObject, giving it the CSID + // of the CollectionObject record as an argument. + + // Check that the SQL function's returned value, which is expected + // to be a reference (refName) to a storage location authority term, + // is at a minimum: + // * Non-null + // * Capable of being successfully parsed by an authority item parser, + // returning a non-null parse result. + + // Compare that returned value to the value in the + // lastIdentifiedLocation field of that CollectionObject + + // If the two values differ, update the CollectionObject record, + // setting the value of the lastIdentifiedLocation field of that + // CollectionObject record to the value returned from the SQL function. } } /** - * Identifies whether a document is an active document; that is, if - * it is not a versioned record; not a proxy (symbolic link to an - * actual record); and not in the 'deleted' workflow state. + * Identifies whether a document is a Movement document * - * (A note relating the latter: Nuxeo appears to send 'documentModified' events - * even on workflow transitions, such when records are 'soft deleted' by being - * transitioned to the 'deleted' workflow state.) + * @param docModel a document model + * @return true if the document is a Movement document; false if it is not. + */ + private boolean isMovementDocument(DocumentModel docModel) { + return documentMatchesType(docModel, MovementConstants.NUXEO_DOCTYPE); + } + + // FIXME: Generic methods like the following might be split off + // into an event utilities class. - ADR 2012-12-05 + + // FIXME: Identify whether the equivalent of this utility method is + // already implemented and substitute a call to the latter if so. + + /** + * Identifies whether a document matches a supplied document type. + * + * @param docModel a document model. + * @param docType a document type string. + * @return true if the document matches the supplied document type; false if it does not. + */ + private boolean documentMatchesType(DocumentModel docModel, String docType) { + if (docModel == null || Tools.isBlank(docType)) { + return false; + } + if (docModel.getType().startsWith(docType)) { + return true; + } else { + return false; + } + } + + /** + * Identifies whether a document is an active document; that is, if it is + * not a versioned record; not a proxy (symbolic link to an actual record); + * and not in the 'deleted' workflow state. + * + * (A note relating the latter: Nuxeo appears to send 'documentModified' + * events even on workflow transitions, such when records are 'soft deleted' + * by being transitioned to the 'deleted' workflow state.) * * @param docModel - * @return true if the document is an active document; false if it - * is not. + * @return true if the document is an active document; false if it is not. */ private boolean isActiveDocument(DocumentModel docModel) { + if (docModel == null) { + return false; + } boolean isActiveDocument = false; try { if (!docModel.isVersion() diff --git a/services/collectionobject/service/src/main/resources/db/mysql/collectionobject.sql b/services/collectionobject/service/src/main/resources/db/mysql/collectionobject.sql new file mode 100644 index 000000000..52a328055 --- /dev/null +++ b/services/collectionobject/service/src/main/resources/db/mysql/collectionobject.sql @@ -0,0 +1,3 @@ +-- File intentionally empty +-- Can add SQL commands for CollectionObject-related database setup +-- in MySQL below. diff --git a/services/collectionobject/service/src/main/resources/db/postgresql/collectionobject.sql b/services/collectionobject/service/src/main/resources/db/postgresql/collectionobject.sql new file mode 100644 index 000000000..59a98c7da --- /dev/null +++ b/services/collectionobject/service/src/main/resources/db/postgresql/collectionobject.sql @@ -0,0 +1,24 @@ +CREATE OR REPLACE FUNCTION lastidentifiedlocation(character varying) RETURNS character varying + AS 'select m.currentlocation as lastidentifiedlocation +from movements_common m, +hierarchy h1, +relations_common r, +hierarchy h2, +collectionobjects_common c, +misc misc +where m.id=h1.id +and r.subjectcsid=h1.name +and r.subjectdocumenttype=''Movement'' +and r.objectdocumenttype=''CollectionObject'' +and r.objectcsid=h2.name +and h2.id=c.id +and misc.id = c.id +and misc.lifecyclestate <> ''deleted'' +and m.currentlocation is not null +and m.locationdate is not null +and h2.name=$1 +order by m.locationdate desc,row_number() over(order by locationdate) +limit 1' +LANGUAGE SQL + IMMUTABLE + RETURNS NULL ON NULL INPUT;