From 67fd04f6fc1e01a1a5d5ced940970a1c5a345605 Mon Sep 17 00:00:00 2001 From: Aron Roberts Date: Thu, 6 Dec 2012 18:41:46 -0800 Subject: [PATCH] CSPACE-5727: Event listener now successfully acquires a list of related CollectionObject / Cataloging records and the computed current location for each. Added trivial method useful when debugging JDBC results to JDBCTools class. --- .../listener/UpdateObjectLocationOnMove.java | 99 ++++++++++++------- .../services/common/storage/JDBCTools.java | 24 ++++- 2 files changed, 87 insertions(+), 36 deletions(-) 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 25f8c3d30..701668134 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 @@ -6,20 +6,23 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.sql.Connection; import java.sql.ResultSet; -import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; +import java.util.List; 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.RefNameUtils; import org.collectionspace.services.common.api.Tools; +import org.collectionspace.services.common.query.QueryContext; import org.collectionspace.services.common.storage.JDBCTools; import org.collectionspace.services.movement.nuxeo.MovementConstants; import org.collectionspace.services.nuxeo.util.NuxeoUtils; import org.nuxeo.ecm.core.api.ClientException; +import org.nuxeo.ecm.core.api.CoreSession; import org.nuxeo.ecm.core.api.DocumentModel; +import org.nuxeo.ecm.core.api.DocumentModelList; import org.nuxeo.ecm.core.event.Event; import org.nuxeo.ecm.core.event.EventContext; import org.nuxeo.ecm.core.event.EventListener; @@ -138,53 +141,88 @@ public class UpdateObjectLocationOnMove implements EventListener { // relations with Movement-as-subject and CollectionObject-as-object; // that may NOT always be the case. - // buildNXQLQuery(List docTypes, QueryContext queryContext); - - // 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: + // The following is boilerplate and may be incorrect: + + CoreSession coreSession = docEventContext.getCoreSession(); + final String RELATION_DOCTYPE = "Relation"; // FIXME: Get from external constant + final String COLLECTIONOBJECT_DOCTYPE = "CollectionObject"; // FIXME: Get from external constant + String query = String.format( + "SELECT * FROM %1$s WHERE " // collectionspace_core:tenantId = 1 " + + "(relations_common:subjectCsid = '%2$s' " + + "AND relations_common:objectDocumentType = '%3$s') " + + "AND (ecm:currentLifeCycleState <> 'deleted') " + + "AND ecm:isProxy = 0 " + + "AND ecm:isCheckedInVersion = 0", RELATION_DOCTYPE, movementCsid, COLLECTIONOBJECT_DOCTYPE); + DocumentModelList relatedDocModels = coreSession.query(query); + if (relatedDocModels == null || relatedDocModels.isEmpty()) { + return; + } else { + logger.debug("Found " + relatedDocModels.size() + " related documents."); + } - ArrayList collectionObjectCsids = new ArrayList(); - collectionObjectCsids.add("5b4c617e-53a0-484b-804e"); // FIXME: Hard-coded for testing + // Iterate through the list of Relation records found and build + // a list of CollectionObject CSIDs, by extracting the object CSIDs + // from those Relation records. + String csid = ""; + final String RELATIONS_COMMON_SCHEMA = "relations_common"; // FIXME: Get from external constant + final String OBJECT_CSID_PROPERTY = "objectCsid"; // FIXME: Get from external constant + List collectionObjectCsids = new ArrayList(); + for (DocumentModel relatedDocModel : relatedDocModels) { + csid = (String) relatedDocModel.getProperty(RELATIONS_COMMON_SCHEMA, OBJECT_CSID_PROPERTY); + if (Tools.notBlank(csid)) { + collectionObjectCsids.add(csid); + } + } + if (collectionObjectCsids == null || collectionObjectCsids.isEmpty()) { + return; + } else { + logger.debug("Found " + collectionObjectCsids.size() + " CollectionObject CSIDs."); + } + // Iterate through the list of CollectionObject CSIDs found. DocumentModel collectionObjectDocModel = null; String computedCurrentLocationRefName = ""; - for (String csid : collectionObjectCsids) { - - // Verify that the CollectionObject record is active (use isActiveDocument(), below). + for (String collectionObjectCsid : collectionObjectCsids) { + // Verify that the CollectionObject record is active. + // Code below untried; likely needs work. /* try { collectionObjectDocModel = NuxeoUtils.getDocFromCsid(null, null, csid); } catch (Exception e) { logger.warn("Exception in getDocFromCsid: ", e); } + if (!isActiveDocument(collectionObjectDocModel)) { + continue; + } + * */ // Via a JDBC call, invoke the SQL function to obtain the computed // current location of that CollectionObject. - computedCurrentLocationRefName = computeCurrentLocation(csid); + computedCurrentLocationRefName = computeCurrentLocation(collectionObjectCsid); logger.debug("computedCurrentLocationRefName=" + computedCurrentLocationRefName); - // 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 and non-blank (need to verify this assumption; can a + // Check that the value returned from this SQL function, 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 meaningfully be 'un-set'?) - // * Capable of being successfully parsed by an authority item parser, - // returning a non-null parse result. + // * Capable of being successfully parsed by an authority item parser; + // that is, returning a non-null parse result. if ((Tools.notBlank(computedCurrentLocationRefName) && (RefNameUtils.parseAuthorityTermInfo(computedCurrentLocationRefName) != null))) { logger.debug("refName passes basic validation tests."); - } - // Compare that returned value to the value in the - // computedCurrentLocation field of that CollectionObject + // If the value returned from the function passes validation, + // compare that value to the value in the computedCurrentLocation + // field of that CollectionObject + // + // If the two values differ, update the CollectionObject record, + // setting the value of the computedCurrentLocation field of that + // CollectionObject record to the value returned from the SQL function. - // If the two values differ, update the CollectionObject record, - // setting the value of the computedCurrentLocation field of that - // CollectionObject record to the value returned from the SQL function. + } } @@ -314,7 +352,7 @@ public class UpdateObjectLocationOnMove implements EventListener { * Cataloging) record. * * @param csid the CSID of a CollectionObject record. - * @return + * @return the computed current location of the CollectionObject record. */ private String computeCurrentLocation(String csid) { String computedCurrentLocation = ""; @@ -403,13 +441,4 @@ public class UpdateObjectLocationOnMove implements EventListener { } return str; } - - public void printResultSet(ResultSet rs) throws SQLException { - ResultSetMetaData metadata = rs.getMetaData(); - int numberOfColumns = metadata.getColumnCount(); - for (int i = 1; i <= numberOfColumns; i++) { - logger.debug(metadata.getColumnName(i)); - logger.debug(metadata.getColumnType(i)); - } - } } \ No newline at end of file diff --git a/services/common/src/main/java/org/collectionspace/services/common/storage/JDBCTools.java b/services/common/src/main/java/org/collectionspace/services/common/storage/JDBCTools.java index c8a622a6a..4325afa11 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/storage/JDBCTools.java +++ b/services/common/src/main/java/org/collectionspace/services/common/storage/JDBCTools.java @@ -30,6 +30,7 @@ import javax.sql.DataSource; import java.sql.DatabaseMetaData; import java.sql.Connection; import java.sql.ResultSet; +import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.util.HashMap; @@ -125,9 +126,14 @@ public class JDBCTools { return result; } + + // Regarding the method below, we might instead identify whether we can + // return a CachedRowSet or equivalent. + // http://docs.oracle.com/javase/1.5.0/docs/api/javax/sql/rowset/CachedRowSet.html + // -- ADR 2012-12-06 /* THIS IS BROKEN - If you close the statement, it closes the ResultSet!!! - public static ResultSet executeQuery(String repoName, String sql) throws Exception { + public static CachedRowSet executeQuery(String repoName, String sql) throws Exception { Connection conn = null; Statement stmt = null; try { @@ -302,5 +308,21 @@ public class JDBCTools { System.out.println("database url=" + metadata.getURL()); } } + + /** + * Prints metadata related to a JDBC ResultSet, such as column names. + * This is a utility method for use during debugging. + * + * @param rs a ResultSet. + * @throws SQLException + */ + public void printResultSetMetaData(ResultSet rs) throws SQLException { + ResultSetMetaData metadata = rs.getMetaData(); + int numberOfColumns = metadata.getColumnCount(); + for (int i = 1; i <= numberOfColumns; i++) { + logger.debug(metadata.getColumnName(i)); + // Insert other debug statements to retrieve additional per-column metadata here ... + } + } } -- 2.47.3