From: remillet Date: Sat, 4 Feb 2017 00:04:44 +0000 (-0800) Subject: NOJIRA: Refactored much of the event handler that updates a cataloging record's Compu... X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=e21f1a56741de999a1a30fb9a0d2aca74da76032;p=tmp%2Fjakarta-migration.git NOJIRA: Refactored much of the event handler that updates a cataloging record's Computed Current Location field. --- diff --git a/3rdparty/nuxeo/nuxeo-platform-listener/updateobjectlocationonmove/pom.xml b/3rdparty/nuxeo/nuxeo-platform-listener/updateobjectlocationonmove/pom.xml index 1c9c4e940..a473cc341 100644 --- a/3rdparty/nuxeo/nuxeo-platform-listener/updateobjectlocationonmove/pom.xml +++ b/3rdparty/nuxeo/nuxeo-platform-listener/updateobjectlocationonmove/pom.xml @@ -32,6 +32,16 @@ org.collectionspace.services.client ${project.version} + + org.collectionspace.services + org.collectionspace.services.location.client + ${project.version} + + + org.collectionspace.services + org.collectionspace.services.collectionobject.service + ${project.version} + 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 772469da8..849b64a08 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 @@ -1,15 +1,19 @@ package org.collectionspace.services.listener; +import java.util.Calendar; import java.util.GregorianCalendar; import java.util.HashSet; +import java.util.Locale; import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.collectionspace.services.client.AbstractCommonListUtils; +import org.collectionspace.services.client.LocationAuthorityClient; import org.collectionspace.services.client.workflow.WorkflowClient; +import org.collectionspace.services.collectionobject.nuxeo.CollectionObjectConstants; import org.collectionspace.services.common.api.Tools; -import org.collectionspace.services.common.api.Tools.NoRelatedRecordsException; +import org.collectionspace.services.common.relation.nuxeo.RelationConstants; +import org.collectionspace.services.common.api.RefName; import org.collectionspace.services.movement.nuxeo.MovementConstants; import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface; import org.collectionspace.services.nuxeo.client.java.CoreSessionWrapper; @@ -22,7 +26,6 @@ import org.nuxeo.ecm.core.api.event.DocumentEventTypes; import org.nuxeo.ecm.core.api.impl.DocumentModelImpl; import org.nuxeo.ecm.core.api.impl.DocumentModelListImpl; import org.nuxeo.ecm.core.event.Event; -import org.nuxeo.ecm.core.event.EventContext; import org.nuxeo.ecm.core.event.EventListener; import org.nuxeo.ecm.core.event.impl.DocumentEventContext; @@ -31,27 +34,38 @@ public abstract class AbstractUpdateObjectLocationValues implements EventListene // 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 static Log logger = LogFactory.getLog(AbstractUpdateObjectLocationValues.class); + // FIXME: Make the following message, or its equivalent, a constant usable by all event listeners private final static String NO_FURTHER_PROCESSING_MESSAGE = "This event listener will not continue processing this event ..."; + private final static GregorianCalendar EARLIEST_COMPARISON_DATE = new GregorianCalendar(1600, 1, 1); private final static String RELATIONS_COMMON_SCHEMA = "relations_common"; // FIXME: Get from external constant - private final static String RELATION_DOCTYPE = "Relation"; // FIXME: Get from external constant + + private final static String COLLECTIONOBJECT_DOCTYPE = CollectionObjectConstants.NUXEO_DOCTYPE; + private final static String RELATION_DOCTYPE = RelationConstants.NUXEO_DOCTYPE;//"Relation"; // FIXME: Get from external constant + private final static String MOVEMENT_DOCTYPE = MovementConstants.NUXEO_DOCTYPE; + private final static String SUBJECT_CSID_PROPERTY = "subjectCsid"; // FIXME: Get from external constant private final static String OBJECT_CSID_PROPERTY = "objectCsid"; // FIXME: Get from external constant private final static String SUBJECT_DOCTYPE_PROPERTY = "subjectDocumentType"; // FIXME: Get from external constant private final static String OBJECT_DOCTYPE_PROPERTY = "objectDocumentType"; // FIXME: Get from external constant 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 CURRENT_LOCATION_ELEMENT_NAME = "currentLocation"; // From movement_commons schema. FIXME: Get from external constant that already exists 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 protected final static String CURRENT_LOCATION_PROPERTY = "currentLocation"; // FIXME: Get from external constant protected final static String COLLECTIONSPACE_CORE_SCHEMA = "collectionspace_core"; // FIXME: Get from external constant protected final static String CREATED_AT_PROPERTY = "createdAt"; // FIXME: Get from external constant protected final static String UPDATED_AT_PROPERTY = "updatedAt"; // FIXME: Get from external constant + + // Use this meta URN/refname to mark computed locations that are indeterminate + private final static String INDETERMINATE_ID = "indeterminate"; + protected final static String INDETERMINATE_LOCATION = RefName.buildAuthorityItem(INDETERMINATE_ID, LocationAuthorityClient.SERVICE_NAME, INDETERMINATE_ID, + INDETERMINATE_ID, "~Indeterminate Location~").toString(); + + // SQL clauses private final static String NONVERSIONED_NONPROXY_DOCUMENT_WHERE_CLAUSE_FRAGMENT = "AND ecm:isCheckedInVersion = 0" + " AND ecm:isProxy = 0 "; @@ -62,98 +76,91 @@ public abstract class AbstractUpdateObjectLocationValues implements EventListene public enum EventNotificationDocumentType { // Document type about which we've received a notification - MOVEMENT, RELATION; + MOVEMENT, RELATION, COLLECTIONOBJECT; + } + + private static void dumpEvent(Event event, String message) { + if (logger.isDebugEnabled()) { + DocumentEventContext docEventContext = (DocumentEventContext) event.getContext(); + DocumentModel docModel = docEventContext.getSourceDocument(); + String eventType = event.getName(); + String csid = NuxeoUtils.getCsid(docModel); + + logger.debug(String.format("### %s:", message != null ? message : "Unspecified")); + logger.debug(String.format("### \t-Event type: %s", eventType)); + + logger.debug("### \t-Target documment:"); + logger.debug(String.format("### \t\tCSID=%s", csid)); + logger.debug(String.format("### \t\tDocType=%s", docModel.getDocumentType().getName())); + + if (documentMatchesType(docModel, RELATION_DOCTYPE)) { + String subjectDocType = (String) docModel.getProperty(RELATIONS_COMMON_SCHEMA, SUBJECT_DOCTYPE_PROPERTY); + String objectDocType = (String) docModel.getProperty(RELATIONS_COMMON_SCHEMA, OBJECT_DOCTYPE_PROPERTY); + String subjectCsid = (String) docModel.getProperty(RELATIONS_COMMON_SCHEMA, SUBJECT_CSID_PROPERTY); + String objectCsid = (String) docModel.getProperty(RELATIONS_COMMON_SCHEMA, OBJECT_CSID_PROPERTY); + logger.debug(String.format("\tRelation info subject=%s:%s\tobject=%s:%s", + subjectCsid, subjectDocType, objectCsid, objectDocType)); + } else if (documentMatchesType(docModel, MOVEMENT_DOCTYPE)) { + String currentLocation = (String) docModel.getProperty(MOVEMENTS_COMMON_SCHEMA, CURRENT_LOCATION_ELEMENT_NAME); + GregorianCalendar locationDate = (GregorianCalendar) docModel.getProperty(MOVEMENTS_COMMON_SCHEMA, LOCATION_DATE_PROPERTY); + logger.debug("### \t-Movement Info:"); + logger.debug(String.format("### \t\tCSID=%s", csid)); + logger.debug(String.format("### \t\tlocation=%s", currentLocation != null ? currentLocation : "null")); + if (locationDate != null) { + logger.debug(String.format("### \t\tdate=%1$tm-%1$te-%1$tY", locationDate != null ? locationDate : "")); + } else { + logger.debug(String.format("### \t\tdate=")); + } + } else { + logger.debug(String.format("### Ignoring Update Location event: %s", eventType)); + } + } } @Override public void handleEvent(Event event) throws ClientException { - - boolean isAboutToBeRemovedEvent = false; - String movementCsidToFilter = ""; - String eventType = ""; - - logger.trace("In handleEvent in UpdateObjectLocationOnMove ..."); - - EventContext eventContext = event.getContext(); - if (eventContext == null) { + dumpEvent(event, "Update Location"); + // Ensure we have all the event data we need to proceed. + if (event.getContext() == null || !(event.getContext() instanceof DocumentEventContext)) { return; } - if (!(eventContext instanceof DocumentEventContext)) { - return; - } - DocumentEventContext docEventContext = (DocumentEventContext) eventContext; - DocumentModel docModel = docEventContext.getSourceDocument(); + DocumentEventContext docEventContext = (DocumentEventContext) event.getContext(); + DocumentModel eventDocModel = docEventContext.getSourceDocument(); + String eventType = event.getName(); + boolean isAboutToBeRemovedEvent = eventType.equals(DocumentEventTypes.ABOUT_TO_REMOVE); - eventType = event.getName(); - if (logger.isTraceEnabled()) { - logger.trace("A(n) " + eventType + " event was received by UpdateObjectLocationOnMove ..."); - } - if (eventType.equals(DocumentEventTypes.ABOUT_TO_REMOVE)) { - isAboutToBeRemovedEvent = true; - } - - // If this document event involves a Relation record, does this pertain to - // a relationship between a Movement record and a CollectionObject record? // - // If not, we're not interested in processing this document event - // in this event handler, as it will have no bearing on updating a - // computed current location for a CollectionObject. - + // Ensure this event relates to a relationship record (between cataloging and movement records) or a movement record. If so, get the CSID + // of the corresponding movement record. Otherwise, exit. // - // (The rest of the code flow below is then identical to that which - // is followed when this document event involves a Movement record.) - String movementCsid = ""; + String eventMovementCsid = null; Enum notificationDocumentType; - if (documentMatchesType(docModel, RELATION_DOCTYPE)) { - if (logger.isTraceEnabled()) { - logger.trace("An event involving a Relation document was received by UpdateObjectLocationOnMove ..."); - } - // Get a Movement CSID from the Relation record. - // - // If we can't get it - if this Relation doesn't involve a - // Movement - then we don't have a pertinent relation record - // that can be processed by this event listener / handler.) - movementCsid = getCsidForDesiredDocTypeFromRelation(docModel, MOVEMENT_DOCTYPE, COLLECTIONOBJECT_DOCTYPE); - if (Tools.isBlank(movementCsid)) { - logger.warn("Could not obtain CSID for Movement record from document event."); - logger.warn(NO_FURTHER_PROCESSING_MESSAGE); + if (documentMatchesType(eventDocModel, RELATION_DOCTYPE)) { + notificationDocumentType = EventNotificationDocumentType.RELATION; + // Ensure this relationship record is a CollectionObject/Movement tuple. + eventMovementCsid = getCsidForDesiredDocTypeFromRelation(eventDocModel, MOVEMENT_DOCTYPE, COLLECTIONOBJECT_DOCTYPE); + if (Tools.isBlank(eventMovementCsid)) { return; } - // If this Relation record is about to be (hard) deleted, set aside - // the CSID for the Movement record to which it pertains, so it can - // be filtered out in all subsequent processing of the pertinent - // Cataloging record's computed current location. - if (isAboutToBeRemovedEvent) { - movementCsidToFilter = movementCsid; - } - notificationDocumentType = EventNotificationDocumentType.RELATION; - } else if (documentMatchesType(docModel, MOVEMENT_DOCTYPE)) { + } else if (documentMatchesType(eventDocModel, MOVEMENT_DOCTYPE)) { + notificationDocumentType = EventNotificationDocumentType.MOVEMENT; // Otherwise, get a Movement CSID directly from the Movement record. - if (logger.isTraceEnabled()) { - logger.trace("An event involving a Movement document was received by UpdateObjectLocationOnMove ..."); - } - // FIXME: exclude update events for Movement records here, if we can - // identify that we'll still be properly handling update events - // that include a relations list as part of the update payload, - // perhaps because that may trigger a separate event notification. - movementCsid = NuxeoUtils.getCsid(docModel); - if (Tools.isBlank(movementCsid)) { + eventMovementCsid = NuxeoUtils.getCsid(eventDocModel); + if (Tools.isBlank(eventMovementCsid)) { logger.warn("Could not obtain CSID for Movement record from document event."); logger.warn(NO_FURTHER_PROCESSING_MESSAGE); return; } - // If this Movement record is about to be (hard) deleted, set aside - // its CSID so it can be filtered out in all subsequent processing - // of the pertinent Cataloging record's computed current location. - if (isAboutToBeRemovedEvent) { - movementCsidToFilter = movementCsid; - } - notificationDocumentType = EventNotificationDocumentType.MOVEMENT; + } else if (documentMatchesType(eventDocModel, COLLECTIONOBJECT_DOCTYPE) && + eventType.equals(DocumentEventTypes.DOCUMENT_UPDATED)) { + // + // This ensures we resolve "stale" location values by recomputing the current location + // when a cataloging records gets updated. Stale location values can and do occur for a variety of reasons. + // + notificationDocumentType = EventNotificationDocumentType.COLLECTIONOBJECT; } else { - if (logger.isTraceEnabled()) { - logger.trace("This event did not involve a document relevant to UpdateObjectLocationOnMove ..."); - } + // We don't need to handle this event. return; } @@ -172,91 +179,72 @@ public abstract class AbstractUpdateObjectLocationValues implements EventListene // scope to handle only transitions into the 'soft deleted' state, // we can add additional checks for doing so at this point in the code. - // For debugging - if (logger.isTraceEnabled()) { - logger.trace("Movement CSID=" + movementCsid); - logger.trace("Notification document type=" + notificationDocumentType.name()); - } - - // All Nuxeo sessions that get passed around to CollectionSpace code need to be - // wrapped inside of a CoreSessionWrapper - CoreSessionInterface coreSession = new CoreSessionWrapper(docEventContext.getCoreSession()); + // + // Get a list of all the CollectionObject records affected by this event. + // + CoreSessionInterface session = new CoreSessionWrapper(docEventContext.getCoreSession()); // NOTE: All Nuxeo sessions that get passed around to CollectionSpace code need to be wrapped inside of a CoreSessionWrapper Set collectionObjectCsids = new HashSet<>(); - if (notificationDocumentType == EventNotificationDocumentType.RELATION) { - String relatedCollectionObjectCsid = - getCsidForDesiredDocTypeFromRelation(docModel, COLLECTIONOBJECT_DOCTYPE, MOVEMENT_DOCTYPE); + String relatedCollectionObjectCsid = getCsidForDesiredDocTypeFromRelation(eventDocModel, COLLECTIONOBJECT_DOCTYPE, MOVEMENT_DOCTYPE); collectionObjectCsids.add(relatedCollectionObjectCsid); } else if (notificationDocumentType == EventNotificationDocumentType.MOVEMENT) { - collectionObjectCsids.addAll(getCollectionObjectCsidsRelatedToMovement(movementCsid, coreSession)); + collectionObjectCsids.addAll(getCollectionObjectCsidsRelatedToMovement(eventMovementCsid, session)); + } else if (notificationDocumentType == EventNotificationDocumentType.COLLECTIONOBJECT) { + collectionObjectCsids.add(NuxeoUtils.getCsid(eventDocModel)); + } else { + // This event did not involve a document relevant to us. + return; } - if (collectionObjectCsids.isEmpty()) { - if (logger.isTraceEnabled()) { - logger.trace("Could not obtain any CSIDs of related CollectionObject records."); - logger.trace(NO_FURTHER_PROCESSING_MESSAGE); - } + // + // If we found no collectionobject records needing updating, then we're done. + // + if (collectionObjectCsids.isEmpty() == true) { return; - } else { - if (logger.isTraceEnabled()) { - logger.trace("Found " + collectionObjectCsids.size() + " CSID(s) of related CollectionObject records."); - } } - // Iterate through the list of CollectionObject CSIDs found. - // For each CollectionObject, obtain its most recent, related Movement, - // and update relevant field(s) with values from that Movement record. + + // + // Now iterate through the list of affected CollectionObjects found. + // For each CollectionObject, obtain its most recent, related Movement record, + // and update update the Computed Current Location field if needed. + // DocumentModel collectionObjectDocModel; DocumentModel mostRecentMovementDocModel; - for (String collectionObjectCsid : collectionObjectCsids) { - if (logger.isTraceEnabled()) { - logger.trace("CollectionObject CSID=" + collectionObjectCsid); + for (String collectionObjectCsid : collectionObjectCsids) { + collectionObjectDocModel = getCurrentDocModelFromCsid(session, collectionObjectCsid); + if (isActiveDocument(collectionObjectDocModel) == true) { + // + // Get the CollectionObject's most recent, valid related Movement to use for computing the + // object's current location. + // + String mostRecentLocation = getMostRecentMovement(event, session, collectionObjectCsid, + isAboutToBeRemovedEvent, eventMovementCsid); + // + // Update the CollectionObject's Computed Current Location field with the Movement record's location + // + boolean didLocationChange = updateCollectionObjectLocation(collectionObjectDocModel, mostRecentLocation); + + // + // If the location changed, save/persist the change to the repository and log the change. + // + if (didLocationChange == true) { + session.saveDocument(collectionObjectDocModel); + // + // Log an INFO message if we've changed the cataloging record's location + // + if (logger.isInfoEnabled()) { + String computedCurrentLocationRefName = + (String) collectionObjectDocModel.getProperty(COLLECTIONOBJECTS_COMMON_SCHEMA, COMPUTED_CURRENT_LOCATION_PROPERTY); + logger.info(String.format("Updating cataloging record=%s current location to %s", + NuxeoUtils.getCsid(collectionObjectDocModel), computedCurrentLocationRefName)); + } + } } - // Verify that the CollectionObject is both retrievable and active. - collectionObjectDocModel = getCurrentDocModelFromCsid(coreSession, collectionObjectCsid); - if (collectionObjectDocModel == null) { - if (logger.isTraceEnabled()) { - logger.trace("CollectionObject is not current (i.e. is a non-current version), is a proxy, or is unretrievable."); - } - continue; - } - // Verify that the CollectionObject record is active. - if (!isActiveDocument(collectionObjectDocModel)) { - if (logger.isTraceEnabled()) { - logger.trace("CollectionObject is inactive (i.e. deleted or in an otherwise inactive lifestyle state)."); - } - continue; - } - // Get the CollectionObject's most recent, related Movement. - - try { - mostRecentMovementDocModel = getMostRecentMovement(coreSession, collectionObjectCsid, - isAboutToBeRemovedEvent, movementCsidToFilter); - if (mostRecentMovementDocModel == null) { - // This means we couldn't figure out which Movement record to use. - continue; - } - } catch (NoRelatedRecordsException e) { - // This means there were NO active Movement records to use. - mostRecentMovementDocModel = new DocumentModelImpl(MOVEMENT_DOCTYPE); // Create an empty document model - } - - // Update the CollectionObject with values from that Movement. - collectionObjectDocModel = - updateCollectionObjectValuesFromMovement(collectionObjectDocModel, mostRecentMovementDocModel); - if (logger.isTraceEnabled()) { - String computedCurrentLocationRefName = - (String) collectionObjectDocModel.getProperty(COLLECTIONOBJECTS_COMMON_SCHEMA, - COMPUTED_CURRENT_LOCATION_PROPERTY); - logger.trace("computedCurrentLocation refName after value update=" + computedCurrentLocationRefName); - } - - coreSession.saveDocument(collectionObjectDocModel); } } /** - * Returns the CSIDs of CollectionObject records that are related to a - * Movement record. + * Returns the CSIDs of active CollectionObject records related to a Movement record. * * @param movementCsid the CSID of a Movement record. * @param coreSession a repository session. @@ -289,13 +277,12 @@ public abstract class AbstractUpdateObjectLocationValues implements EventListene + ")" + ACTIVE_DOCUMENT_WHERE_CLAUSE_FRAGMENT, RELATION_DOCTYPE, RELATIONS_COMMON_SCHEMA, movementCsid, COLLECTIONOBJECT_DOCTYPE); + DocumentModelList relationDocModels = coreSession.query(query); if (relationDocModels == null || relationDocModels.isEmpty()) { - // Encountering a Movement record that is not related to any - // CollectionObject is potentially a normal occurrence, so no - // error messages are logged here when we stop handling this event. return csids; } + // Iterate through the list of Relation records found and build // a list of CollectionObject CSIDs, by extracting the relevant CSIDs // from those Relation records. @@ -306,6 +293,7 @@ public abstract class AbstractUpdateObjectLocationValues implements EventListene csids.add(csid); } } + return csids; } @@ -335,6 +323,10 @@ public abstract class AbstractUpdateObjectLocationValues implements EventListene } } + protected static boolean isActiveDocument(DocumentModel docModel) { + return isActiveDocument(docModel, false, null); + } + /** * Identifies whether a document is an active document; currently, whether * it is not in a 'deleted' workflow state. @@ -342,18 +334,27 @@ public abstract class AbstractUpdateObjectLocationValues implements EventListene * @param docModel * @return true if the document is an active document; false if it is not. */ - protected static boolean isActiveDocument(DocumentModel docModel) { - if (docModel == null) { - return false; - } + protected static boolean isActiveDocument(DocumentModel docModel, boolean isAboutToBeRemovedEvent, String aboutToBeRemovedCsid) { boolean isActiveDocument = false; - try { - if (!docModel.getCurrentLifeCycleState().contains(WorkflowClient.WORKFLOWSTATE_DELETED)) { - isActiveDocument = true; - } - } catch (ClientException ce) { - logger.warn("Error while identifying whether document is an active document: ", ce); + + if (docModel != null) { + try { + if (!docModel.getCurrentLifeCycleState().contains(WorkflowClient.WORKFLOWSTATE_DELETED)) { + isActiveDocument = true; + } + } catch (ClientException ce) { + logger.warn("Error while identifying whether document is an active document: ", ce); + } + // + // If doc model is the target of the "aboutToBeRemoved" event, mark it as not active. + // + if (isAboutToBeRemovedEvent && Tools.notBlank(aboutToBeRemovedCsid)) { + if (NuxeoUtils.getCsid(docModel).equalsIgnoreCase(aboutToBeRemovedCsid)) { + isActiveDocument = false; + } + } } + return isActiveDocument; } @@ -371,6 +372,7 @@ public abstract class AbstractUpdateObjectLocationValues implements EventListene */ protected static DocumentModel getCurrentDocModelFromCsid(CoreSessionInterface session, String collectionObjectCsid) { DocumentModelList docModelList = null; + try { final String query = "SELECT * FROM " + NuxeoUtils.BASE_DOCUMENT_TYPE @@ -382,15 +384,31 @@ public abstract class AbstractUpdateObjectLocationValues implements EventListene } catch (Exception e) { logger.warn("Exception in query to get active document model for CollectionObject: ", e); } + if (docModelList == null || docModelList.isEmpty()) { logger.warn("Could not get active document models for CollectionObject(s)."); return null; } else if (docModelList.size() != 1) { - logger.debug("Found more than 1 active document with CSID=" + collectionObjectCsid); + logger.error("Found more than 1 active document with CSID=" + collectionObjectCsid); return null; } + return docModelList.get(0); } + + // + // Returns true if this event is for the creation of a new relationship record + // + private static boolean isCreatingNewRelationship(Event event) { + boolean result = false; + + DocumentModel docModel = ((DocumentEventContext)event.getContext()).getSourceDocument(); + if (event.getName().equals(DocumentEventTypes.DOCUMENT_CREATED) && documentMatchesType(docModel, RELATION_DOCTYPE)) { + result = true; + } + + return result; + } // FIXME: A quick first pass, using an only partly query-based technique for // getting the most recent Movement record related to a CollectionObject, @@ -426,14 +444,18 @@ public abstract class AbstractUpdateObjectLocationValues implements EventListene * @return the most recent Movement record related to the CollectionObject * identified by the supplied CSID. */ - protected static DocumentModel getMostRecentMovement(CoreSessionInterface session, String collectionObjectCsid, - boolean isAboutToBeRemovedEvent, String aboutToBeRemovedMovementCsidToFilter) - throws ClientException, Tools.NoRelatedRecordsException { - DocumentModel mostRecentMovementDocModel = null; - // Get Relation records for Movements related to this CollectionObject. + protected static String getMostRecentMovement(Event event, + CoreSessionInterface session, String collectionObjectCsid, + boolean isAboutToBeRemovedEvent, String eventMovementCsid) + throws ClientException { + // + // Assume we can determine the most recent location by creating an indeterminate result + // + String result = INDETERMINATE_LOCATION; + + // + // Get active Relation records involving Movement records related to this CollectionObject. // - // Some values below are hard-coded for readability, rather than - // being obtained from constants. String query = String.format( "SELECT * FROM %1$s WHERE " // collectionspace_core:tenantId = 1 " + "(" @@ -445,135 +467,101 @@ public abstract class AbstractUpdateObjectLocationValues implements EventListene + ")" + ACTIVE_DOCUMENT_WHERE_CLAUSE_FRAGMENT, RELATION_DOCTYPE, RELATIONS_COMMON_SCHEMA, collectionObjectCsid, MOVEMENT_DOCTYPE); - if (logger.isTraceEnabled()) { - logger.trace("query=" + query); - } + logger.trace("query=" + query); + 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 mostRecentMovementDocModel; - } else { - if (logger.isTraceEnabled()) { - logger.trace("Found " + relationDocModels.size() + " relations to Movement records to/from this CollectionObject record."); - } - } - + if (isCreatingNewRelationship(event) == true) { + DocumentModel newRelation = ((DocumentEventContext)event.getContext()).getSourceDocument(); + relationDocModels.add(newRelation); + } + // // Remove redundant document models from the list. // - relationDocModels = removeRedundantRelations(relationDocModels); + relationDocModels = removeRedundantRelations(relationDocModels); // - // Remove relationships with inactive movement records + // Remove relationships that are with inactive movement records // - relationDocModels = removeRelationsWithInactiveMovements(session, relationDocModels); + relationDocModels = removeInactiveRelations(session, relationDocModels, isAboutToBeRemovedEvent, eventMovementCsid); - if (relationDocModels == null || relationDocModels.size() == 0) throw new Tools.NoRelatedRecordsException(); + // + // If there are no candidate relationships after we removed the duplicates and inactive ones, + // throw an exception. + // + if (relationDocModels == null || relationDocModels.size() == 0) { + return result; + } // // If there is only one related movement record, then return it as the most recent - // movement record -if it's current location element is not empty. + // movement record -but only if it's current location element is not empty. // if (relationDocModels.size() == 1) { DocumentModel relationDocModel = relationDocModels.get(0); DocumentModel movementDocModel = getMovementDocModelFromRelation(session, relationDocModel); - String currentLocation = (String) movementDocModel.getProperty(MOVEMENTS_COMMON_SCHEMA, CURRENT_LOCATION_ELEMENT_NAME); - if (Tools.isBlank(currentLocation) || !isActiveDocument(movementDocModel)) { // currentLocation must be set and record must be active - movementDocModel = null; + String location = (String) movementDocModel.getProperty(MOVEMENTS_COMMON_SCHEMA, CURRENT_LOCATION_ELEMENT_NAME); + + if (Tools.isBlank(location) == false) { + result = location; + } else { // currentLocation must be set + logger.error(String.format("Movement record=%s is missing its required location value and so is excluded from the computation of cataloging record=%s's current location.", + NuxeoUtils.getCsid(movementDocModel), collectionObjectCsid)); } - - return movementDocModel; + + return result; } - // Iterate through related movement records, to find the related + // + // Iterate through the list (>2) of related movement records, to find the related // Movement record with the most recent location date. + // GregorianCalendar mostRecentLocationDate = EARLIEST_COMPARISON_DATE; - // Note: the following value is used to compare any two records, rather - // than to identify the most recent value so far encountered. Thus, it may - // occasionally be set backward or forward in time, within the loop below. - GregorianCalendar comparisonUpdatedDate = EARLIEST_COMPARISON_DATE; - DocumentModel movementDocModel; - Set alreadyProcessedMovementCsids = new HashSet<>(); - String relatedMovementCsid; + GregorianCalendar mostRecentUpdatedDate = EARLIEST_COMPARISON_DATE; + 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. + String relatedMovementCsid; + DocumentModel movementDocModel; + // + // The movement record is either the subject or object of the relationship, but not both. + // 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(relatedMovementCsid)) { - continue; - } - // Because of the OR clause used in the query above, there may be - // two or more Relation records returned in the query results that - // 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(relatedMovementCsid)) { - continue; - } else { - alreadyProcessedMovementCsids.add(relatedMovementCsid); - } - if (logger.isTraceEnabled()) { - logger.trace("Related movement CSID=" + relatedMovementCsid); - } - // If our event involves a Movement record that is about to be - // (hard) deleted, or a Movement record referenced by a Relation - // record that is about to be (hard) deleted, filter out that record. - if (isAboutToBeRemovedEvent && Tools.notBlank(aboutToBeRemovedMovementCsidToFilter)) { - if (relatedMovementCsid.equals(aboutToBeRemovedMovementCsidToFilter)) { - if (logger.isTraceEnabled()) { - logger.trace("Skipping about-to-be-deleted Movement record or referenced, related Movement record ..."); - } - continue; - } - } movementDocModel = getCurrentDocModelFromCsid(session, relatedMovementCsid); - if (movementDocModel == null) { - if (logger.isTraceEnabled()) { - logger.trace("Movement is not current (i.e. is a non-current version), is a proxy, or is unretrievable."); - } - continue; - } - // Verify that the Movement record is active. - if (!isActiveDocument(movementDocModel)) { - if (logger.isTraceEnabled()) { - logger.trace("Movement is inactive (i.e. is deleted or in another inactive lifestyle state)."); - } - continue; - } - GregorianCalendar locationDate = - (GregorianCalendar) movementDocModel.getProperty(MOVEMENTS_COMMON_SCHEMA, LOCATION_DATE_PROPERTY); + String location = (String) movementDocModel.getProperty(MOVEMENTS_COMMON_SCHEMA, CURRENT_LOCATION_ELEMENT_NAME); + + // // If the current Movement record lacks a location date, it cannot // be established as the most recent Movement record; skip over it. + // + GregorianCalendar locationDate = (GregorianCalendar) movementDocModel.getProperty(MOVEMENTS_COMMON_SCHEMA, LOCATION_DATE_PROPERTY); if (locationDate == null) { + logger.info(String.format("Movement record=%s has no location date and so is excluded from computation of cataloging record=%s current location.", + NuxeoUtils.getCsid(movementDocModel), collectionObjectCsid)); continue; } - GregorianCalendar updatedDate = - (GregorianCalendar) movementDocModel.getProperty(COLLECTIONSPACE_CORE_SCHEMA, UPDATED_AT_PROPERTY); + + GregorianCalendar updatedDate = (GregorianCalendar) movementDocModel.getProperty(COLLECTIONSPACE_CORE_SCHEMA, UPDATED_AT_PROPERTY); if (locationDate.after(mostRecentLocationDate)) { mostRecentLocationDate = locationDate; - if (updatedDate != null) { - comparisonUpdatedDate = updatedDate; - } - mostRecentMovementDocModel = movementDocModel; + mostRecentUpdatedDate = updatedDate; + result = location; + } else if (locationDate.compareTo(mostRecentLocationDate) == 0) { // If the current Movement record's location date is identical // to that of the (at this time) most recent Movement record, then // instead compare the two records using their update date values - } else if (locationDate.compareTo(mostRecentLocationDate) == 0) { - if (updatedDate != null && updatedDate.after(comparisonUpdatedDate)) { + if (updatedDate.after(mostRecentUpdatedDate)) { // The most recent location date value doesn't need to be // updated here, as the two records' values are identical - comparisonUpdatedDate = updatedDate; - mostRecentMovementDocModel = movementDocModel; + mostRecentUpdatedDate = updatedDate; + result = location; } } } - return mostRecentMovementDocModel; + return result; } // @@ -629,30 +617,43 @@ public abstract class AbstractUpdateObjectLocationValues implements EventListene // Return a Relation document model list with redundant (either identical or reciprocal) relations removed. // private static DocumentModelList removeRedundantRelations(DocumentModelList relationDocModelList) { - DocumentModelList resultList = new DocumentModelListImpl(); - for (DocumentModel relationDocModel : relationDocModelList) { - if (existsInResultList(resultList, relationDocModel) == false) { - resultList.add(relationDocModel); - } + DocumentModelList resultList = null; + + if (relationDocModelList != null && relationDocModelList.size() > 0) { + resultList = new DocumentModelListImpl(); + for (DocumentModel relationDocModel : relationDocModelList) { + if (existsInResultList(resultList, relationDocModel) == false) { + resultList.add(relationDocModel); + } + } } + // TODO Auto-generated method stub return resultList; } // - // Return just the list of relationships with active Movement records + // Return just the list of active relationships with active Movement records. A value of 'true' for the 'isAboutToBeRemovedEvent' + // argument indicates that relationships with the 'movementCsid' record should be considered inactive. // - private static DocumentModelList removeRelationsWithInactiveMovements(CoreSessionInterface session, DocumentModelList relationDocModelList) { - DocumentModelList resultList = new DocumentModelListImpl(); + private static DocumentModelList removeInactiveRelations(CoreSessionInterface session, + DocumentModelList relationDocModelList, + boolean isAboutToBeRemovedEvent, + String eventMovementCsid) { + DocumentModelList resultList = null; - for (DocumentModel relationDocModel : relationDocModelList) { - String movementCsid = getCsidForDesiredDocTypeFromRelation(relationDocModel, MOVEMENT_DOCTYPE, COLLECTIONOBJECT_DOCTYPE); - DocumentModel movementDocModel = getCurrentDocModelFromCsid(session, movementCsid); - if (isActiveDocument(movementDocModel) == true) { - resultList.add(relationDocModel); - } else { - logger.trace(String.format("Disqualified relationship with inactive Movement record=%s.", movementCsid)); - } + if (relationDocModelList != null && relationDocModelList.size() > 0) { + resultList = new DocumentModelListImpl(); + for (DocumentModel relationDocModel : relationDocModelList) { + String movementCsid = getCsidForDesiredDocTypeFromRelation(relationDocModel, MOVEMENT_DOCTYPE, COLLECTIONOBJECT_DOCTYPE); + DocumentModel movementDocModel = getCurrentDocModelFromCsid(session, movementCsid); + if (isActiveDocument(movementDocModel, isAboutToBeRemovedEvent, eventMovementCsid) == true) { + resultList.add(relationDocModel); + } else { + logger.debug(String.format("Disqualified relationship=%s with Movement record=%s from current location computation.", + NuxeoUtils.getCsid(relationDocModel), movementCsid)); + } + } } return resultList; @@ -677,30 +678,29 @@ public abstract class AbstractUpdateObjectLocationValues implements EventListene /** * Returns the CSID for a desired document type from a Relation record, - * where the relationship involves two specified, different document types. + * where the relationship involves two specified document types. * * @param relationDocModel a document model for a Relation record. * @param desiredDocType a desired document type. * @param relatedDocType a related document type. * @throws ClientException + * * @return the CSID from the desired document type in the relation. Returns - * an empty string if the Relation record does not involve both the desired - * and related document types, or if the desired document type is at both - * ends of the relation. + * null if the Relation record does not involve both the desired + * and related document types. */ protected static String getCsidForDesiredDocTypeFromRelation(DocumentModel relationDocModel, String desiredDocType, String relatedDocType) throws ClientException { - String csid = ""; + String csid = null; String subjectDocType = (String) relationDocModel.getProperty(RELATIONS_COMMON_SCHEMA, SUBJECT_DOCTYPE_PROPERTY); String objectDocType = (String) relationDocModel.getProperty(RELATIONS_COMMON_SCHEMA, OBJECT_DOCTYPE_PROPERTY); - if (subjectDocType.startsWith(desiredDocType) && objectDocType.startsWith(desiredDocType)) { - return csid; - } - if (subjectDocType.startsWith(desiredDocType) && objectDocType.startsWith(relatedDocType)) { + + if (subjectDocType.startsWith(desiredDocType) && objectDocType.startsWith(relatedDocType)) { // Use startsWith() method, because customized tenant type names differ in their suffix. csid = (String) relationDocModel.getProperty(RELATIONS_COMMON_SCHEMA, SUBJECT_CSID_PROPERTY); } else if (subjectDocType.startsWith(relatedDocType) && objectDocType.startsWith(desiredDocType)) { csid = (String) relationDocModel.getProperty(RELATIONS_COMMON_SCHEMA, OBJECT_CSID_PROPERTY); } + return csid; } @@ -717,7 +717,7 @@ public abstract class AbstractUpdateObjectLocationValues implements EventListene * record. * @throws ClientException */ - protected abstract DocumentModel updateCollectionObjectValuesFromMovement(DocumentModel collectionObjectDocModel, - DocumentModel movementDocModel) + protected abstract boolean updateCollectionObjectLocation(DocumentModel collectionObjectDocModel, + String movementRecordsLocation) 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 4be3f82bb..93b98b204 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 @@ -4,6 +4,7 @@ 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.collectionspace.services.nuxeo.util.NuxeoUtils; import org.nuxeo.ecm.core.api.ClientException; import org.nuxeo.ecm.core.api.DocumentModel; @@ -14,81 +15,34 @@ public class UpdateObjectLocationOnMove extends AbstractUpdateObjectLocationValu private final Log logger = LogFactory.getLog(UpdateObjectLocationOnMove.class); @Override - protected DocumentModel updateCollectionObjectValuesFromMovement(DocumentModel collectionObjectDocModel, - DocumentModel movementDocModel) throws ClientException { + protected boolean updateCollectionObjectLocation(DocumentModel collectionObjectDocModel, + String movementRecordsLocation) throws ClientException { + boolean result = false; - 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; - } - - protected DocumentModel updateComputedCurrentLocationValue(DocumentModel collectionObjectDocModel, - DocumentModel movementDocModel) - throws ClientException { - - // - // First see if we're being asked to clear the computed location field - // - if (movementDocModel.getCoreSession() == null) { - collectionObjectDocModel.setProperty(COLLECTIONOBJECTS_COMMON_SCHEMA, - COMPUTED_CURRENT_LOCATION_PROPERTY, null); - return collectionObjectDocModel; - } - - // Get the current location value from the Movement (the "new" value) - 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 an authority term (such as a storage + // Check that the location value returned, which is expected to be a reference (refName) to an authority term (such as a storage // location or organization term): + // * Ensure it is not blank. + // * Ensure it is successfully parsed by the authority item parser. // - // * Is not blank - // * Is capable of being successfully parsed by an authority item parser. - if (Tools.isBlank(currentLocationRefName)) { - if (logger.isTraceEnabled()) { - logger.trace("Current location in Movement record was blank"); - } - return collectionObjectDocModel; - } else if (RefNameUtils.parseAuthorityTermInfo(currentLocationRefName) == null) { - logger.warn(String.format("Could not parse current location refName '%s' in Movement record", - currentLocationRefName)); - return collectionObjectDocModel; - } else { - if (logger.isTraceEnabled()) { - logger.trace("current location refName passes basic validation tests."); - logger.trace("currentLocation refName=" + currentLocationRefName); - } + if (Tools.isBlank(movementRecordsLocation)) { + return result; + } else if (RefNameUtils.parseAuthorityTermInfo(movementRecordsLocation) == null) { + logger.warn(String.format("Ignoring movment record. Could not parse the location field's refName '%s'.", + movementRecordsLocation)); + return result; } - // Get the computed current location value of the CollectionObject - // (the "existing" value) - String existingComputedCurrentLocationRefName = - (String) collectionObjectDocModel.getProperty(COLLECTIONOBJECTS_COMMON_SCHEMA, + // Get the computed current location value of the CollectionObject. + String existingComputedCurrentLocation = (String) collectionObjectDocModel.getProperty(COLLECTIONOBJECTS_COMMON_SCHEMA, COMPUTED_CURRENT_LOCATION_PROPERTY); - if (logger.isTraceEnabled()) { - logger.trace("Existing computedCurrentLocation refName=" + existingComputedCurrentLocationRefName); - } - // If the new value is not blank (redundant with a check just above, but - // a quick, extra guard) and the new value is different than the existing value ... - if ( (Tools.notBlank(currentLocationRefName)) && (!currentLocationRefName.equals(existingComputedCurrentLocationRefName))) { - if (logger.isTraceEnabled()) { - logger.trace("computedCurrentLocation refName requires updating."); - } - // ... update the existing value (in the CollectionObject) with the - // new value (from the Movement). + // If the movement record's location is different than the existing catalog's then update it and return 'true' + if (movementRecordsLocation.equalsIgnoreCase(existingComputedCurrentLocation) == false) { collectionObjectDocModel.setProperty(COLLECTIONOBJECTS_COMMON_SCHEMA, - COMPUTED_CURRENT_LOCATION_PROPERTY, currentLocationRefName); - - } else { - if (logger.isTraceEnabled()) { - logger.trace("computedCurrentLocation refName does NOT require updating."); - } + COMPUTED_CURRENT_LOCATION_PROPERTY, movementRecordsLocation); + result = true; // We've updated the location field. } - return collectionObjectDocModel; + return result; } } \ No newline at end of file diff --git a/services/JaxRsServiceProvider/src/main/resources/log4j.properties b/services/JaxRsServiceProvider/src/main/resources/log4j.properties index 54471805b..0db6cc9a1 100644 --- a/services/JaxRsServiceProvider/src/main/resources/log4j.properties +++ b/services/JaxRsServiceProvider/src/main/resources/log4j.properties @@ -53,12 +53,21 @@ log4j.additivity.perf.collectionspace=false # CollectionSpace loggers and default levels - all loggers using the rootLogger if not otherwise specified # log4j.logger.org.collectionspace=DEBUG -#log4j.logger.org.collectionspace.services.nuxeo.client.java.NuxeoClientEmbedded=ERROR +log4j.logger.org.collectionspace.services.common.ServiceMain=INFO +log4j.logger.org.collectionspace.authentication.realm.db.CSpaceDbRealm=ERROR +log4j.logger.org.collectionspace.services.nuxeo.client.java.CoreSessionWrapper=ERROR +log4j.logger.org.collectionspace.services.nuxeo.client.java.NuxeoConnectorEmbedded=ERROR +log4j.logger.org.collectionspace.services.common.authorization_mgt.AuthorizationCommon=ERROR +log4j.logger.org.collectionspace.services.nuxeo.client.java.TenantRepository=ERROR +log4j.logger.org.collectionspace.services.common.init=ERROR +log4j.logger.org.collectionspace.services.common.config.ServiceConfigUtils=ERROR +log4j.logger.org.collectionspace.services.report.nuxeo.ReportPostInitHandler=ERROR +log4j.logger.org.collectionspace.services.client.AbstractServiceClientImpl=ERROR #log4j.logger.org.collectionspace.services.nuxeo.client.java.RepositoryClientImpl=ERROR -#log4j.logger.org.collectionspace.services.common.security.SecurityInterceptor=ERROR +log4j.logger.org.collectionspace.services.common.security.SecurityInterceptor=ERROR #log4j.logger.org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl=DEBUG #log4j.logger.org.collectionspace.services.nuxeo.client.java=ERROR -#log4j.logger.org.collectionspace.services.common.storage.JDBCTools=ERROR +log4j.logger.org.collectionspace.services.common.storage.JDBCTools=ERROR #log4j.logger.org.collectionspace.services.common.profile.CSpaceFilter=ERROR #log4j.logger.org.collectionspace.services.common.vocabulary.nuxeo=TRACE diff --git a/services/common-api/src/main/java/org/collectionspace/services/common/api/Tools.java b/services/common-api/src/main/java/org/collectionspace/services/common/api/Tools.java index 4a6b7f064..16d356ee8 100644 --- a/services/common-api/src/main/java/org/collectionspace/services/common/api/Tools.java +++ b/services/common-api/src/main/java/org/collectionspace/services/common/api/Tools.java @@ -33,12 +33,7 @@ import java.util.regex.Matcher; * @author Laramie Crocker * v.1.4 */ -public class Tools { - - public static class NoRelatedRecordsException extends Exception { - - } - +public class Tools { private static final String PROPERTY_VAR_REGEX = "\\$\\{([A-Za-z0-9_\\.]+)\\}"; /** @return first glued to second with the separator string, at most one time - useful for appending paths. diff --git a/services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java b/services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java index cbf820b6e..4ae59463f 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java +++ b/services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java @@ -388,8 +388,8 @@ public class ServiceMain { if (Tools.isEmpty(initHandlerClassname)) { continue; } - if (ServiceMain.logger.isDebugEnabled()) { - ServiceMain.logger.debug(String.format("Firing post-init handler %s ...", initHandlerClassname)); + if (ServiceMain.logger.isTraceEnabled()) { + ServiceMain.logger.trace(String.format("Firing post-init handler %s ...", initHandlerClassname)); } List @@ -864,8 +864,8 @@ public class ServiceMain { } if (logger.isInfoEnabled()) { - logger.info("Found and can read prototype Nuxeo config file at path %s", - prototypeNuxeoDatasourceFile.getAbsolutePath()); + logger.info(String.format("Using prototype Nuxeo server configuration file at path %s", + prototypeNuxeoDatasourceFile.getAbsolutePath())); } // @@ -924,8 +924,8 @@ public class ServiceMain { } if (logger.isInfoEnabled()) { - logger.info("Found and can read the prototype Elasticsearch configuration file at path '%s'.", - result.getAbsolutePath()); + logger.info(String.format(String.format("Using the prototype Elasticsearch configuration file at path '%s'.", + result.getAbsolutePath()))); } return result; @@ -946,8 +946,8 @@ public class ServiceMain { } if (logger.isInfoEnabled()) { - logger.info("Found and can read the prototype Elasticsearch extension file at path %s", - result.getAbsolutePath()); + logger.info(String.format("Using the prototype Elasticsearch extension file at path %s", + result.getAbsolutePath())); } return result; @@ -1026,7 +1026,8 @@ public class ServiceMain { throw new RuntimeException(msg); } if (logger.isInfoEnabled()) { - logger.info("Found and can read prototype Nuxeo config file at path %s", prototypeNuxeoConfigFile.getAbsolutePath()); + logger.info(String.format("Using prototype Nuxeo config file at path %s", + prototypeNuxeoConfigFile.getAbsolutePath())); } // diff --git a/services/common/src/main/java/org/collectionspace/services/common/config/TenantBindingConfigReaderImpl.java b/services/common/src/main/java/org/collectionspace/services/common/config/TenantBindingConfigReaderImpl.java index c60f8ae40..b55073769 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/config/TenantBindingConfigReaderImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/common/config/TenantBindingConfigReaderImpl.java @@ -502,10 +502,7 @@ public class TenantBindingConfigReaderImpl extends AbstractConfigReaderImpl principals = subject.getPrincipals(); - logger.debug("Nuxeo login performed with principals: "); + logger.trace("Nuxeo login performed with principals: "); for (Principal principal : principals) { - logger.debug("[" + principal.getName() + "]"); + logger.trace("[" + principal.getName() + "]"); } } private void logLogoutContext(LoginContext loginContext) { + if (!logger.isTraceEnabled()) return; + if (loginContext != null) { logger.trace("CollectionSpace services now logging out of Nuxeo with LoginContext: " + loginContext); Subject subject = loginContext.getSubject(); Set principals = subject.getPrincipals(); - logger.debug("Nuxeo logout performed with principals: "); + logger.trace("Nuxeo logout performed with principals: "); for (Principal principal : principals) { - logger.debug("[" + principal.getName() + "]"); + logger.trace("[" + principal.getName() + "]"); } } else { logger.trace("Logged out."); @@ -374,11 +378,9 @@ public class SecurityInterceptor implements PreProcessInterceptor, PostProcessIn Thread.currentThread(), threadLocalLoginContext, threadLocalLoginContext.get())); } // - // Debug message + // Debug logging // - if (logger.isDebugEnabled() == true) { - logLoginContext(loginContext); - } + logLoginContext(loginContext); } else { // // We're already logged in somehow? This is probably not good. It seems to mean that the LoginContext last @@ -395,14 +397,12 @@ public class SecurityInterceptor implements PreProcessInterceptor, PostProcessIn private synchronized void nuxeoLogout() throws LoginException { LoginContext loginContext = threadLocalLoginContext != null ? threadLocalLoginContext.get() : null; if (loginContext != null) { - if (logger.isDebugEnabled() == true) { - logLogoutContext(loginContext); - } + logLogoutContext(loginContext); loginContext.logout(); threadLocalLoginContext.set(null); // We need to clear the login context from this thread, so the next request on this thread has to login again. logLogoutContext(null); frameworkLogins--; - if (logger.isDebugEnabled()) { + if (logger.isTraceEnabled()) { String.format("Framework logins: ", frameworkLogins); } } else { diff --git a/services/index/3rdparty/nuxeo-platform-cs-index/src/main/resources/schemas/index_common.xsd b/services/index/3rdparty/nuxeo-platform-cs-index/src/main/resources/schemas/index_common.xsd new file mode 100644 index 000000000..f8f0a563d --- /dev/null +++ b/services/index/3rdparty/nuxeo-platform-cs-index/src/main/resources/schemas/index_common.xsd @@ -0,0 +1,22 @@ + + + + + + + + diff --git a/services/publicitem/3rdparty/nuxeo-platform-cs-publicitem/src/main/resources/OSGI-INF/layouts-contrib.xml b/services/publicitem/3rdparty/nuxeo-platform-cs-publicitem/src/main/resources/OSGI-INF/layouts-contrib.xml new file mode 100644 index 000000000..0325741f0 --- /dev/null +++ b/services/publicitem/3rdparty/nuxeo-platform-cs-publicitem/src/main/resources/OSGI-INF/layouts-contrib.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + contentName + + + + + + + true + + contentName + + + dataInputText + + + + + +