<parent>
<artifactId>org.collectionspace.services.3rdparty.nuxeo.listener</artifactId>
<groupId>org.collectionspace.services</groupId>
- <version>${revision}</version>
+ <version>${revision}</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<name>org.collectionspace.services.listener.botgarden</name>
<url>http://maven.apache.org</url>
-
+
<dependencies>
<dependency>
<groupId>org.nuxeo.ecm.core</groupId>
<artifactId>nuxeo-core-storage-sql</artifactId>
+ <version>${nuxeo.core.version}</version>
</dependency>
<dependency>
<groupId>org.nuxeo.ecm.platform</groupId>
<artifactId>nuxeo-platform-filemanager-api</artifactId>
- <version>${nuxeo.platform.version}</version>
+ <version>${nuxeo.platform.version}</version>
</dependency>
<dependency>
<groupId>org.collectionspace.services</groupId>
</dependency>
</dependencies>
-
+
<build>
<resources>
<resource>
</plugin>
</plugins>
</build>
-
+
</project>
package org.collectionspace.services.listener.botgarden;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
import org.collectionspace.services.client.workflow.WorkflowClient;
import org.collectionspace.services.movement.nuxeo.MovementConstants;
-import org.collectionspace.services.nuxeo.listener.AbstractCSEventListenerImpl;
+import org.collectionspace.services.nuxeo.listener.AbstractCSEventSyncListenerImpl;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.DocumentRef;
import org.nuxeo.ecm.core.api.VersioningOption;
import org.nuxeo.ecm.core.event.Event;
import org.nuxeo.ecm.core.event.EventContext;
import org.nuxeo.ecm.core.event.impl.DocumentEventContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-public class CreateVersionListener extends AbstractCSEventListenerImpl {
+public class CreateVersionListener extends AbstractCSEventSyncListenerImpl {
public static final String SKIP_PROPERTY = "CreateVersionListener.SKIP";
+ static final Log logger = LogFactory.getLog(CreateVersionListener.class);
- final Logger logger = LoggerFactory.getLogger(CreateVersionListener.class);
-
+ @Override
+ public boolean shouldHandleEvent(Event event) {
+ EventContext eventContext = event.getContext();
+ if (isRegistered(event) && eventContext instanceof DocumentEventContext) {
+ return true;
+ }
+
+ return false;
+ }
+
@Override
- public void handleEvent(Event event) {
+ public void handleCSEvent(Event event) {
EventContext ec = event.getContext();
+ DocumentEventContext context = (DocumentEventContext) ec;
- if (isRegistered(event) && ec instanceof DocumentEventContext) {
- DocumentEventContext context = (DocumentEventContext) ec;
-
- if (ec.hasProperty(SKIP_PROPERTY) && ((Boolean) ec.getProperty(SKIP_PROPERTY))) {
- logger.debug("Skipping create version");
- }
- else {
- DocumentModel doc = context.getSourceDocument();
+ if (ec.hasProperty(SKIP_PROPERTY) && ((Boolean) ec.getProperty(SKIP_PROPERTY))) {
+ logger.debug("Skipping create version");
+ }
+ else {
+ DocumentModel doc = context.getSourceDocument();
- logger.debug("docType=" + doc.getType());
+ logger.debug("docType=" + doc.getType());
- if (doc.getType().startsWith(MovementConstants.NUXEO_DOCTYPE) &&
- !doc.isVersion() &&
- !doc.isProxy() &&
- !doc.getCurrentLifeCycleState().equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
- // Version the document
- DocumentRef versionRef = doc.checkIn(VersioningOption.MINOR, null);
- DocumentModel versionDoc = context.getCoreSession().getDocument(versionRef);
+ if (doc.getType().startsWith(MovementConstants.NUXEO_DOCTYPE) &&
+ !doc.isVersion() &&
+ !doc.isProxy() &&
+ !doc.getCurrentLifeCycleState().equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
+ // Version the document
+ DocumentRef versionRef = doc.checkIn(VersioningOption.MINOR, null);
+ DocumentModel versionDoc = context.getCoreSession().getDocument(versionRef);
- logger.debug("created version: id=" + versionDoc.getId() + " csid=" + versionDoc.getName());
+ logger.debug("created version: id=" + versionDoc.getId() + " csid=" + versionDoc.getName());
- // Check out the document, so it can be modified
- doc.checkOut();
- }
+ // Check out the document, so it can be modified
+ doc.checkOut();
}
}
}
-}
+
+ @Override
+ public Log getLogger() {
+ return logger;
+ }
+}
\ No newline at end of file
package org.collectionspace.services.listener.botgarden;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
import org.collectionspace.services.client.workflow.WorkflowClient;
import org.collectionspace.services.movement.nuxeo.MovementBotGardenConstants;
import org.collectionspace.services.movement.nuxeo.MovementConstants;
-import org.collectionspace.services.nuxeo.listener.AbstractCSEventListenerImpl;
+import org.collectionspace.services.nuxeo.listener.AbstractCSEventSyncListenerImpl;
+
import org.nuxeo.ecm.core.api.CoreSession;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.event.Event;
import org.nuxeo.ecm.core.event.EventContext;
import org.nuxeo.ecm.core.event.impl.DocumentEventContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-public class DeleteDeadLocationListener extends AbstractCSEventListenerImpl {
- final Logger logger = LoggerFactory.getLogger(DeleteDeadLocationListener.class);
+public class DeleteDeadLocationListener extends AbstractCSEventSyncListenerImpl {
+ static final Log logger = LogFactory.getLog(DeleteDeadLocationListener.class);
- /*
- * Delete dead locations.
- */
@Override
- public void handleEvent(Event event) {
+ public boolean shouldHandleEvent(Event event) {
EventContext ec = event.getContext();
- if (isRegistered(event) && ec instanceof DocumentEventContext) {
+ if (ec instanceof DocumentEventContext) {
DocumentEventContext context = (DocumentEventContext) ec;
DocumentModel doc = context.getSourceDocument();
if (doc.getType().startsWith(MovementConstants.NUXEO_DOCTYPE) &&
- !doc.isVersion() &&
- !doc.isProxy() &&
+ !doc.isVersion() &&
+ !doc.isProxy() &&
!doc.getCurrentLifeCycleState().equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
- String actionCode = (String) doc.getProperty(MovementBotGardenConstants.ACTION_CODE_SCHEMA_NAME,
- MovementBotGardenConstants.ACTION_CODE_FIELD_NAME);
-
- logger.debug("actionCode=" + actionCode);
-
- if (actionCode != null && actionCode.equals(MovementBotGardenConstants.DEAD_ACTION_CODE)) {
- CoreSession session = context.getCoreSession();
-
- if (session.getAllowedStateTransitions(doc.getRef()).contains(WorkflowClient.WORKFLOWTRANSITION_DELETE)) {
- session.followTransition(doc.getRef(), WorkflowClient.WORKFLOWTRANSITION_DELETE);
- }
- }
+ return true;
}
}
+
+ return false;
+ }
+
+ /*
+ * Delete dead locations.
+ */
+ @Override
+ public void handleCSEvent(Event event) {
+ EventContext ec = event.getContext();
+ DocumentEventContext context = (DocumentEventContext) ec;
+ DocumentModel doc = context.getSourceDocument();
+
+ String actionCode = (String) doc.getProperty(MovementBotGardenConstants.ACTION_CODE_SCHEMA_NAME,
+ MovementBotGardenConstants.ACTION_CODE_FIELD_NAME);
+
+ logger.debug("actionCode=" + actionCode);
+
+ if (actionCode != null && actionCode.equals(MovementBotGardenConstants.DEAD_ACTION_CODE)) {
+ CoreSession session = context.getCoreSession();
+
+ if (session.getAllowedStateTransitions(doc.getRef()).contains(WorkflowClient.WORKFLOWTRANSITION_DELETE)) {
+ session.followTransition(doc.getRef(), WorkflowClient.WORKFLOWTRANSITION_DELETE);
+ }
+ }
+ }
+
+ @Override
+ public Log getLogger() {
+ return logger;
}
-}
+}
\ No newline at end of file
import java.util.Set;
import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.collectionspace.services.batch.BatchResource;
import org.collectionspace.services.batch.nuxeo.UpdateAccessCodeBatchJob;
+import org.collectionspace.services.batch.nuxeo.UpdateAccessCodeBatchJob.UpdateAccessCodeResults;
+import org.collectionspace.services.client.BatchClient;
+import org.collectionspace.services.client.PoxPayloadIn;
+import org.collectionspace.services.client.PoxPayloadOut;
import org.collectionspace.services.client.workflow.WorkflowClient;
import org.collectionspace.services.collectionobject.nuxeo.CollectionObjectBotGardenConstants;
import org.collectionspace.services.collectionobject.nuxeo.CollectionObjectConstants;
import org.collectionspace.services.common.ResourceMap;
+import org.collectionspace.services.common.context.ServiceContext;
import org.collectionspace.services.common.invocable.InvocationResults;
import org.collectionspace.services.common.relation.nuxeo.RelationConstants;
-import org.collectionspace.services.nuxeo.listener.AbstractCSEventListenerImpl;
+import org.collectionspace.services.nuxeo.client.java.CoreSessionWrapper;
+import org.collectionspace.services.nuxeo.listener.AbstractCSEventSyncListenerImpl;
import org.collectionspace.services.taxonomy.nuxeo.TaxonBotGardenConstants;
import org.collectionspace.services.taxonomy.nuxeo.TaxonConstants;
+import org.collectionspace.services.taxonomy.nuxeo.TaxonomyAuthorityConstants;
+
import org.jboss.resteasy.spi.ResteasyProviderFactory;
+
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.event.CoreEventConstants;
import org.nuxeo.ecm.core.api.event.DocumentEventTypes;
import org.nuxeo.ecm.core.event.Event;
import org.nuxeo.ecm.core.event.EventContext;
import org.nuxeo.ecm.core.event.impl.DocumentEventContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* A listener that updates the access code on taxon records when collectionobjects
* @author ray
*
*/
-public class UpdateAccessCodeListener extends AbstractCSEventListenerImpl {
- final Logger logger = LoggerFactory.getLogger(UpdateAccessCodeListener.class);
+public class UpdateAccessCodeListener extends AbstractCSEventSyncListenerImpl {
+ static final Log logger = LogFactory.getLog(UpdateAccessCodeListener.class);
public static final String PREVIOUS_DEAD_FLAG_PROPERTY_NAME = "UpdateAccessCodeListener.previousDeadFlag";
public static final String PREVIOUS_TAXON_NAMES_PROPERTY_NAME = "UpdateAccessCodeListener.previousTaxonNames";
private static final String TAXON_FIELD_NAME = TAXON_PATH_ELEMENTS[2];
@Override
- public void handleEvent(Event event) {
+ public boolean shouldHandleEvent(Event event) {
+ return event.getContext() instanceof DocumentEventContext;
+ }
+
+ @Override
+ public void handleCSEvent(Event event) {
EventContext ec = event.getContext();
- if (isRegistered(event) && ec instanceof DocumentEventContext) {
- DocumentEventContext context = (DocumentEventContext) ec;
- DocumentModel doc = context.getSourceDocument();
+ DocumentEventContext context = (DocumentEventContext) ec;
+ DocumentModel doc = context.getSourceDocument();
+ String docType = doc.getType();
- logger.debug("docType=" + doc.getType());
+ logger.debug("docType=" + docType);
- if (doc.getType().startsWith(CollectionObjectConstants.NUXEO_DOCTYPE) &&
- !doc.isVersion() &&
- !doc.isProxy() &&
- !doc.getCurrentLifeCycleState().equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
+ if (docType.startsWith(CollectionObjectConstants.NUXEO_DOCTYPE) &&
+ !doc.isVersion() &&
+ !doc.isProxy() &&
+ !doc.getCurrentLifeCycleState().equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
- if (event.getName().equals(DocumentEventTypes.BEFORE_DOC_UPDATE)) {
- // Stash the previous dead flag and taxonomic ident values, so they can be retrieved in the documentModified handler.
+ if (event.getName().equals(DocumentEventTypes.BEFORE_DOC_UPDATE)) {
+ // Stash the previous dead flag and taxonomic ident values, so they can be retrieved in the documentModified handler.
- DocumentModel previousDoc = (DocumentModel) context.getProperty(CoreEventConstants.PREVIOUS_DOCUMENT_MODEL);
+ DocumentModel previousDoc = (DocumentModel) context.getProperty(CoreEventConstants.PREVIOUS_DOCUMENT_MODEL);
- String previousDeadFlag = (String) previousDoc.getProperty(CollectionObjectBotGardenConstants.DEAD_FLAG_SCHEMA_NAME,
- CollectionObjectBotGardenConstants.DEAD_FLAG_FIELD_NAME);
- context.setProperty(PREVIOUS_DEAD_FLAG_PROPERTY_NAME, previousDeadFlag);
+ String previousDeadFlag = (String) previousDoc.getProperty(CollectionObjectBotGardenConstants.DEAD_FLAG_SCHEMA_NAME,
+ CollectionObjectBotGardenConstants.DEAD_FLAG_FIELD_NAME);
+ context.setProperty(PREVIOUS_DEAD_FLAG_PROPERTY_NAME, previousDeadFlag);
- List<String> previousTaxonNames = getTaxonNames(previousDoc);
- context.setProperty(PREVIOUS_TAXON_NAMES_PROPERTY_NAME, previousTaxonNames.toArray(new String[previousTaxonNames.size()]));
- }
- else {
- boolean deadFlagChanged = false;
- Set<String> deletedTaxonNames = null;
- Set<String> addedTaxonNames = null;
-
- if (event.getName().equals(DocumentEventTypes.DOCUMENT_UPDATED)) {
- // As an optimization, check if the dead flag of the collectionobject has
- // changed, or if the taxonomic identification has changed. If so, we need to
- // update the access codes of referenced taxon records.
-
- String previousDeadFlag = (String) context.getProperty(PREVIOUS_DEAD_FLAG_PROPERTY_NAME);
- String currentDeadFlag = (String) doc.getProperty(CollectionObjectBotGardenConstants.DEAD_FLAG_SCHEMA_NAME,
- CollectionObjectBotGardenConstants.DEAD_FLAG_FIELD_NAME);
+ List<String> previousTaxonNames = getTaxonNames(previousDoc);
+ context.setProperty(PREVIOUS_TAXON_NAMES_PROPERTY_NAME, previousTaxonNames.toArray(new String[previousTaxonNames.size()]));
+ }
+ else {
+ boolean deadFlagChanged = false;
+ Set<String> deletedTaxonNames = null;
+ Set<String> addedTaxonNames = null;
- if (previousDeadFlag == null) {
- previousDeadFlag = "";
- }
+ String currentDeadFlag = (String) doc.getProperty(CollectionObjectBotGardenConstants.DEAD_FLAG_SCHEMA_NAME,
+ CollectionObjectBotGardenConstants.DEAD_FLAG_FIELD_NAME);
- if (currentDeadFlag == null) {
- currentDeadFlag = "";
- }
+ if (currentDeadFlag == null) {
+ currentDeadFlag = "";
+ }
- if (previousDeadFlag.equals(currentDeadFlag)) {
- logger.debug("dead flag not changed: previousDeadFlag=" + previousDeadFlag + " currentDeadFlag=" + currentDeadFlag);
- }
- else {
- logger.debug("dead flag changed: previousDeadFlag=" + previousDeadFlag + " currentDeadFlag=" + currentDeadFlag);
- deadFlagChanged = true;
- }
+ if (event.getName().equals(DocumentEventTypes.DOCUMENT_UPDATED)) {
+ // As an optimization, check if the dead flag of the collectionobject has
+ // changed, or if the taxonomic identification has changed. If so, we need to
+ // update the access codes of referenced taxon records.
- List<String> previousTaxonNames = Arrays.asList((String[]) context.getProperty(PREVIOUS_TAXON_NAMES_PROPERTY_NAME));
- List<String> currentTaxonNames = getTaxonNames(doc);
+ String previousDeadFlag = (String) context.getProperty(PREVIOUS_DEAD_FLAG_PROPERTY_NAME);
- deletedTaxonNames = findDeletedTaxonNames(previousTaxonNames, currentTaxonNames);
- logger.debug("found deleted taxon names: " + StringUtils.join(deletedTaxonNames, ", "));
+ if (previousDeadFlag == null) {
+ previousDeadFlag = "";
+ }
- addedTaxonNames = findAddedTaxonNames(previousTaxonNames, currentTaxonNames);
- logger.debug("found added taxon names: " + StringUtils.join(addedTaxonNames, ", "));
+ if (previousDeadFlag.equals(currentDeadFlag)) {
+ logger.debug("dead flag not changed: previousDeadFlag=" + previousDeadFlag + " currentDeadFlag=" + currentDeadFlag);
}
- else if (event.getName().equals(DocumentEventTypes.DOCUMENT_CREATED)) {
+ else {
+ logger.debug("dead flag changed: previousDeadFlag=" + previousDeadFlag + " currentDeadFlag=" + currentDeadFlag);
deadFlagChanged = true;
}
- UpdateAccessCodeBatchJob updater = createUpdater();
+ List<String> previousTaxonNames = Arrays.asList((String[]) context.getProperty(PREVIOUS_TAXON_NAMES_PROPERTY_NAME));
+ List<String> currentTaxonNames = getTaxonNames(doc);
- if (deadFlagChanged) {
- String collectionObjectCsid = doc.getName();
+ deletedTaxonNames = findDeletedTaxonNames(previousTaxonNames, currentTaxonNames);
+ logger.debug("found deleted taxon names: " + StringUtils.join(deletedTaxonNames, ", "));
- try {
- // Pass false for the second parameter to updateReferencedAccessCodes, so that it doesn't
- // propagate changes up the taxon hierarchy. Propagation is taken care of by this
- // event handler: As taxon records are modified, this handler executes, and updates the
- // parent.
+ addedTaxonNames = findAddedTaxonNames(previousTaxonNames, currentTaxonNames);
+ logger.debug("found added taxon names: " + StringUtils.join(addedTaxonNames, ", "));
+ }
+ else if (event.getName().equals(DocumentEventTypes.DOCUMENT_CREATED)) {
+ deadFlagChanged = true;
+ }
- InvocationResults results = updater.updateReferencedAccessCodes(collectionObjectCsid, false);
+ if (deadFlagChanged) {
+ String collectionObjectCsid = doc.getName();
- logger.debug("updateReferencedAccessCodes complete: numAffected=" + results.getNumAffected() + " userNote=" + results.getUserNote());
- }
- catch (Exception e) {
- logger.error(e.getMessage(), e);
- }
- }
- else {
- // If the dead flag didn't change, we still need to recalculate the access codes of
- // any taxonomic idents that were added.
-
- if (addedTaxonNames != null) {
- for (String addedTaxonName : addedTaxonNames) {
- logger.debug("updating added taxon: " + addedTaxonName);
+ try {
+ // Pass false for the second parameter to updateReferencedAccessCodes, so that it doesn't
+ // propagate changes up the taxon hierarchy. Propagation is taken care of by this
+ // event handler: As taxon records are modified, this handler executes, and updates the
+ // parent.
- try {
- InvocationResults results = updater.updateAccessCode(addedTaxonName, false);
+ InvocationResults results = createUpdater(context).updateReferencedAccessCodes(collectionObjectCsid, false);
- logger.debug("updateAccessCode complete: numAffected=" + results.getNumAffected() + " userNote=" + results.getUserNote());
- }
- catch (Exception e) {
- logger.error(e.getMessage(), e);
- }
- }
- }
+ logger.debug("updateReferencedAccessCodes complete: numAffected=" + results.getNumAffected() + " userNote=" + results.getUserNote());
+ }
+ catch (Exception e) {
+ logger.error(e.getMessage(), e);
}
+ }
+ else {
+ // If the dead flag didn't change, we still need to recalculate the access codes of
+ // any taxonomic idents that were added.
- if (deletedTaxonNames != null) {
- // If any taxonomic idents were removed from the collectionobject, they need to have their
- // access codes recalculated.
+ if (addedTaxonNames != null) {
+ boolean isDead = currentDeadFlag.equalsIgnoreCase("true");
+ boolean knownAlive = !isDead;
- for (String deletedTaxonName : deletedTaxonNames) {
- logger.debug("updating deleted taxon: " + deletedTaxonName);
+ for (String addedTaxonName : addedTaxonNames) {
+ logger.debug("updating added taxon: " + addedTaxonName);
try {
- InvocationResults results = updater.updateAccessCode(deletedTaxonName, false);
+ UpdateAccessCodeResults results = createUpdater(context).updateAccessCode(addedTaxonName, false, knownAlive);
- logger.debug("updateAccessCode complete: numAffected=" + results.getNumAffected() + " userNote=" + results.getUserNote());
+ logger.debug("updateAccessCode complete: numAffected=" + results.getNumAffected());
}
catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
}
- }
- else if (doc.getType().startsWith(TaxonConstants.NUXEO_DOCTYPE) &&
- !doc.isVersion() &&
- !doc.isProxy() &&
- !doc.getCurrentLifeCycleState().equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
- if (event.getName().equals(DocumentEventTypes.BEFORE_DOC_UPDATE)) {
- // Stash the previous access code value, so it can be retrieved in the documentModified handler.
+ if (deletedTaxonNames != null) {
+ // If any taxonomic idents were removed from the collectionobject, they need to have their
+ // access codes recalculated.
- DocumentModel previousDoc = (DocumentModel) context.getProperty(CoreEventConstants.PREVIOUS_DOCUMENT_MODEL);
- String previousAccessCode = (String) previousDoc.getProperty(TaxonBotGardenConstants.ACCESS_CODE_SCHEMA_NAME, TaxonBotGardenConstants.ACCESS_CODE_FIELD_NAME);
+ for (String deletedTaxonName : deletedTaxonNames) {
+ logger.debug("updating deleted taxon: " + deletedTaxonName);
- context.setProperty(PREVIOUS_ACCESS_CODE_PROPERTY_NAME, previousAccessCode);
+ try {
+ InvocationResults results = createUpdater(context).updateAccessCode(deletedTaxonName, false);
+
+ logger.debug("updateAccessCode complete: numAffected=" + results.getNumAffected() + " userNote=" + results.getUserNote());
+ }
+ catch (Exception e) {
+ logger.error(e.getMessage(), e);
+ }
+ }
}
- else {
- boolean updateRequired = false;
+ }
+ }
+ else if (docType.startsWith(TaxonConstants.NUXEO_DOCTYPE) &&
+ !docType.startsWith(TaxonomyAuthorityConstants.NUXEO_DOCTYPE) &&
+ !doc.isVersion() &&
+ !doc.isProxy() &&
+ !doc.getCurrentLifeCycleState().equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
- if (event.getName().equals(DocumentEventTypes.DOCUMENT_UPDATED)) {
- // As an optimization, check if the access code of the taxon has
- // changed. We only need to update the access code of the parent taxon
- // record if it has.
+ if (event.getName().equals(DocumentEventTypes.BEFORE_DOC_UPDATE)) {
+ // Stash the previous access code value, so it can be retrieved in the documentModified handler.
- String previousAccessCode = (String) context.getProperty(PREVIOUS_ACCESS_CODE_PROPERTY_NAME);
- String currentAccessCode = (String) doc.getProperty(TaxonBotGardenConstants.ACCESS_CODE_SCHEMA_NAME, TaxonBotGardenConstants.ACCESS_CODE_FIELD_NAME);
+ DocumentModel previousDoc = (DocumentModel) context.getProperty(CoreEventConstants.PREVIOUS_DOCUMENT_MODEL);
+ String previousAccessCode = (String) previousDoc.getProperty(TaxonBotGardenConstants.ACCESS_CODE_SCHEMA_NAME, TaxonBotGardenConstants.ACCESS_CODE_FIELD_NAME);
- if (previousAccessCode == null) {
- previousAccessCode = "";
- }
+ context.setProperty(PREVIOUS_ACCESS_CODE_PROPERTY_NAME, previousAccessCode);
+ }
+ else {
+ boolean updateRequired = false;
- if (currentAccessCode == null) {
- currentAccessCode = "";
- }
+ if (event.getName().equals(DocumentEventTypes.DOCUMENT_UPDATED)) {
+ // As an optimization, check if the access code of the taxon has
+ // changed. We only need to update the access code of the parent taxon
+ // record if it has.
- if (previousAccessCode.equals(currentAccessCode)) {
- logger.debug("update not required: previousAccessCode=" + previousAccessCode + " currentAccessCode=" + currentAccessCode);
- }
- else {
- logger.debug("update required: previousAccessCode=" + previousAccessCode + " currentAccessCode=" + currentAccessCode);
- updateRequired = true;
- }
+ String previousAccessCode = (String) context.getProperty(PREVIOUS_ACCESS_CODE_PROPERTY_NAME);
+ String currentAccessCode = (String) doc.getProperty(TaxonBotGardenConstants.ACCESS_CODE_SCHEMA_NAME, TaxonBotGardenConstants.ACCESS_CODE_FIELD_NAME);
+
+ if (previousAccessCode == null) {
+ previousAccessCode = "";
+ }
+
+ if (currentAccessCode == null) {
+ currentAccessCode = "";
+ }
+
+ if (previousAccessCode.equals(currentAccessCode)) {
+ logger.debug("update not required: previousAccessCode=" + previousAccessCode + " currentAccessCode=" + currentAccessCode);
}
- else if (event.getName().equals(DocumentEventTypes.DOCUMENT_CREATED)) {
+ else {
+ logger.debug("update required: previousAccessCode=" + previousAccessCode + " currentAccessCode=" + currentAccessCode);
updateRequired = true;
}
+ }
+ else if (event.getName().equals(DocumentEventTypes.DOCUMENT_CREATED)) {
+ updateRequired = true;
+ }
- if (updateRequired) {
- String taxonCsid = doc.getName();
+ if (updateRequired) {
+ String taxonCsid = doc.getName();
- try {
- // Pass false for the second parameter to updateReferencedAccessCodes, so that it doesn't
- // propagate changes up the taxon hierarchy. Propagation is taken care of by this
- // event handler: As taxon records are modified, this handler executes, and updates the
- // parent.
+ try {
+ // Pass false for the second parameter to updateReferencedAccessCodes, so that it doesn't
+ // propagate changes up the taxon hierarchy. Propagation is taken care of by this
+ // event handler: As taxon records are modified, this handler executes, and updates the
+ // parent.
- InvocationResults results = createUpdater().updateParentAccessCode(taxonCsid, false);
+ InvocationResults results = createUpdater(context).updateParentAccessCode(taxonCsid, false);
- logger.debug("updateParentAccessCode complete: numAffected=" + results.getNumAffected() + " userNote=" + results.getUserNote());
- }
- catch (Exception e) {
- logger.error(e.getMessage(), e);
- }
+ logger.debug("updateParentAccessCode complete: numAffected=" + results.getNumAffected() + " userNote=" + results.getUserNote());
+ }
+ catch (Exception e) {
+ logger.error(e.getMessage(), e);
}
}
}
- else if (doc.getType().equals(RelationConstants.NUXEO_DOCTYPE) &&
- !doc.isVersion() &&
- !doc.isProxy()) {
+ }
+ else if (doc.getType().equals(RelationConstants.NUXEO_DOCTYPE) &&
+ !doc.isVersion() &&
+ !doc.isProxy()) {
- if (event.getName().equals(DocumentEventTypes.DOCUMENT_CREATED)) {
- String subjectDocType = (String) doc.getProperty(RelationConstants.SUBJECT_DOCTYPE_SCHEMA_NAME, RelationConstants.SUBJECT_DOCTYPE_FIELD_NAME);
- String objectDocType = (String) doc.getProperty(RelationConstants.OBJECT_DOCTYPE_SCHEMA_NAME, RelationConstants.OBJECT_DOCTYPE_FIELD_NAME);;
- String relationType = (String) doc.getProperty(RelationConstants.TYPE_SCHEMA_NAME, RelationConstants.TYPE_FIELD_NAME);
+ if (event.getName().equals(DocumentEventTypes.DOCUMENT_CREATED)) {
+ String subjectDocType = (String) doc.getProperty(RelationConstants.SUBJECT_DOCTYPE_SCHEMA_NAME, RelationConstants.SUBJECT_DOCTYPE_FIELD_NAME);
+ String objectDocType = (String) doc.getProperty(RelationConstants.OBJECT_DOCTYPE_SCHEMA_NAME, RelationConstants.OBJECT_DOCTYPE_FIELD_NAME);;
+ String relationType = (String) doc.getProperty(RelationConstants.TYPE_SCHEMA_NAME, RelationConstants.TYPE_FIELD_NAME);
- logger.debug("subjectDocType=" + subjectDocType + " objectDocType=" + objectDocType + " relationType=" + relationType);
+ logger.debug("subjectDocType=" + subjectDocType + " objectDocType=" + objectDocType + " relationType=" + relationType);
- if (subjectDocType.equals(TaxonConstants.NUXEO_DOCTYPE) && objectDocType.equals(TaxonConstants.NUXEO_DOCTYPE) && relationType.equals(RelationConstants.BROADER_TYPE)) {
- String parentTaxonCsid = (String) doc.getProperty(RelationConstants.OBJECT_CSID_SCHEMA_NAME, RelationConstants.OBJECT_CSID_FIELD_NAME);
- logger.debug("child added, updating parent taxon: parentTaxonCsid=" + parentTaxonCsid);
+ if (subjectDocType.equals(TaxonConstants.NUXEO_DOCTYPE) && objectDocType.equals(TaxonConstants.NUXEO_DOCTYPE) && relationType.equals(RelationConstants.BROADER_TYPE)) {
+ String parentTaxonCsid = (String) doc.getProperty(RelationConstants.OBJECT_CSID_SCHEMA_NAME, RelationConstants.OBJECT_CSID_FIELD_NAME);
+ String childTaxonCsid = (String) doc.getProperty(RelationConstants.SUBJECT_CSID_SCHEMA_NAME, RelationConstants.SUBJECT_CSID_FIELD_NAME);
- try {
- InvocationResults results = createUpdater().updateAccessCode(parentTaxonCsid, false);
+ logger.debug("child added, updating parent taxon: parentTaxonCsid=" + parentTaxonCsid + " childTaxonCsid=" + childTaxonCsid);
- logger.debug("updateAccessCode complete: numAffected=" + results.getNumAffected() + " userNote=" + results.getUserNote());
- }
- catch (Exception e) {
- logger.error(e.getMessage(), e);
- }
+ try {
+ UpdateAccessCodeResults results = createUpdater(context).updateAccessCode(parentTaxonCsid, false, childTaxonCsid);
+
+ logger.debug("updateAccessCode complete: numAffected=" + results.getNumAffected());
+ }
+ catch (Exception e) {
+ logger.error(e.getMessage(), e);
}
}
- else if (event.getName().equals(DocumentEventTypes.ABOUT_TO_REMOVE)) {
- String subjectDocType = (String) doc.getProperty(RelationConstants.SUBJECT_DOCTYPE_SCHEMA_NAME, RelationConstants.SUBJECT_DOCTYPE_FIELD_NAME);
- String objectDocType = (String) doc.getProperty(RelationConstants.OBJECT_DOCTYPE_SCHEMA_NAME, RelationConstants.OBJECT_DOCTYPE_FIELD_NAME);;
- String relationType = (String) doc.getProperty(RelationConstants.TYPE_SCHEMA_NAME, RelationConstants.TYPE_FIELD_NAME);
+ }
+ else if (event.getName().equals(DocumentEventTypes.ABOUT_TO_REMOVE)) {
+ String subjectDocType = (String) doc.getProperty(RelationConstants.SUBJECT_DOCTYPE_SCHEMA_NAME, RelationConstants.SUBJECT_DOCTYPE_FIELD_NAME);
+ String objectDocType = (String) doc.getProperty(RelationConstants.OBJECT_DOCTYPE_SCHEMA_NAME, RelationConstants.OBJECT_DOCTYPE_FIELD_NAME);;
+ String relationType = (String) doc.getProperty(RelationConstants.TYPE_SCHEMA_NAME, RelationConstants.TYPE_FIELD_NAME);
- logger.debug("subjectDocType=" + subjectDocType + " objectDocType=" + objectDocType + " relationType=" + relationType);
+ logger.debug("subjectDocType=" + subjectDocType + " objectDocType=" + objectDocType + " relationType=" + relationType);
- if (subjectDocType.equals(TaxonConstants.NUXEO_DOCTYPE) && objectDocType.equals(TaxonConstants.NUXEO_DOCTYPE) && relationType.equals(RelationConstants.BROADER_TYPE)) {
- String parentTaxonCsid = (String) doc.getProperty(RelationConstants.OBJECT_CSID_SCHEMA_NAME, RelationConstants.OBJECT_CSID_FIELD_NAME);
+ if (subjectDocType.equals(TaxonConstants.NUXEO_DOCTYPE) && objectDocType.equals(TaxonConstants.NUXEO_DOCTYPE) && relationType.equals(RelationConstants.BROADER_TYPE)) {
+ String parentTaxonCsid = (String) doc.getProperty(RelationConstants.OBJECT_CSID_SCHEMA_NAME, RelationConstants.OBJECT_CSID_FIELD_NAME);
- // Stash the parent taxon csid, so it can be retrieved in the documentRemoved handler.
- logger.debug("about to delete taxon hierarchy relation: parentTaxonCsid=" + parentTaxonCsid);
- context.setProperty(DELETED_RELATION_PARENT_CSID_PROPERTY_NAME, parentTaxonCsid);
- }
+ // Stash the parent taxon csid, so it can be retrieved in the documentRemoved handler.
+ logger.debug("about to delete taxon hierarchy relation: parentTaxonCsid=" + parentTaxonCsid);
+ context.setProperty(DELETED_RELATION_PARENT_CSID_PROPERTY_NAME, parentTaxonCsid);
}
- else if (event.getName().equals(DocumentEventTypes.DOCUMENT_REMOVED)) {
- String parentTaxonCsid = (String) context.getProperty(DELETED_RELATION_PARENT_CSID_PROPERTY_NAME);
+ }
+ else if (event.getName().equals(DocumentEventTypes.DOCUMENT_REMOVED)) {
+ String parentTaxonCsid = (String) context.getProperty(DELETED_RELATION_PARENT_CSID_PROPERTY_NAME);
- if (StringUtils.isNotEmpty(parentTaxonCsid)) {
- logger.debug("child removed, updating parent taxon: parentTaxonCsid=" + parentTaxonCsid);
+ if (StringUtils.isNotEmpty(parentTaxonCsid)) {
+ logger.debug("child removed, updating parent taxon: parentTaxonCsid=" + parentTaxonCsid);
- try {
- InvocationResults results = createUpdater().updateAccessCode(parentTaxonCsid, false);
+ try {
+ InvocationResults results = createUpdater(context).updateAccessCode(parentTaxonCsid, false);
- logger.debug("updateAccessCode complete: numAffected=" + results.getNumAffected() + " userNote=" + results.getUserNote());
- }
- catch (Exception e) {
- logger.error(e.getMessage(), e);
- }
+ logger.debug("updateAccessCode complete: numAffected=" + results.getNumAffected() + " userNote=" + results.getUserNote());
+ }
+ catch (Exception e) {
+ logger.error(e.getMessage(), e);
}
}
}
return addedTaxonNameSet;
}
- private UpdateAccessCodeBatchJob createUpdater() {
+ private UpdateAccessCodeBatchJob createUpdater(DocumentEventContext context) throws Exception {
ResourceMap resourceMap = ResteasyProviderFactory.getContextData(ResourceMap.class);
+ BatchResource batchResource = (BatchResource) resourceMap.get(BatchClient.SERVICE_NAME);
+ ServiceContext<PoxPayloadIn, PoxPayloadOut> serviceContext = batchResource.createServiceContext(batchResource.getServiceName());
+
+ serviceContext.setCurrentRepositorySession(new CoreSessionWrapper(context.getCoreSession()));
UpdateAccessCodeBatchJob updater = new UpdateAccessCodeBatchJob();
+ updater.setServiceContext(serviceContext);
updater.setResourceMap(resourceMap);
return updater;
}
+
+ @Override
+ public Log getLogger() {
+ return logger;
+ }
}
package org.collectionspace.services.listener.botgarden;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.collectionspace.services.batch.BatchResource;
import org.collectionspace.services.batch.nuxeo.UpdateDeadFlagBatchJob;
+import org.collectionspace.services.client.BatchClient;
+import org.collectionspace.services.client.PoxPayloadIn;
+import org.collectionspace.services.client.PoxPayloadOut;
import org.collectionspace.services.client.workflow.WorkflowClient;
import org.collectionspace.services.collectionobject.nuxeo.CollectionObjectConstants;
import org.collectionspace.services.common.ResourceMap;
+import org.collectionspace.services.common.context.ServiceContext;
import org.collectionspace.services.common.invocable.InvocationResults;
import org.collectionspace.services.common.relation.nuxeo.RelationConstants;
import org.collectionspace.services.movement.nuxeo.MovementBotGardenConstants;
import org.collectionspace.services.movement.nuxeo.MovementConstants;
-import org.collectionspace.services.nuxeo.listener.AbstractCSEventListenerImpl;
+import org.collectionspace.services.nuxeo.client.java.CoreSessionWrapper;
+import org.collectionspace.services.nuxeo.listener.AbstractCSEventSyncListenerImpl;
+
import org.jboss.resteasy.spi.ResteasyProviderFactory;
+
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.event.DocumentEventTypes;
import org.nuxeo.ecm.core.event.Event;
import org.nuxeo.ecm.core.event.EventContext;
import org.nuxeo.ecm.core.event.impl.DocumentEventContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-public class UpdateDeadFlagListener extends AbstractCSEventListenerImpl {
- final Logger logger = LoggerFactory.getLogger(UpdateDeadFlagListener.class);
+public class UpdateDeadFlagListener extends AbstractCSEventSyncListenerImpl {
+ static final Log logger = LogFactory.getLog(UpdateDeadFlagListener.class);
+ @Override
+ public boolean shouldHandleEvent(Event event) {
+ return event.getContext() instanceof DocumentEventContext;
+ }
+
/*
* Set the dead flag and dead date on collectionobjects related to a new or modified movement record.
*/
@Override
- public void handleEvent(Event event) {
+ public void handleCSEvent(Event event) {
EventContext ec = event.getContext();
-
- if (isRegistered(event) && ec instanceof DocumentEventContext) {
- DocumentEventContext context = (DocumentEventContext) ec;
- DocumentModel doc = context.getSourceDocument();
-
- logger.debug("docType=" + doc.getType());
-
- if (event.getName().equals(DocumentEventTypes.DOCUMENT_CREATED)) {
- /*
- * Handle the case where a new movement is created with action code revive, and then related
- * to a collectionobject. The movement won't have any relations at the time it's created,
- * so we need to capture the creation of the relation.
- */
- if (doc.getType().equals(RelationConstants.NUXEO_DOCTYPE) &&
- !doc.isVersion() &&
- !doc.isProxy()) {
- String subjectDocType = (String) doc.getProperty(RelationConstants.SUBJECT_DOCTYPE_SCHEMA_NAME, RelationConstants.SUBJECT_DOCTYPE_FIELD_NAME);
- String objectDocType = (String) doc.getProperty(RelationConstants.OBJECT_DOCTYPE_SCHEMA_NAME, RelationConstants.OBJECT_DOCTYPE_FIELD_NAME);;
-
- logger.debug("subjectDocType=" + subjectDocType + " objectDocType=" + objectDocType);
-
- if (subjectDocType.equals(MovementConstants.NUXEO_DOCTYPE) && objectDocType.equals(CollectionObjectConstants.NUXEO_DOCTYPE)) {
- String movementCsid = (String) doc.getProperty(RelationConstants.SUBJECT_CSID_SCHEMA_NAME, RelationConstants.SUBJECT_CSID_FIELD_NAME);
- String collectionObjectCsid = (String) doc.getProperty(RelationConstants.OBJECT_CSID_SCHEMA_NAME, RelationConstants.OBJECT_CSID_FIELD_NAME);
-
- try {
- InvocationResults results = createUpdater().updateDeadFlag(collectionObjectCsid, movementCsid);
-
- logger.debug("updateDeadFlag complete: numAffected=" + results.getNumAffected() + " userNote=" + results.getUserNote());
- } catch (Exception e) {
- logger.error(e.getMessage(), e);
- }
+ DocumentEventContext context = (DocumentEventContext) ec;
+ DocumentModel doc = context.getSourceDocument();
+
+ logger.debug("docType=" + doc.getType());
+
+ if (event.getName().equals(DocumentEventTypes.DOCUMENT_CREATED)) {
+ /*
+ * Handle the case where a new movement is created with action code revive, and then related
+ * to a collectionobject. The movement won't have any relations at the time it's created,
+ * so we need to capture the creation of the relation.
+ */
+ if (doc.getType().equals(RelationConstants.NUXEO_DOCTYPE) &&
+ !doc.isVersion() &&
+ !doc.isProxy()) {
+ String subjectDocType = (String) doc.getProperty(RelationConstants.SUBJECT_DOCTYPE_SCHEMA_NAME, RelationConstants.SUBJECT_DOCTYPE_FIELD_NAME);
+ String objectDocType = (String) doc.getProperty(RelationConstants.OBJECT_DOCTYPE_SCHEMA_NAME, RelationConstants.OBJECT_DOCTYPE_FIELD_NAME);;
+
+ logger.debug("subjectDocType=" + subjectDocType + " objectDocType=" + objectDocType);
+
+ if (subjectDocType.equals(MovementConstants.NUXEO_DOCTYPE) && objectDocType.equals(CollectionObjectConstants.NUXEO_DOCTYPE)) {
+ String movementCsid = (String) doc.getProperty(RelationConstants.SUBJECT_CSID_SCHEMA_NAME, RelationConstants.SUBJECT_CSID_FIELD_NAME);
+ String collectionObjectCsid = (String) doc.getProperty(RelationConstants.OBJECT_CSID_SCHEMA_NAME, RelationConstants.OBJECT_CSID_FIELD_NAME);
+
+ try {
+ InvocationResults results = createUpdater(context).updateDeadFlag(collectionObjectCsid, movementCsid);
+
+ logger.debug("updateDeadFlag complete: numAffected=" + results.getNumAffected() + " userNote=" + results.getUserNote());
+ } catch (Exception e) {
+ logger.error(e.getMessage(), e);
}
}
}
- else {
- /*
- * Handle document modification. If the modified document was a movement record, and
- * its action code is dead or revived, update the dead flag. We don't actually have to
- * check the action code here, since it will be checked inside UpdateDeadFlagBatchJob.updateRelatedDeadFlags,
- * but it is an optimization.
- */
- if (doc.getType().startsWith(MovementConstants.NUXEO_DOCTYPE) &&
- !doc.isVersion() &&
- !doc.isProxy() &&
- !doc.getCurrentLifeCycleState().equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
- String actionCode = (String) doc.getProperty(MovementBotGardenConstants.ACTION_CODE_SCHEMA_NAME, MovementBotGardenConstants.ACTION_CODE_FIELD_NAME);
-
- logger.debug("actionCode=" + actionCode);
-
- if (actionCode != null && (actionCode.equals(MovementBotGardenConstants.DEAD_ACTION_CODE) || actionCode.equals(MovementBotGardenConstants.REVIVED_ACTION_CODE))) {
- String movementCsid = doc.getName();
-
- try {
- InvocationResults results = createUpdater().updateRelatedDeadFlags(movementCsid);
-
- logger.debug("updateRelatedDeadFlags complete: numAffected=" + results.getNumAffected() + " userNote=" + results.getUserNote());
- } catch (Exception e) {
- logger.error(e.getMessage(), e);
- }
+ }
+ else {
+ /*
+ * Handle document modification. If the modified document was a movement record, and
+ * its action code is dead or revived, update the dead flag. We don't actually have to
+ * check the action code here, since it will be checked inside UpdateDeadFlagBatchJob.updateRelatedDeadFlags,
+ * but it is an optimization.
+ */
+ if (doc.getType().startsWith(MovementConstants.NUXEO_DOCTYPE) &&
+ !doc.isVersion() &&
+ !doc.isProxy() &&
+ !doc.getCurrentLifeCycleState().equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
+ String actionCode = (String) doc.getProperty(MovementBotGardenConstants.ACTION_CODE_SCHEMA_NAME, MovementBotGardenConstants.ACTION_CODE_FIELD_NAME);
+
+ logger.debug("actionCode=" + actionCode);
+
+ if (actionCode != null && (actionCode.equals(MovementBotGardenConstants.DEAD_ACTION_CODE) || actionCode.equals(MovementBotGardenConstants.REVIVED_ACTION_CODE))) {
+ String movementCsid = doc.getName();
+
+ try {
+ InvocationResults results = createUpdater(context).updateRelatedDeadFlags(movementCsid);
+
+ logger.debug("updateRelatedDeadFlags complete: numAffected=" + results.getNumAffected() + " userNote=" + results.getUserNote());
+ } catch (Exception e) {
+ logger.error(e.getMessage(), e);
}
}
}
}
- }
+ }
- private UpdateDeadFlagBatchJob createUpdater() {
+ private UpdateDeadFlagBatchJob createUpdater(DocumentEventContext context) throws Exception {
ResourceMap resourceMap = ResteasyProviderFactory.getContextData(ResourceMap.class);
+ BatchResource batchResource = (BatchResource) resourceMap.get(BatchClient.SERVICE_NAME);
+ ServiceContext<PoxPayloadIn, PoxPayloadOut> serviceContext = batchResource.createServiceContext(batchResource.getServiceName());
+
+ serviceContext.setCurrentRepositorySession(new CoreSessionWrapper(context.getCoreSession()));
UpdateDeadFlagBatchJob updater = new UpdateDeadFlagBatchJob();
+ updater.setServiceContext(serviceContext);
updater.setResourceMap(resourceMap);
return updater;
}
-}
+
+ @Override
+ public Log getLogger() {
+ return logger;
+ }
+}
\ No newline at end of file
package org.collectionspace.services.listener.botgarden;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
import org.collectionspace.services.client.workflow.WorkflowClient;
import org.collectionspace.services.movement.nuxeo.MovementBotGardenConstants;
import org.collectionspace.services.movement.nuxeo.MovementConstants;
-import org.collectionspace.services.nuxeo.listener.AbstractCSEventListenerImpl;
+import org.collectionspace.services.nuxeo.listener.AbstractCSEventSyncListenerImpl;
+
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.event.CoreEventConstants;
import org.nuxeo.ecm.core.api.event.DocumentEventTypes;
import org.nuxeo.ecm.core.event.Event;
import org.nuxeo.ecm.core.event.EventContext;
import org.nuxeo.ecm.core.event.impl.DocumentEventContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-public class UpdateLocationListener extends AbstractCSEventListenerImpl {
- final Logger logger = LoggerFactory.getLogger(UpdateLocationListener.class);
+public class UpdateLocationListener extends AbstractCSEventSyncListenerImpl {
+ static final Log logger = LogFactory.getLog(UpdateLocationListener.class);
+
+ @Override
+ public boolean shouldHandleEvent(Event event) {
+ EventContext ec = event.getContext();
+ if (ec instanceof DocumentEventContext) {
+ DocumentEventContext context = (DocumentEventContext) ec;
+ DocumentModel doc = context.getSourceDocument();
+
+ if (doc.getType().startsWith(MovementConstants.NUXEO_DOCTYPE) &&
+ !doc.isVersion() &&
+ !doc.isProxy() &&
+ !doc.getCurrentLifeCycleState().equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
/*
* Set the currentLocation and previousLocation fields in a Current Location record
* to appropriate values.
* </ui>
*/
@Override
- public void handleEvent(Event event) {
+ public void handleCSEvent(Event event) {
EventContext ec = event.getContext();
+ DocumentEventContext context = (DocumentEventContext) ec;
+ DocumentModel doc = context.getSourceDocument();
- if (isRegistered(event) && ec instanceof DocumentEventContext) {
- DocumentEventContext context = (DocumentEventContext) ec;
- DocumentModel doc = context.getSourceDocument();
-
- if (doc.getType().startsWith(MovementConstants.NUXEO_DOCTYPE) &&
- !doc.isVersion() &&
- !doc.isProxy() &&
- !doc.getCurrentLifeCycleState().equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
- String actionCode = (String) doc.getProperty(MovementBotGardenConstants.ACTION_CODE_SCHEMA_NAME,
- MovementBotGardenConstants.ACTION_CODE_FIELD_NAME);
+ String actionCode = (String) doc.getProperty(MovementBotGardenConstants.ACTION_CODE_SCHEMA_NAME,
+ MovementBotGardenConstants.ACTION_CODE_FIELD_NAME);
- logger.debug("actionCode=" + actionCode);
+ logger.debug("actionCode=" + actionCode);
- if (event.getName().equals(DocumentEventTypes.DOCUMENT_CREATED)) {
- /*
- * Special case for a document that is created with an action code of dead.
- * In this case, we'll set the currentLocation to none, and the previousLocation to
- * the current value of currentLocation, since there isn't a previous value. To do
- * this, we can simply save the document, which will cause the beforeDocumentModification
- * event to fire, taking us into the other branch of this code, with the current document
- * becoming the previous document.
- */
- if (actionCode != null && actionCode.equals(MovementBotGardenConstants.DEAD_ACTION_CODE)) {
- context.getCoreSession().saveDocument(doc);
+ if (event.getName().equals(DocumentEventTypes.DOCUMENT_CREATED)) {
+ /*
+ * Special case for a document that is created with an action code of dead.
+ * In this case, we'll set the currentLocation to none, and the previousLocation to
+ * the current value of currentLocation, since there isn't a previous value. To do
+ * this, we can simply save the document, which will cause the beforeDocumentModification
+ * event to fire, taking us into the other branch of this code, with the current document
+ * becoming the previous document.
+ */
+ if (actionCode != null && actionCode.equals(MovementBotGardenConstants.DEAD_ACTION_CODE)) {
+ context.getCoreSession().saveDocument(doc);
- /*
- * The saveDocument call will have caused the document to be versioned via documentModified,
- * so we can skip the versioning that would normally happen on documentCreated.
- */
- ec.setProperty(CreateVersionListener.SKIP_PROPERTY, true);
- }
- }
- else {
- if (actionCode != null && actionCode.equals(MovementBotGardenConstants.DEAD_ACTION_CODE)) {
- doc.setProperty(MovementConstants.CURRENT_LOCATION_SCHEMA_NAME, MovementConstants.CURRENT_LOCATION_FIELD_NAME, MovementConstants.NONE_LOCATION);
- }
+ /*
+ * The saveDocument call will have caused the document to be versioned via documentModified,
+ * so we can skip the versioning that would normally happen on documentCreated.
+ */
+ ec.setProperty(CreateVersionListener.SKIP_PROPERTY, true);
+ }
+ }
+ else {
+ if (actionCode != null && actionCode.equals(MovementBotGardenConstants.DEAD_ACTION_CODE)) {
+ doc.setProperty(MovementConstants.CURRENT_LOCATION_SCHEMA_NAME, MovementConstants.CURRENT_LOCATION_FIELD_NAME, MovementConstants.NONE_LOCATION);
+ }
- DocumentModel previousDoc = (DocumentModel) context.getProperty(CoreEventConstants.PREVIOUS_DOCUMENT_MODEL);
- String previousLocation = (String) previousDoc.getProperty(MovementConstants.CURRENT_LOCATION_SCHEMA_NAME, MovementConstants.CURRENT_LOCATION_FIELD_NAME);
+ DocumentModel previousDoc = (DocumentModel) context.getProperty(CoreEventConstants.PREVIOUS_DOCUMENT_MODEL);
+ String previousLocation = (String) previousDoc.getProperty(MovementConstants.CURRENT_LOCATION_SCHEMA_NAME, MovementConstants.CURRENT_LOCATION_FIELD_NAME);
- logger.debug("previousLocation=" + previousLocation);
+ logger.debug("previousLocation=" + previousLocation);
- doc.setProperty(MovementConstants.PREVIOUS_LOCATION_SCHEMA_NAME, MovementConstants.PREVIOUS_LOCATION_FIELD_NAME, previousLocation);
- }
- }
+ doc.setProperty(MovementConstants.PREVIOUS_LOCATION_SCHEMA_NAME, MovementConstants.PREVIOUS_LOCATION_FIELD_NAME, previousLocation);
}
}
-}
+
+ @Override
+ public Log getLogger() {
+ return logger;
+ }
+}
\ No newline at end of file
import java.util.List;
import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.collectionspace.services.batch.BatchResource;
import org.collectionspace.services.batch.nuxeo.UpdateRareFlagBatchJob;
+import org.collectionspace.services.client.BatchClient;
+import org.collectionspace.services.client.PoxPayloadIn;
+import org.collectionspace.services.client.PoxPayloadOut;
import org.collectionspace.services.client.workflow.WorkflowClient;
import org.collectionspace.services.collectionobject.nuxeo.CollectionObjectBotGardenConstants;
import org.collectionspace.services.collectionobject.nuxeo.CollectionObjectConstants;
import org.collectionspace.services.common.ResourceMap;
+import org.collectionspace.services.common.context.ServiceContext;
import org.collectionspace.services.common.invocable.InvocationResults;
-import org.collectionspace.services.nuxeo.listener.AbstractCSEventListenerImpl;
+import org.collectionspace.services.nuxeo.client.java.CoreSessionWrapper;
+import org.collectionspace.services.nuxeo.listener.AbstractCSEventSyncListenerImpl;
import org.collectionspace.services.taxonomy.nuxeo.TaxonBotGardenConstants;
import org.collectionspace.services.taxonomy.nuxeo.TaxonConstants;
+import org.collectionspace.services.taxonomy.nuxeo.TaxonomyAuthorityConstants;
+
import org.jboss.resteasy.spi.ResteasyProviderFactory;
+
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.event.CoreEventConstants;
import org.nuxeo.ecm.core.api.event.DocumentEventTypes;
import org.nuxeo.ecm.core.event.Event;
import org.nuxeo.ecm.core.event.EventContext;
import org.nuxeo.ecm.core.event.impl.DocumentEventContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* A listener that updates the rare flag on collectionobjects when collectionobjects
* @author ray
*
*/
-public class UpdateRareFlagListener extends AbstractCSEventListenerImpl {
- final Logger logger = LoggerFactory.getLogger(UpdateRareFlagListener.class);
+public class UpdateRareFlagListener extends AbstractCSEventSyncListenerImpl {
+ static final Log logger = LogFactory.getLog(UpdateRareFlagListener.class);
public static final String PREVIOUS_TAXON_PROPERTY_NAME = "UpdateRareFlagListener.previousTaxon";
public static final String PREVIOUS_HAS_RARE_CONSERVATION_CATEGORY_PROPERTY_NAME = "UpdateRareFlagListener.previousHasRareConservationCategory";
private static final String PLANT_ATTRIBUTES_GROUP_LIST_FIELD_NAME = CONSERVATION_CATEGORY_PATH_ELEMENTS[0];
private static final String CONSERVATION_CATEGORY_FIELD_NAME = CONSERVATION_CATEGORY_PATH_ELEMENTS[2];
+ @Override
+ public boolean shouldHandleEvent(Event event) {
+ return event.getContext() instanceof DocumentEventContext;
+ }
+
@Override
- public void handleEvent(Event event) {
+ public void handleCSEvent(Event event) {
EventContext ec = event.getContext();
+ DocumentEventContext context = (DocumentEventContext) ec;
+ DocumentModel doc = context.getSourceDocument();
+ String docType = doc.getType();
- if (isRegistered(event) && ec instanceof DocumentEventContext) {
- DocumentEventContext context = (DocumentEventContext) ec;
- DocumentModel doc = context.getSourceDocument();
+ logger.debug("docType=" + docType);
- logger.debug("docType=" + doc.getType());
+ if (docType.startsWith(CollectionObjectConstants.NUXEO_DOCTYPE) &&
+ !doc.isVersion() &&
+ !doc.isProxy() &&
+ !doc.getCurrentLifeCycleState().equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
- if (doc.getType().startsWith(CollectionObjectConstants.NUXEO_DOCTYPE) &&
- !doc.isVersion() &&
- !doc.isProxy() &&
- !doc.getCurrentLifeCycleState().equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
+ if (event.getName().equals(DocumentEventTypes.BEFORE_DOC_UPDATE)) {
+ // Stash the previous primary taxonomic ident, so it can be retrieved in the documentModified handler.
- if (event.getName().equals(DocumentEventTypes.BEFORE_DOC_UPDATE)) {
- // Stash the previous primary taxonomic ident, so it can be retrieved in the documentModified handler.
+ DocumentModel previousDoc = (DocumentModel) context.getProperty(CoreEventConstants.PREVIOUS_DOCUMENT_MODEL);
+ String previousTaxon = (String) previousDoc.getProperty(CollectionObjectBotGardenConstants.TAXON_SCHEMA_NAME,
+ CollectionObjectBotGardenConstants.PRIMARY_TAXON_FIELD_NAME);
- DocumentModel previousDoc = (DocumentModel) context.getProperty(CoreEventConstants.PREVIOUS_DOCUMENT_MODEL);
- String previousTaxon = (String) previousDoc.getProperty(CollectionObjectBotGardenConstants.TAXON_SCHEMA_NAME,
+ context.setProperty(PREVIOUS_TAXON_PROPERTY_NAME, previousTaxon);
+ }
+ else {
+ boolean updateRequired = false;
+
+ if (event.getName().equals(DocumentEventTypes.DOCUMENT_UPDATED)) {
+ // A collectionobject was modified. As an optimization, check if the primary taxonomic determination
+ // of the collectionobject has changed. We only need to update the rare flag if it has.
+
+ String previousTaxon = (String) context.getProperty(PREVIOUS_TAXON_PROPERTY_NAME);
+ String currentTaxon = (String) doc.getProperty(CollectionObjectBotGardenConstants.TAXON_SCHEMA_NAME,
CollectionObjectBotGardenConstants.PRIMARY_TAXON_FIELD_NAME);
- context.setProperty(PREVIOUS_TAXON_PROPERTY_NAME, previousTaxon);
- }
- else {
- boolean updateRequired = false;
-
- if (event.getName().equals(DocumentEventTypes.DOCUMENT_UPDATED)) {
- // A collectionobject was modified. As an optimization, check if the primary taxonomic determination
- // of the collectionobject has changed. We only need to update the rare flag if it has.
-
- String previousTaxon = (String) context.getProperty(PREVIOUS_TAXON_PROPERTY_NAME);
- String currentTaxon = (String) doc.getProperty(CollectionObjectBotGardenConstants.TAXON_SCHEMA_NAME,
- CollectionObjectBotGardenConstants.PRIMARY_TAXON_FIELD_NAME);
-
- if (previousTaxon == null) {
- previousTaxon = "";
- }
-
- if (currentTaxon == null) {
- currentTaxon = "";
- }
-
- if (previousTaxon.equals(currentTaxon)) {
- logger.debug("update not required: previousTaxon=" + previousTaxon + " currentTaxon=" + currentTaxon);
- }
- else {
- logger.debug("update required: previousTaxon=" + previousTaxon + " currentTaxon=" + currentTaxon);
- updateRequired = true;
- }
+ if (previousTaxon == null) {
+ previousTaxon = "";
}
- else if (event.getName().equals(DocumentEventTypes.DOCUMENT_CREATED)) {
- // A collectionobject was created. Always update the rare flag.
+ if (currentTaxon == null) {
+ currentTaxon = "";
+ }
+
+ if (previousTaxon.equals(currentTaxon)) {
+ logger.debug("update not required: previousTaxon=" + previousTaxon + " currentTaxon=" + currentTaxon);
+ }
+ else {
+ logger.debug("update required: previousTaxon=" + previousTaxon + " currentTaxon=" + currentTaxon);
updateRequired = true;
}
+ }
+ else if (event.getName().equals(DocumentEventTypes.DOCUMENT_CREATED)) {
+ // A collectionobject was created. Always update the rare flag.
+
+ updateRequired = true;
+ }
- if (updateRequired) {
- String collectionObjectCsid = doc.getName();
+ if (updateRequired) {
+ String collectionObjectCsid = doc.getName();
- try {
- InvocationResults results = createUpdater().updateRareFlag(collectionObjectCsid);
+ try {
+ InvocationResults results = createUpdater(context).updateRareFlag(collectionObjectCsid);
- logger.debug("updateRareFlag complete: numAffected=" + results.getNumAffected() + " userNote=" + results.getUserNote());
- } catch (Exception e) {
- logger.error(e.getMessage(), e);
- }
+ logger.debug("updateRareFlag complete: numAffected=" + results.getNumAffected() + " userNote=" + results.getUserNote());
+ } catch (Exception e) {
+ logger.error(e.getMessage(), e);
}
}
}
- else if (doc.getType().startsWith(TaxonConstants.NUXEO_DOCTYPE) &&
- !doc.isVersion() &&
- !doc.isProxy() &&
- !doc.getCurrentLifeCycleState().equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
+ }
+ else if (docType.startsWith(TaxonConstants.NUXEO_DOCTYPE) &&
+ !docType.startsWith(TaxonomyAuthorityConstants.NUXEO_DOCTYPE) &&
+ !doc.isVersion() &&
+ !doc.isProxy() &&
+ !doc.getCurrentLifeCycleState().equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
- if (event.getName().equals(DocumentEventTypes.BEFORE_DOC_UPDATE)) {
- // Stash whether there was previously a non-empty conservation category, so it can be retrieved in the documentModified handler.
+ if (event.getName().equals(DocumentEventTypes.BEFORE_DOC_UPDATE)) {
+ // Stash whether there was previously a non-empty conservation category, so it can be retrieved in the documentModified handler.
- DocumentModel previousDoc = (DocumentModel) context.getProperty(CoreEventConstants.PREVIOUS_DOCUMENT_MODEL);
- boolean previousHasRareConservationCategory = hasRareConservationCategory(previousDoc);
+ DocumentModel previousDoc = (DocumentModel) context.getProperty(CoreEventConstants.PREVIOUS_DOCUMENT_MODEL);
+ boolean previousHasRareConservationCategory = hasRareConservationCategory(previousDoc);
- context.setProperty(PREVIOUS_HAS_RARE_CONSERVATION_CATEGORY_PROPERTY_NAME, new Boolean(previousHasRareConservationCategory));
- }
- else {
- boolean updateRequired = false;
-
- if (event.getName().equals(DocumentEventTypes.DOCUMENT_UPDATED)) {
- // A taxon record was modified. As an optimization, check if there is now a rare
- // conservation category when there wasn't before, or vice versa. We only need to update
- // the rare flags of referencing collectionobjects if there was a change.
-
- boolean previousHasRareConservationCategory = (Boolean) context.getProperty(PREVIOUS_HAS_RARE_CONSERVATION_CATEGORY_PROPERTY_NAME);
- boolean currentHasRareConservationCategory = hasRareConservationCategory(doc);
-
- if (previousHasRareConservationCategory == currentHasRareConservationCategory) {
- logger.debug("update not required: previousHasRareConservationCategory=" + previousHasRareConservationCategory +
- " currentHasRareConservationCategory=" + currentHasRareConservationCategory);
- }
- else {
- logger.debug("update required: previousHasRareConservationCategory=" + previousHasRareConservationCategory +
- " currentHasRareConservationCategory=" + currentHasRareConservationCategory);
- updateRequired = true;
- }
+ context.setProperty(PREVIOUS_HAS_RARE_CONSERVATION_CATEGORY_PROPERTY_NAME, new Boolean(previousHasRareConservationCategory));
+ }
+ else {
+ boolean updateRequired = false;
+
+ if (event.getName().equals(DocumentEventTypes.DOCUMENT_UPDATED)) {
+ // A taxon record was modified. As an optimization, check if there is now a rare
+ // conservation category when there wasn't before, or vice versa. We only need to update
+ // the rare flags of referencing collectionobjects if there was a change.
+
+ boolean previousHasRareConservationCategory = (Boolean) context.getProperty(PREVIOUS_HAS_RARE_CONSERVATION_CATEGORY_PROPERTY_NAME);
+ boolean currentHasRareConservationCategory = hasRareConservationCategory(doc);
+
+ if (previousHasRareConservationCategory == currentHasRareConservationCategory) {
+ logger.debug("update not required: previousHasRareConservationCategory=" + previousHasRareConservationCategory +
+ " currentHasRareConservationCategory=" + currentHasRareConservationCategory);
}
+ else {
+ logger.debug("update required: previousHasRareConservationCategory=" + previousHasRareConservationCategory +
+ " currentHasRareConservationCategory=" + currentHasRareConservationCategory);
+ updateRequired = true;
+ }
+ }
- if (updateRequired) {
- String taxonCsid = doc.getName();
+ if (updateRequired) {
+ String taxonCsid = doc.getName();
+ String vocabularyCsid = (String) doc.getProperty(TaxonConstants.IN_AUTHORITY_SCHEMA_NAME, TaxonConstants.IN_AUTHORITY_FIELD_NAME);
- try {
- InvocationResults results = createUpdater().updateReferencingRareFlags(taxonCsid);
+ try {
+ InvocationResults results = createUpdater(context).updateReferencingRareFlags(taxonCsid, vocabularyCsid);
- logger.debug("updateReferencingRareFlags complete: numAffected=" + results.getNumAffected() + " userNote=" + results.getUserNote());
- } catch (Exception e) {
- logger.error(e.getMessage(), e);
- }
+ logger.debug("updateReferencingRareFlags complete: numAffected=" + results.getNumAffected() + " userNote=" + results.getUserNote());
+ } catch (Exception e) {
+ logger.error(e.getMessage(), e);
}
}
}
return hasRareConservationCategory;
}
- private UpdateRareFlagBatchJob createUpdater() {
+ private UpdateRareFlagBatchJob createUpdater(DocumentEventContext context) throws Exception {
ResourceMap resourceMap = ResteasyProviderFactory.getContextData(ResourceMap.class);
+ BatchResource batchResource = (BatchResource) resourceMap.get(BatchClient.SERVICE_NAME);
+ ServiceContext<PoxPayloadIn, PoxPayloadOut> serviceContext = batchResource.createServiceContext(batchResource.getServiceName());
+
+ serviceContext.setCurrentRepositorySession(new CoreSessionWrapper(context.getCoreSession()));
UpdateRareFlagBatchJob updater = new UpdateRareFlagBatchJob();
+ updater.setServiceContext(serviceContext);
updater.setResourceMap(resourceMap);
return updater;
}
+
+ @Override
+ public Log getLogger() {
+ return logger;
+ }
}
package org.collectionspace.services.listener.botgarden;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
import org.jboss.resteasy.spi.ResteasyProviderFactory;
+import org.collectionspace.services.batch.BatchResource;
import org.collectionspace.services.batch.nuxeo.FormatVoucherNameBatchJob;
+import org.collectionspace.services.client.BatchClient;
+import org.collectionspace.services.client.PoxPayloadIn;
+import org.collectionspace.services.client.PoxPayloadOut;
import org.collectionspace.services.client.workflow.WorkflowClient;
import org.collectionspace.services.common.ResourceMap;
+import org.collectionspace.services.common.context.ServiceContext;
import org.collectionspace.services.loanout.nuxeo.LoanoutBotGardenConstants;
import org.collectionspace.services.loanout.nuxeo.LoanoutConstants;
-import org.collectionspace.services.nuxeo.listener.AbstractCSEventListenerImpl;
+import org.collectionspace.services.nuxeo.client.java.CoreSessionWrapper;
+import org.collectionspace.services.nuxeo.listener.AbstractCSEventSyncListenerImpl;
+
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.event.CoreEventConstants;
import org.nuxeo.ecm.core.api.event.DocumentEventTypes;
import org.nuxeo.ecm.core.event.Event;
import org.nuxeo.ecm.core.event.EventContext;
import org.nuxeo.ecm.core.event.impl.DocumentEventContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-public class UpdateStyledNameListener extends AbstractCSEventListenerImpl {
+public class UpdateStyledNameListener extends AbstractCSEventSyncListenerImpl {
public static final String RUN_AFTER_MODIFIED_PROPERTY = "UpdateStyledNameListener.RUN_AFTER_MODIFIED";
+ static final Log logger = LogFactory.getLog(UpdateStyledNameListener.class);
- final Logger logger = LoggerFactory.getLogger(UpdateStyledNameListener.class);
-
- @Override
- public void handleEvent(Event event) {
+ @Override
+ public boolean shouldHandleEvent(Event event) {
EventContext ec = event.getContext();
- if (isRegistered(event) && ec instanceof DocumentEventContext) {
+ if (ec instanceof DocumentEventContext) {
DocumentEventContext context = (DocumentEventContext) ec;
DocumentModel doc = context.getSourceDocument();
!doc.isVersion() &&
!doc.isProxy() &&
!doc.getCurrentLifeCycleState().equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public void handleCSEvent(Event event) {
+ EventContext ec = event.getContext();
+ DocumentEventContext context = (DocumentEventContext) ec;
+ DocumentModel doc = context.getSourceDocument();
- if (event.getName().equals(DocumentEventTypes.BEFORE_DOC_UPDATE)) {
- DocumentModel previousDoc = (DocumentModel) context.getProperty(CoreEventConstants.PREVIOUS_DOCUMENT_MODEL);
+ logger.debug("docType=" + doc.getType());
- String previousLabelRequested = (String) previousDoc.getProperty(LoanoutBotGardenConstants.LABEL_REQUESTED_SCHEMA_NAME,
- LoanoutBotGardenConstants.LABEL_REQUESTED_FIELD_NAME);
- String labelRequested = (String) doc.getProperty(LoanoutBotGardenConstants.LABEL_REQUESTED_SCHEMA_NAME,
- LoanoutBotGardenConstants.LABEL_REQUESTED_FIELD_NAME);
+ if (event.getName().equals(DocumentEventTypes.BEFORE_DOC_UPDATE)) {
+ DocumentModel previousDoc = (DocumentModel) context.getProperty(CoreEventConstants.PREVIOUS_DOCUMENT_MODEL);
- logger.debug("previousLabelRequested=" + previousLabelRequested + " labelRequested=" + labelRequested);
+ String previousLabelRequested = (String) previousDoc.getProperty(LoanoutBotGardenConstants.LABEL_REQUESTED_SCHEMA_NAME,
+ LoanoutBotGardenConstants.LABEL_REQUESTED_FIELD_NAME);
+ String labelRequested = (String) doc.getProperty(LoanoutBotGardenConstants.LABEL_REQUESTED_SCHEMA_NAME,
+ LoanoutBotGardenConstants.LABEL_REQUESTED_FIELD_NAME);
- if ((previousLabelRequested == null || previousLabelRequested.equals(LoanoutBotGardenConstants.LABEL_REQUESTED_NO_VALUE)) &&
- labelRequested.equals(LoanoutBotGardenConstants.LABEL_REQUESTED_YES_VALUE)) {
- // The label request is changing from no to yes, so we should update the styled name.
- ec.setProperty(RUN_AFTER_MODIFIED_PROPERTY, true);
- }
- }
- else {
- boolean doUpdate = false;
+ logger.debug("previousLabelRequested=" + previousLabelRequested + " labelRequested=" + labelRequested);
+
+ if ((previousLabelRequested == null || previousLabelRequested.equals(LoanoutBotGardenConstants.LABEL_REQUESTED_NO_VALUE)) &&
+ labelRequested.equals(LoanoutBotGardenConstants.LABEL_REQUESTED_YES_VALUE)) {
+ // The label request is changing from no to yes, so we should update the styled name.
+ ec.setProperty(RUN_AFTER_MODIFIED_PROPERTY, true);
+ }
+ }
+ else {
+ boolean doUpdate = false;
- if (event.getName().equals(DocumentEventTypes.DOCUMENT_CREATED)) {
- String labelRequested = (String) doc.getProperty(LoanoutBotGardenConstants.LABEL_REQUESTED_SCHEMA_NAME,
- LoanoutBotGardenConstants.LABEL_REQUESTED_FIELD_NAME);
+ if (event.getName().equals(DocumentEventTypes.DOCUMENT_CREATED)) {
+ String labelRequested = (String) doc.getProperty(LoanoutBotGardenConstants.LABEL_REQUESTED_SCHEMA_NAME,
+ LoanoutBotGardenConstants.LABEL_REQUESTED_FIELD_NAME);
- doUpdate = (labelRequested != null && labelRequested.equals(LoanoutBotGardenConstants.LABEL_REQUESTED_YES_VALUE));
- } else {
- doUpdate = ec.hasProperty(RUN_AFTER_MODIFIED_PROPERTY) && ((Boolean) ec.getProperty(RUN_AFTER_MODIFIED_PROPERTY));
- }
+ doUpdate = (labelRequested != null && labelRequested.equals(LoanoutBotGardenConstants.LABEL_REQUESTED_YES_VALUE));
+ } else {
+ doUpdate = ec.hasProperty(RUN_AFTER_MODIFIED_PROPERTY) && ((Boolean) ec.getProperty(RUN_AFTER_MODIFIED_PROPERTY));
+ }
- if (doUpdate) {
- logger.debug("Updating styled name");
+ if (doUpdate) {
+ logger.debug("Updating styled name");
- String voucherCsid = doc.getName();
+ String voucherCsid = doc.getName();
- try {
- createFormatter().formatVoucherName(voucherCsid);
- } catch (Exception e) {
- logger.error(e.getMessage(), e);
- }
- }
+ try {
+ createFormatter(context).formatVoucherName(voucherCsid);
+ } catch (Exception e) {
+ logger.error(e.getMessage(), e);
}
}
}
}
- private FormatVoucherNameBatchJob createFormatter() {
+ private FormatVoucherNameBatchJob createFormatter(DocumentEventContext context) throws Exception {
ResourceMap resourceMap = ResteasyProviderFactory.getContextData(ResourceMap.class);
+ BatchResource batchResource = (BatchResource) resourceMap.get(BatchClient.SERVICE_NAME);
+ ServiceContext<PoxPayloadIn, PoxPayloadOut> serviceContext = batchResource.createServiceContext(batchResource.getServiceName());
+
+ serviceContext.setCurrentRepositorySession(new CoreSessionWrapper(context.getCoreSession()));
FormatVoucherNameBatchJob formatter = new FormatVoucherNameBatchJob();
+ formatter.setServiceContext(serviceContext);
formatter.setResourceMap(resourceMap);
return formatter;
}
-}
+
+ @Override
+ public Log getLogger() {
+ return logger;
+ }
+}
\ No newline at end of file
import java.util.Map;
import org.apache.commons.lang.StringUtils;
+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.RefName;
import org.collectionspace.services.common.api.TaxonFormatter;
-import org.collectionspace.services.nuxeo.listener.AbstractCSEventListenerImpl;
+import org.collectionspace.services.nuxeo.listener.AbstractCSEventSyncListenerImpl;
import org.collectionspace.services.taxonomy.nuxeo.TaxonBotGardenConstants;
import org.collectionspace.services.taxonomy.nuxeo.TaxonConstants;
+import org.collectionspace.services.taxonomy.nuxeo.TaxonomyAuthorityConstants;
+
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.event.CoreEventConstants;
import org.nuxeo.ecm.core.api.event.DocumentEventTypes;
import org.nuxeo.ecm.core.event.Event;
import org.nuxeo.ecm.core.event.EventContext;
import org.nuxeo.ecm.core.event.impl.DocumentEventContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-public class UpdateFormattedDisplayNameListener extends AbstractCSEventListenerImpl {
+public class UpdateFormattedDisplayNameListener extends AbstractCSEventSyncListenerImpl {
public static final String RUN_AFTER_MODIFIED_PROPERTY = "UpdateFormattedDisplayNameListener.RUN_AFTER_MODIFIED";
+ static final Log logger = LogFactory.getLog(UpdateFormattedDisplayNameListener.class);
private static final String[] DISPLAY_NAME_PATH_ELEMENTS = TaxonConstants.DISPLAY_NAME_FIELD_NAME.split("/");
private static final String TERM_GROUP_LIST_FIELD_NAME = DISPLAY_NAME_PATH_ELEMENTS[0];
private static final String[] FORMATTED_DISPLAY_NAME_PATH_ELEMENTS = TaxonConstants.FORMATTED_DISPLAY_NAME_FIELD_NAME.split("/");
private static final String FORMATTED_DISPLAY_NAME_FIELD_NAME = FORMATTED_DISPLAY_NAME_PATH_ELEMENTS[2];
- final Logger logger = LoggerFactory.getLogger(UpdateFormattedDisplayNameListener.class);
- @Override
- public void handleEvent(Event event) {
+ @Override
+ public boolean shouldHandleEvent(Event event) {
EventContext ec = event.getContext();
- if (isRegistered(event) && ec instanceof DocumentEventContext) {
+ if (ec instanceof DocumentEventContext) {
DocumentEventContext context = (DocumentEventContext) ec;
DocumentModel doc = context.getSourceDocument();
+ String docType = doc.getType();
- logger.debug("docType=" + doc.getType());
+ logger.debug("docType=" + docType);
- if (doc.getType().startsWith(TaxonConstants.NUXEO_DOCTYPE) &&
+ if (docType.startsWith(TaxonConstants.NUXEO_DOCTYPE) &&
+ !docType.startsWith(TaxonomyAuthorityConstants.NUXEO_DOCTYPE) &&
!doc.isVersion() &&
!doc.isProxy() &&
!doc.getCurrentLifeCycleState().equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
+ return true;
+ }
+ }
- String refName = (String) doc.getProperty(TaxonConstants.REFNAME_SCHEMA_NAME, TaxonConstants.REFNAME_FIELD_NAME);
- RefName.AuthorityItem item = RefName.AuthorityItem.parse(refName);
- String parentShortId = item.getParentShortIdentifier();
-
- logger.debug("parentShortId=" + parentShortId);
+ return false;
+ }
- if (!parentShortId.equals(TaxonBotGardenConstants.COMMON_VOCABULARY_SHORTID)) {
- if (event.getName().equals(DocumentEventTypes.DOCUMENT_CREATED)) {
- // Save the document, to get the BEFORE_DOC_UPDATE branch to run.
- doc.getCoreSession().saveDocument(doc);
- }
- else if (event.getName().equals(DocumentEventTypes.BEFORE_DOC_UPDATE)) {
- DocumentModel previousDoc = (DocumentModel) context.getProperty(CoreEventConstants.PREVIOUS_DOCUMENT_MODEL);
+ @Override
+ public void handleCSEvent(Event event) {
+ EventContext ec = event.getContext();
+ DocumentEventContext context = (DocumentEventContext) ec;
+ DocumentModel doc = context.getSourceDocument();
+
+ String docType = doc.getType();
+ logger.debug("docType=" + docType);
+
+ String refName = (String) doc.getProperty(TaxonConstants.REFNAME_SCHEMA_NAME, TaxonConstants.REFNAME_FIELD_NAME);
+ RefName.AuthorityItem item = RefName.AuthorityItem.parse(refName);
+ String parentShortId = item.getParentShortIdentifier();
+
+ logger.debug("parentShortId=" + parentShortId);
+
+ if (!parentShortId.equals(TaxonBotGardenConstants.COMMON_VOCABULARY_SHORTID)) {
+ if (event.getName().equals(DocumentEventTypes.DOCUMENT_CREATED)) {
+ // Save the document, to get the BEFORE_DOC_UPDATE branch to run.
+ doc.getCoreSession().saveDocument(doc);
+ }
+ else if (event.getName().equals(DocumentEventTypes.BEFORE_DOC_UPDATE)) {
+ DocumentModel previousDoc = (DocumentModel) context.getProperty(CoreEventConstants.PREVIOUS_DOCUMENT_MODEL);
- updateFormattedDisplayNames(doc, previousDoc);
- }
- }
+ updateFormattedDisplayNames(doc, previousDoc);
}
}
}
return displayNames;
}
*/
-}
+
+ @Override
+ public Log getLogger() {
+ return logger;
+ }
+}
\ No newline at end of file
package org.collectionspace.services.listener;
-import java.util.Iterator;
import java.util.List;
import org.apache.commons.collections.ListUtils;
import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.collectionspace.services.nuxeo.listener.AbstractCSEventPostCommitListenerImpl;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.LifeCycleConstants;
import org.nuxeo.ecm.core.api.event.DocumentEventTypes;
import org.nuxeo.ecm.core.event.Event;
import org.nuxeo.ecm.core.event.EventBundle;
-import org.nuxeo.ecm.core.event.PostCommitEventListener;
import org.nuxeo.ecm.core.event.impl.DocumentEventContext;
import org.nuxeo.elasticsearch.ElasticSearchComponent;
import org.nuxeo.elasticsearch.api.ElasticSearchService;
* be reindexed; for example, if a related record denormalizes data from the updated record at
* index time.
*/
-public class Reindex implements PostCommitEventListener {
+public class Reindex extends AbstractCSEventPostCommitListenerImpl {
+ private final static Log logger = LogFactory.getLog(Reindex.class);
+
// FIXME: This listener runs asynchronously post-commit, so that reindexing records after a
- // save does not hold up the save. In order to make it async, this class does not extend
- // AbstractCSEventListenerImpl, because AbstractCSEventListenerImpl does not implement
- // PostCommitEventListener (DRYD-477). Therefore this listener is not able to use the
- // isRegistered method of AbstractCSEventListenerImpl to determine if it has been registered to
- // run for the current tenant. Instead, it relies on the ReindexSupport listener, which does
- // extend AbstractCSEventListenerImpl, to set a property in the event context that is used to
- // determine if this listener should run. This means that this listener will be considered to
- // be registered if and only if the ReindexSupport listener is registered.
-
- public static final String IS_REGISTERED_KEY = "Reindex.IS_REGISTERED";
+ // save does not hold up the save.
+
public static final String PREV_COVERAGE_KEY = "Reindex.PREV_COVERAGE";
public static final String PREV_PUBLISH_TO_KEY = "Reindex.PREV_PUBLISH_TO";
+ public static final String ELASTICSEARCH_ENABLED_PROP = "elasticsearch.enabled";
+
+ @Override
+ public boolean shouldHandleEventBundle(EventBundle eventBundle) {
+ if (Framework.isBooleanPropertyTrue(ELASTICSEARCH_ENABLED_PROP) && eventBundle.size() > 0) {
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override
+ public boolean shouldHandleEvent(Event event) {
+ DocumentEventContext eventContext = (DocumentEventContext) event.getContext();
+ DocumentModel doc = eventContext.getSourceDocument();
+ String docType = doc.getType();
+
+ if (docType.startsWith("Media")) {
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public void handleCSEvent(Event event) {
+ DocumentEventContext eventContext = (DocumentEventContext) event.getContext();
+ DocumentModel doc = eventContext.getSourceDocument();
+ String eventName = event.getName();
- @Override
- public void handleEvent(EventBundle events) {
// When a media record is created, reindex the material item that is referenced by its
// coverage field.
// TODO: Make this configurable. This is currently hardcoded to the needs of the material
// profile/Material Order application.
+
+ if (
+ eventName.equals(DocumentEventTypes.DOCUMENT_CREATED) ||
+ eventName.equals(DocumentEventTypes.DOCUMENT_UPDATED)
+ ) {
+ String prevCoverage = (String) eventContext.getProperty(PREV_COVERAGE_KEY);
+ String coverage = (String) doc.getProperty("media_common", "coverage");
- if (Framework.isBooleanPropertyTrue("elasticsearch.enabled") && events.size() > 0) {
- Iterator<Event> iter = events.iterator();
-
- while (iter.hasNext()) {
- Event event = iter.next();
- DocumentEventContext eventContext = (DocumentEventContext) event.getContext();
- Boolean isRegistered = (Boolean) eventContext.getProperty(IS_REGISTERED_KEY);
+ List<String> prevPublishTo = (List<String>) eventContext.getProperty(PREV_PUBLISH_TO_KEY);
+ List<String> publishTo = (List<String>) doc.getProperty("media_materials", "publishToList");
- if (isRegistered != null && isRegistered == true) {
- DocumentModel doc = eventContext.getSourceDocument();
- String docType = doc.getType();
- String eventName = event.getName();
-
- if (docType.startsWith("Media")) {
- if (
- eventName.equals(DocumentEventTypes.DOCUMENT_CREATED) ||
- eventName.equals(DocumentEventTypes.DOCUMENT_UPDATED)
- ) {
- String prevCoverage = (String) eventContext.getProperty(PREV_COVERAGE_KEY);
- String coverage = (String) doc.getProperty("media_common", "coverage");
-
- List<String> prevPublishTo = (List<String>) eventContext.getProperty(PREV_PUBLISH_TO_KEY);
- List<String> publishTo = (List<String>) doc.getProperty("media_materials", "publishToList");
-
- if (doc.getCurrentLifeCycleState().equals(LifeCycleConstants.DELETED_STATE)) {
- reindex(doc.getRepositoryName(), coverage);
- }
- else if (
- !ListUtils.isEqualList(prevPublishTo, publishTo) ||
- !StringUtils.equals(prevCoverage, coverage)
- ) {
- if (!StringUtils.equals(prevCoverage, coverage)) {
- reindex(doc.getRepositoryName(), prevCoverage);
- }
-
- reindex(doc.getRepositoryName(), coverage);
- }
- }
- else if (eventName.equals(DocumentEventTypes.DOCUMENT_REMOVED)) {
- String prevCoverage = (String) eventContext.getProperty(PREV_COVERAGE_KEY);
-
- reindex(doc.getRepositoryName(), prevCoverage);
- }
- }
+ if (doc.getCurrentLifeCycleState().equals(LifeCycleConstants.DELETED_STATE)) {
+ reindex(doc.getRepositoryName(), coverage);
+ }
+ else if (
+ !ListUtils.isEqualList(prevPublishTo, publishTo) ||
+ !StringUtils.equals(prevCoverage, coverage)
+ ) {
+ if (!StringUtils.equals(prevCoverage, coverage)) {
+ reindex(doc.getRepositoryName(), prevCoverage);
}
+
+ reindex(doc.getRepositoryName(), coverage);
}
}
- }
+ else if (eventName.equals(DocumentEventTypes.DOCUMENT_REMOVED)) {
+ String prevCoverage = (String) eventContext.getProperty(PREV_COVERAGE_KEY);
+
+ reindex(doc.getRepositoryName(), prevCoverage);
+ }
+ }
+
+ @Override
+ protected Log getLogger() {
+ return logger;
+ }
private void reindex(String repositoryName, String refName) {
if (StringUtils.isEmpty(refName)) {
import java.io.Serializable;
import java.util.List;
-import org.collectionspace.services.nuxeo.listener.AbstractCSEventListenerImpl;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.collectionspace.services.nuxeo.listener.AbstractCSEventSyncListenerImpl;
+
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.event.CoreEventConstants;
import org.nuxeo.ecm.core.api.event.DocumentEventTypes;
/**
* Event listener that stores the values of fields of interest before documents are updated or
- * deleted. This is necessary because the previous/deleted doument model will not be available
+ * deleted. This is necessary because the previous/deleted document model will not be available
* to a post-modification/deletion event listener. Storing the previous/deleted values allows
* the post-modification/deletion event listener to take action if a field value was changed,
* or if a document was deleted that had a certain field value.
* a single class that implements both PostCommitEventListener and EventListener (such a listener
* will only run synchronously).
*/
-public class ReindexSupport extends AbstractCSEventListenerImpl {
+public class ReindexSupport extends AbstractCSEventSyncListenerImpl {
+ final static Log logger = LogFactory.getLog(ReindexSupport.class);
@Override
- public void handleEvent(Event event) {
+ public boolean shouldHandleEvent(Event event) {
+ if (Framework.isBooleanPropertyTrue(Reindex.ELASTICSEARCH_ENABLED_PROP) && event instanceof DocumentEventContext) {
+ DocumentEventContext eventContext = (DocumentEventContext) event.getContext();
+ DocumentModel doc = eventContext.getSourceDocument();
+ String docType = doc.getType();
+ if (docType.startsWith("Media")) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public void handleCSEvent(Event event) {
// When a media record is about to be updated, store the value of the coverage and
// publishToList fields.
// TODO: Make this configurable. This is currently hardcoded to the needs of the material
// profile/Material Order application.
+ DocumentEventContext eventContext = (DocumentEventContext) event.getContext();
+ DocumentModel doc = eventContext.getSourceDocument();
+ String eventName = event.getName();
- if (isRegistered(event)) {
- DocumentEventContext eventContext = (DocumentEventContext) event.getContext();
-
- // Set a property if this listener is registered for the current tenant. This allows
- // the Reindex listener to determine if it should run (since it is async, it cannot
- // extend AbstractCSEventListenerImpl, so it cannot use the isRegistered method).
-
- eventContext.setProperty(Reindex.IS_REGISTERED_KEY, true);
+ if (eventName.equals(DocumentEventTypes.BEFORE_DOC_UPDATE)) {
+ DocumentModel previousDoc = (DocumentModel) eventContext.getProperty(CoreEventConstants.PREVIOUS_DOCUMENT_MODEL);
+ String coverage = (String) previousDoc.getProperty("media_common", "coverage");
+ List<String> publishTo = (List<String>) previousDoc.getProperty("media_materials", "publishToList");
- if (Framework.isBooleanPropertyTrue("elasticsearch.enabled")) {
- DocumentModel doc = eventContext.getSourceDocument();
- String docType = doc.getType();
- String eventName = event.getName();
-
- if (docType.startsWith("Media")) {
- if (eventName.equals(DocumentEventTypes.BEFORE_DOC_UPDATE)) {
- DocumentModel previousDoc = (DocumentModel) eventContext.getProperty(CoreEventConstants.PREVIOUS_DOCUMENT_MODEL);
- String coverage = (String) previousDoc.getProperty("media_common", "coverage");
- List<String> publishTo = (List<String>) previousDoc.getProperty("media_materials", "publishToList");
-
- eventContext.setProperty(Reindex.PREV_COVERAGE_KEY, coverage);
- eventContext.setProperty(Reindex.PREV_PUBLISH_TO_KEY, (Serializable) publishTo);
- }
- else if (eventName.equals(DocumentEventTypes.ABOUT_TO_REMOVE)) {
- String coverage = (String) doc.getProperty("media_common", "coverage");
-
- eventContext.setProperty(Reindex.PREV_COVERAGE_KEY, coverage);
- }
- }
- }
+ eventContext.setProperty(Reindex.PREV_COVERAGE_KEY, coverage);
+ eventContext.setProperty(Reindex.PREV_PUBLISH_TO_KEY, (Serializable) publishTo);
}
+ else if (eventName.equals(DocumentEventTypes.ABOUT_TO_REMOVE)) {
+ String coverage = (String) doc.getProperty("media_common", "coverage");
+ eventContext.setProperty(Reindex.PREV_COVERAGE_KEY, coverage);
+ }
+ }
+
+ @Override
+ public Log getLogger() {
+ return logger;
}
}
import java.io.Serializable;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
import org.collectionspace.services.common.api.CommonAPI;
import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface;
import org.collectionspace.services.nuxeo.client.java.CoreSessionWrapper;
-import org.collectionspace.services.nuxeo.listener.AbstractCSEventListenerImpl;
+import org.collectionspace.services.nuxeo.listener.AbstractCSEventSyncListenerImpl;
import org.collectionspace.services.nuxeo.util.NuxeoUtils;
+
import org.nuxeo.ecm.core.api.Blob;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.blobholder.BlobHolder;
import org.nuxeo.ecm.core.api.blobholder.DocumentBlobHolder;
-//import org.nuxeo.ecm.core.api.event.DocumentEventTypes;
import org.nuxeo.ecm.core.event.Event;
-import org.nuxeo.ecm.core.event.EventContext;
import org.nuxeo.ecm.core.event.impl.DocumentEventContext;
-//import org.nuxeo.ecm.platform.picture.api.ImagingDocumentConstants;
import org.nuxeo.ecm.platform.picture.api.ImagingDocumentConstants;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-public class UpdateImageDerivatives extends AbstractCSEventListenerImpl {
+public class UpdateImageDerivatives extends AbstractCSEventSyncListenerImpl {
// All Nuxeo sessions that get passed around to CollectionSpace code need to
// be wrapped inside of a CoreSessionWrapper. For example:
- // CoreSessionInterface coreSession = new
- // CoreSessionWrapper(docEventContext.getCoreSession());
-
- private final static Logger logger = LoggerFactory.getLogger(UpdateImageDerivatives.class);
-
+ // CoreSessionInterface coreSession = new CoreSessionWrapper(docEventContext.getCoreSession());
+ private static final Log logger = LogFactory.getLog(UpdateImageDerivatives.class);
+
+ @Override
+ public boolean shouldHandleEvent(Event event) {
+ return event.getContext() instanceof DocumentEventContext;
+ }
+
@Override
- public void handleEvent(Event event) {
- if (logger.isTraceEnabled()) {
- logger.trace(String.format("Entering handleEvent in '%s'...", getClass().getName()));
- }
+ public void handleCSEvent(Event event) {
+ DocumentEventContext docEventContext = (DocumentEventContext) event.getContext();
+ DocumentModel docModel = docEventContext.getSourceDocument();
- if (shouldProcessEvent(event) == true) {
- DocumentEventContext docEventContext = (DocumentEventContext) event.getContext();
- DocumentModel docModel = docEventContext.getSourceDocument();
+ String source = (String)docModel.getProperty(CommonAPI.NUXEO_DUBLINCORE_SCHEMANAME,
+ CommonAPI.NUXEO_DUBLINCORE_SOURCE);
- String eventType = event.getName();
+ if (source != null && source.equalsIgnoreCase(CommonAPI.URL_SOURCED_PICTURE)) {
+ CoreSessionInterface nuxeoSession = new CoreSessionWrapper(docEventContext.getCoreSession());
+ purgeOriginalImage(docModel, nuxeoSession);
+ nuxeoSession.save();
+ } else {
if (logger.isTraceEnabled()) {
- logger.trace(String.format("A(n) '%s' event was received by the %s event listener.",
- eventType, getClass().getName()));
- //logg
- }
-
- String source = (String)docModel.getProperty(CommonAPI.NUXEO_DUBLINCORE_SCHEMANAME,
- CommonAPI.NUXEO_DUBLINCORE_SOURCE);
-
- if (source != null && source.equalsIgnoreCase(CommonAPI.URL_SOURCED_PICTURE)) {
- CoreSessionInterface nuxeoSession = new CoreSessionWrapper(docEventContext.getCoreSession());
- purgeOriginalImage(docModel, nuxeoSession);
- nuxeoSession.save();
- } else {
- if (logger.isTraceEnabled()) {
- logger.trace(String.format("The Nuxeo document titled '%s' did not need processing by the '%s' Nuxeo listener.",
- docModel.getTitle(), getClass().getName()));
- }
+ logger.trace(String.format("The Nuxeo document titled '%s' did not need processing by the '%s' Nuxeo listener.",
+ docModel.getTitle(), getClass().getName()));
}
- }
-
- if (logger.isTraceEnabled()) {
- logger.trace(String.format("Exiting handleEvent in '%s'.", getClass().getName()));
- }
+ }
}
private void purgeOriginalImage(DocumentModel docModel, CoreSessionInterface nuxeoSession) {
// just disassociates the blob content (aka, the original image) from the document.
//
docModel.setPropertyValue("file:content", (Serializable) null);
-
+
//
// Removing this facet ensures the original derivatives are unchanged when
// we call the save method. If we didn't remove the face, then all the
// Nuxeo will still tread this document as a Picture document.
//
NuxeoUtils.addFacet(docModel, ImagingDocumentConstants.PICTURE_FACET);
-
+
//
// Finally, we need to remove the actual blob/image bits that are store on disk.
//
DocumentBlobHolder docBlobHolder = (DocumentBlobHolder) docModel.getAdapter(BlobHolder.class);
- Blob blob = docBlobHolder.getBlob();
+ Blob blob = docBlobHolder.getBlob();
if (blob == null) {
logger.error(String.format("Could not get blob for original image. Trying to delete original for: '%s'",
docModel.getTitle()));
logger.debug(String.format("Started thread '%s' to delete file of blob '%s'.",
thread.getId(), blob.getFilename()));
}
-
+
if (logger.isTraceEnabled()) {
- logger.trace(String.format("Exiting handleEvent in '%s'.", getClass().getName()));
- }
+ logger.trace(String.format("Exiting handleEvent in '%s'.", getClass().getName()));
+ }
}
- private boolean shouldProcessEvent(Event event) {
- boolean result = false;
-
- EventContext eventContext = event.getContext();
- if (eventContext != null) {
- if (isRegistered(event) && eventContext instanceof DocumentEventContext) {
- result = true;
- }
- }
-
- return result;
+ @Override
+ public Log getLogger() {
+ return logger;
}
-
-}
+}
\ No newline at end of file
import java.util.GregorianCalendar;
import java.util.HashSet;
-import java.util.Map;
import java.util.Set;
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.document.DocumentException;
import org.collectionspace.services.movement.nuxeo.MovementConstants;
import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface;
import org.collectionspace.services.nuxeo.client.java.CoreSessionWrapper;
-import org.collectionspace.services.nuxeo.listener.AbstractCSEventListenerImpl;
+import org.collectionspace.services.nuxeo.listener.AbstractCSEventSyncListenerImpl;
import org.collectionspace.services.nuxeo.util.NuxeoUtils;
+
import org.nuxeo.ecm.core.api.ClientException;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.DocumentModelList;
import org.nuxeo.ecm.core.api.impl.DocumentModelListImpl;
import org.nuxeo.ecm.core.event.Event;
import org.nuxeo.ecm.core.event.impl.DocumentEventContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public abstract class AbstractUpdateObjectLocationValues extends AbstractCSEventListenerImpl {
- private final static Logger logger = LoggerFactory.getLogger(AbstractUpdateObjectLocationValues.class);
+public abstract class AbstractUpdateObjectLocationValues extends AbstractCSEventSyncListenerImpl {
// 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 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
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 ";
- private final static String ACTIVE_DOCUMENT_WHERE_CLAUSE_FRAGMENT =
- "AND (ecm:currentLifeCycleState <> 'deleted') "
- + NONVERSIONED_NONPROXY_DOCUMENT_WHERE_CLAUSE_FRAGMENT;
-
// Used to set/get temp values in a DocumentModel instance
private static final String IGNORE_LOCATION_UPDATE_EVENT_LABEL = "IGNORE_LOCATION_UPDATE_EVENT";
-
+
public enum EventNotificationDocumentType {
// Document type about which we've received a notification
-
MOVEMENT, RELATION, COLLECTIONOBJECT;
}
- private static void logEvent(Event event, String message) {
- logEvent(event, message, false);
- }
-
- private static void logEvent(Event event, String message, boolean forceLogging) {
- if (logger.isDebugEnabled() || forceLogging) {
- 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=<empty>"));
- }
- } else {
- logger.debug(String.format("### Ignoring Update Location event: %s", eventType));
- }
- }
- }
-
- /*
- * Figure out if we should ignore this event.
- */
- private boolean shouldIgnoreEvent(DocumentEventContext docEventContext, String ignoreEventLabel) {
- boolean result = false;
-
- Boolean shouldIgnoreEvent = (Boolean) docEventContext.getProperties().get(DOCMODEL_CONTEXT_PROPERTY_PREFIX + ignoreEventLabel);
+ public boolean shouldHandleEvent(Event event) {
+ // Ensure we have all the event data we need to proceed.
+ if (event.getContext() instanceof DocumentEventContext == false) {
+ return false;
+ }
+ //
+ // This event handler itself sometimes triggers additional events. To prevent unnecessary cascading event handling, this event
+ // handler sets a temp flag in the document model's context indicating we should ignore cascading events. This method checks that flag and
+ // exits if it is set.
+ DocumentEventContext docEventContext = (DocumentEventContext) event.getContext();
+ Boolean shouldIgnoreEvent = (Boolean) getContextPropertyValue(docEventContext, IGNORE_LOCATION_UPDATE_EVENT_LABEL);
if (shouldIgnoreEvent != null && shouldIgnoreEvent) {
- result = true;
+ return false;
}
- return result;
+ return true;
}
-
+
@Override
- public void handleEvent(Event event) {
- // Ensure we have all the event data we need to proceed.
- if (isRegistered(event) == false || !(event.getContext() instanceof DocumentEventContext)) {
- if (logger.isTraceEnabled() == true) {
- logEvent(event, "Update Location", true);
- }
- return;
- }
-
- Map<String, String> params = this.getParams(event); // Will be null if no params were configured.
- logEvent(event, "Update Location");
-
+ public void handleCSEvent(Event event) {
DocumentEventContext docEventContext = (DocumentEventContext) event.getContext();
- DocumentModel eventDocModel = docEventContext.getSourceDocument();
+ DocumentModel eventDocModel = docEventContext.getSourceDocument();
String eventType = event.getName();
boolean isAboutToBeRemovedEvent = eventType.equals(DocumentEventTypes.ABOUT_TO_REMOVE);
-
- //
- // This event handler itself sometimes triggers additional events. To prevent unnecessary cascading event handling, this event
- // handler sets a flag in the document model indicating we should ignore cascading events. This method checks that flag and
- // exits if it is set.
- if (shouldIgnoreEvent(docEventContext, IGNORE_LOCATION_UPDATE_EVENT_LABEL) == true) {
- return;
- }
-
+
//
// 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.
// Otherwise, get a Movement CSID directly from the Movement record.
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);
+ getLogger().warn("Could not obtain CSID for Movement record from document event.");
+ getLogger().warn(NO_FURTHER_PROCESSING_MESSAGE);
return;
}
} else if (documentMatchesType(eventDocModel, COLLECTIONOBJECT_DOCTYPE) &&
//
// 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<String> collectionObjectCsids = new HashSet<>();
if (notificationDocumentType == EventNotificationDocumentType.RELATION) {
if (collectionObjectCsids.isEmpty() == true) {
return;
}
-
+
//
// 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) {
+ for (String collectionObjectCsid : collectionObjectCsids) {
collectionObjectDocModel = getCurrentDocModelFromCsid(session, collectionObjectCsid);
if (isActiveDocument(collectionObjectDocModel) == true) {
DocumentModel movementDocModel = getCurrentDocModelFromCsid(session, eventMovementCsid);
// Update the CollectionObject's Computed Current Location field with the Movement record's location
//
boolean didLocationChange = updateCollectionObjectLocation(collectionObjectDocModel, movementDocModel, mostRecentLocation);
-
+
//
// If the location changed, save/persist the change to the repository and log the change.
//
persistLocationChange(session, collectionObjectDocModel);
//
// Log an INFO message if we've changed the cataloging record's location
- //
- if (logger.isInfoEnabled()) {
+ //
+ if (getLogger().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",
+ getLogger().info(String.format("Updating cataloging record=%s current location to %s",
NuxeoUtils.getCsid(collectionObjectDocModel), computedCurrentLocationRefName));
}
}
}
}
}
-
+
//
// Disable update/documentModified events and persist the location change.
//
private void persistLocationChange(CoreSessionInterface session, DocumentModel collectionObjectDocModel) {
-
+
//
// Set a flag in the document model indicating that we want to ignore the update event that
// will be triggered by this save/persist request.
//
// Save/Persist the document to the DB
session.saveDocument(collectionObjectDocModel);
-
+
//
// Clear the flag we set to ignore events triggered by our save request.
clearDocModelContextProperty(collectionObjectDocModel, IGNORE_LOCATION_UPDATE_EVENT_LABEL);
* @throws ClientException
* @return the CSIDs of the CollectionObject records, if any, which are
* related to the Movement record.
- * @throws DocumentException
+ * @throws DocumentException
*/
private Set<String> getCollectionObjectCsidsRelatedToMovement(String movementCsid,
CoreSessionInterface coreSession) throws ClientException {
+ ")"
+ ACTIVE_DOCUMENT_WHERE_CLAUSE_FRAGMENT,
RELATION_DOCTYPE, RELATIONS_COMMON_SCHEMA, movementCsid, COLLECTIONOBJECT_DOCTYPE);
-
+
DocumentModelList relationDocModels = null;
try {
relationDocModels = coreSession.query(query);
} catch (DocumentException e) {
- logger.error(e.getMessage());
+ getLogger().error(e);
}
-
+
if (relationDocModels == null || relationDocModels.isEmpty()) {
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.
csids.add(csid);
}
}
-
+
return csids;
}
-
-// FIXME: Generic methods like many of those below might be split off from
-// this specific event listener/handler, into an event handler utilities
-// class, base classes, or otherwise.
-//
-// FIXME: Identify whether the equivalent of the documentMatchesType utility
-// method is already implemented and substitute a call to the latter if so.
-// This may well already exist.
- /**
- * 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.
- */
- protected static boolean documentMatchesType(DocumentModel docModel, String docType) {
- if (docModel == null || Tools.isBlank(docType)) {
- return false;
- }
- if (docModel.getType().startsWith(docType)) {
- return true;
- } else {
- return false;
- }
- }
-
- 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.
- *
- * @param docModel
- * @return true if the document is an active document; false if it is not.
- */
- protected static boolean isActiveDocument(DocumentModel docModel, boolean isAboutToBeRemovedEvent, String aboutToBeRemovedCsid) {
- boolean isActiveDocument = false;
-
- if (docModel != null) {
- if (!docModel.getCurrentLifeCycleState().contains(WorkflowClient.WORKFLOWSTATE_DELETED)) {
- isActiveDocument = true;
- }
- //
- // 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;
- }
-
- /**
- * Returns the current document model for a record identified by a CSID.
- *
- * Excludes documents which have been versioned (i.e. are a non-current
- * version of a document), are a proxy for another document, or are
- * un-retrievable via their CSIDs.
- *
- * @param session a repository session.
- * @param csid a CollectionObject identifier (CSID)
- * @return a document model for the document identified by the supplied
- * CSID.
- */
- protected static DocumentModel getCurrentDocModelFromCsid(CoreSessionInterface session, String csid) {
- DocumentModelList docModelList = null;
-
- if (Tools.isEmpty(csid)) {
- return null;
- }
-
- try {
- final String query = "SELECT * FROM "
- + NuxeoUtils.BASE_DOCUMENT_TYPE
- + " WHERE "
- + NuxeoUtils.getByNameWhereClause(csid)
- + " "
- + NONVERSIONED_NONPROXY_DOCUMENT_WHERE_CLAUSE_FRAGMENT;
- docModelList = session.query(query);
- } catch (Exception e) {
- logger.warn("Exception in query to get active document model for CSID: " + csid, e);
- }
-
- if (docModelList == null || docModelList.isEmpty()) {
- logger.warn("Could not get active document models for CSID=" + csid);
- return null;
- } else if (docModelList.size() != 1) {
- logger.error("Found more than 1 active document with CSID=" + csid);
- 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;
}
* @throws ClientException
* @return the most recent Movement record related to the CollectionObject
* identified by the supplied CSID.
- * @throws DocumentException
+ * @throws DocumentException
*/
protected String getMostRecentLocation(Event event,
CoreSessionInterface session, String collectionObjectCsid,
// 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.
//
+ ")"
+ ACTIVE_DOCUMENT_WHERE_CLAUSE_FRAGMENT,
RELATION_DOCTYPE, RELATIONS_COMMON_SCHEMA, collectionObjectCsid, MOVEMENT_DOCTYPE);
- logger.trace("query=" + query);
+ getLogger().trace("query=" + query);
DocumentModelList relationDocModels;
try {
relationDocModels = session.query(query);
} catch (DocumentException e) {
- logger.error(e.getMessage());
+ getLogger().error(e);
return null;
}
-
+
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 that are with inactive movement records
//
relationDocModels = removeInactiveRelations(session, relationDocModels, isAboutToBeRemovedEvent, eventMovementCsid);
-
+
//
// 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 -but only if it's current location element is not empty.
DocumentModel relationDocModel = relationDocModels.get(0);
DocumentModel movementDocModel = getMovementDocModelFromRelation(session, relationDocModel);
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.",
+ getLogger().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 result;
}
-
+
//
// Iterate through the list (>2) of related movement records, to find the related
// Movement record with the most recent location date.
}
movementDocModel = getCurrentDocModelFromCsid(session, relatedMovementCsid);
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.",
+ getLogger().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);
if (locationDate.after(mostRecentLocationDate)) {
mostRecentLocationDate = locationDate;
}
}
}
-
+
return result;
}
-
+
//
// This method assumes that the relation passed into this method is between a Movement record
// and a CollectionObject (cataloging) record.
//
- private static DocumentModel getMovementDocModelFromRelation(CoreSessionInterface session, DocumentModel relationDocModel) {
+ private DocumentModel getMovementDocModelFromRelation(CoreSessionInterface session, DocumentModel relationDocModel) {
String movementCsid = null;
-
+
String subjectDocType = (String) relationDocModel.getProperty(RELATIONS_COMMON_SCHEMA, SUBJECT_DOCTYPE_PROPERTY);
if (subjectDocType.endsWith(MOVEMENT_DOCTYPE)) {
movementCsid = (String) relationDocModel.getProperty(RELATIONS_COMMON_SCHEMA, SUBJECT_CSID_PROPERTY);
//
// Compares two Relation document models to see if they're either identical or
- // reciprocal equivalents.
+ // reciprocal equivalents.
//
private static boolean compareRelationDocModels(DocumentModel r1, DocumentModel r2) {
boolean result = false;
-
+
String r1_subjectDocType = (String) r1.getProperty(RELATIONS_COMMON_SCHEMA, SUBJECT_DOCTYPE_PROPERTY);
String r1_objectDocType = (String) r1.getProperty(RELATIONS_COMMON_SCHEMA, OBJECT_DOCTYPE_PROPERTY);
String r1_subjectCsid = (String) r1.getProperty(RELATIONS_COMMON_SCHEMA, SUBJECT_CSID_PROPERTY);
String r2_objectDocType = (String) r2.getProperty(RELATIONS_COMMON_SCHEMA, OBJECT_DOCTYPE_PROPERTY);
String r2_subjectCsid = (String) r2.getProperty(RELATIONS_COMMON_SCHEMA, SUBJECT_CSID_PROPERTY);
String r2_objectCsid = (String) r2.getProperty(RELATIONS_COMMON_SCHEMA, OBJECT_CSID_PROPERTY);
-
+
// Check to see if they're identical
if (r1_subjectDocType.equalsIgnoreCase(r2_subjectDocType) && r1_objectDocType.equalsIgnoreCase(r2_objectDocType)
&& r1_subjectCsid.equalsIgnoreCase(r2_subjectCsid) && r1_objectCsid.equalsIgnoreCase(r2_objectCsid)) {
return true;
}
-
+
// Check to see if they're reciprocal
if (r1_subjectDocType.equalsIgnoreCase(r2_objectDocType) && r1_objectDocType.equalsIgnoreCase(r2_subjectDocType)
&& r1_subjectCsid.equalsIgnoreCase(r2_objectCsid) && r1_objectCsid.equalsIgnoreCase(r2_subjectCsid)) {
//
private static DocumentModelList removeRedundantRelations(DocumentModelList relationDocModelList) {
DocumentModelList resultList = null;
-
+
if (relationDocModelList != null && relationDocModelList.size() > 0) {
resultList = new DocumentModelListImpl();
for (DocumentModel relationDocModel : relationDocModelList) {
}
}
}
-
- // TODO Auto-generated method stub
+
return resultList;
}
-
+
//
// 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 removeInactiveRelations(CoreSessionInterface session,
+ private DocumentModelList removeInactiveRelations(CoreSessionInterface session,
DocumentModelList relationDocModelList,
boolean isAboutToBeRemovedEvent,
String eventMovementCsid) {
DocumentModelList resultList = null;
-
+
if (relationDocModelList != null && relationDocModelList.size() > 0) {
resultList = new DocumentModelListImpl();
for (DocumentModel relationDocModel : relationDocModelList) {
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.",
+ getLogger().debug(String.format("Disqualified relationship=%s with Movement record=%s from current location computation.",
NuxeoUtils.getCsid(relationDocModel), movementCsid));
}
}
}
-
+
return resultList;
}
-
//
// Check to see if the Relation (or its equivalent reciprocal) is already in the list.
//
private static boolean existsInResultList(DocumentModelList relationDocModelList, DocumentModel relationDocModel) {
boolean result = false;
-
+
for (DocumentModel target : relationDocModelList) {
if (compareRelationDocModels(relationDocModel, target) == true) {
result = true;
break;
}
}
-
+
return result;
}
* @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
* null if the Relation record does not involve both the desired
* and related document types.
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(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;
}
protected abstract boolean updateCollectionObjectLocation(DocumentModel collectionObjectDocModel,
DocumentModel movmentDocModel,
String movementRecordsLocation);
-}
+}
\ No newline at end of file
package org.collectionspace.services.listener;
import java.io.Serializable;
+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.DocumentModel;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
public class UpdateObjectLocationAndCrateOnMove extends UpdateObjectLocationOnMove {
- private final Logger logger = LoggerFactory.getLogger(UpdateObjectLocationAndCrateOnMove.class);
+
+ // 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(UpdateObjectLocationAndCrateOnMove.class);
// FIXME: Get values below from external constants
private final static String COLLECTIONOBJECTS_ANTHROPOLOGY_SCHEMA = "collectionobjects_anthropology";
private final static String MOVEMENTS_ANTHROPOLOGY_SCHEMA = "movements_anthropology";
String mostRecentLocation) throws ClientException {
boolean flag = super.updateCollectionObjectLocation(collectionObjectDocModel, movementDocModel, mostRecentLocation);
collectionObjectDocModel = updateComputedCrateValue(collectionObjectDocModel, movementDocModel);
-
+
return flag;
}
private DocumentModel updateComputedCrateValue(DocumentModel collectionObjectDocModel,
DocumentModel movementDocModel)
throws ClientException {
-
+
// Get the current crate value from the Movement (the "new" value)
String crateRefName =
(String) movementDocModel.getProperty(MOVEMENTS_ANTHROPOLOGY_SCHEMA, CRATE_PROPERTY);
logger.trace("crate refName does NOT require updating.");
}
}
-
+
return collectionObjectDocModel;
}
-}
+}
\ No newline at end of file
package org.collectionspace.services.listener;
+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.DocumentModel;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
public class UpdateObjectLocationOnMove extends AbstractUpdateObjectLocationValues {
- private final Logger logger = LoggerFactory.getLogger(UpdateObjectLocationOnMove.class);
+
+ private final Log logger = LogFactory.getLog(UpdateObjectLocationOnMove.class);
@Override
protected boolean updateCollectionObjectLocation(DocumentModel collectionObjectDocModel,
movementRecordsLocation));
return result;
}
-
+
// Get the computed current location value of the CollectionObject.
String existingComputedCurrentLocation = (String) collectionObjectDocModel.getProperty(COLLECTIONOBJECTS_COMMON_SCHEMA,
COMPUTED_CURRENT_LOCATION_PROPERTY);
COMPUTED_CURRENT_LOCATION_PROPERTY, movementRecordsLocation);
result = true; // We've updated the location field.
}
-
+
return result;
}
-}
+
+ @Override
+ public Log getLogger() {
+ return logger;
+ }
+}
\ No newline at end of file
import java.util.IllegalFormatException;
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.document.DocumentException;
import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface;
import org.collectionspace.services.nuxeo.client.java.CoreSessionWrapper;
-import org.collectionspace.services.nuxeo.listener.AbstractCSEventListenerImpl;
+import org.collectionspace.services.nuxeo.listener.AbstractCSEventSyncListenerImpl;
+
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.DocumentModelList;
import org.nuxeo.ecm.core.api.impl.LifeCycleFilter;
import org.nuxeo.ecm.core.event.Event;
import org.nuxeo.ecm.core.event.EventContext;
import org.nuxeo.ecm.core.event.impl.DocumentEventContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-public class UpdateRelationsOnDelete extends AbstractCSEventListenerImpl {
- final Logger logger = LoggerFactory.getLogger(UpdateRelationsOnDelete.class);
+public class UpdateRelationsOnDelete extends AbstractCSEventSyncListenerImpl {
+ // FIXME: We might experiment here with using log4j instead of Apache Commons Logging;
+ // am using the latter to follow Ray's pattern for now
+ final Log logger = LogFactory.getLog(UpdateRelationsOnDelete.class);
+
// FIXME: Get these constant values from external sources rather than redeclaring here
final static String RELATION_DOCTYPE = "Relation";
final static String RELATIONS_COMMON_SUBJECT_CSID_FIELD = "relations_common:subjectCsid";
final static String RELATIONS_COMMON_OBJECT_CSID_FIELD = "relations_common:objectCsid";
@Override
- public void handleEvent(Event event) {
- logger.trace("In handleEvent in UpdateRelationsOnDelete ...");
-
+ public boolean shouldHandleEvent(Event event) {
EventContext eventContext = event.getContext();
- if (isRegistered(event) && isDocumentSoftDeletedEvent(eventContext)) {
-
- logger.trace("A soft deletion event was received by UpdateRelationsOnDelete ...");
-
- DocumentEventContext docContext = (DocumentEventContext) eventContext;
- DocumentModel docModel = docContext.getSourceDocument();
-
- // Exclude soft deletion events involving Relation records themselves
- // from handling by this event handler.
- if (docModel != null && docModel.getType().startsWith(RELATION_DOCTYPE)) {
- return;
- }
-
- // Retrieve a list of relation records, where the soft deleted
- // document provided in the context of the current event is
- // either the subject or object of any relation
-
- // Build a query string
- String csid = docModel.getName();
-
- String queryString;
- try {
- queryString =
- String.format("SELECT * FROM Relation WHERE ecm:isProxy = 0 AND (%1$s='%3$s' OR %2$s='%3$s')",
- RELATIONS_COMMON_SUBJECT_CSID_FIELD, RELATIONS_COMMON_OBJECT_CSID_FIELD, csid);
- logger.trace("Query string=" + queryString);
- } catch (IllegalFormatException ife) {
- logger.warn("Construction of formatted query string failed: ", ife);
- logger.warn("Actions in this event listener will NOT be performed, as a result of a previous Exception.");
- return;
- }
-
- // Create a filter to exclude from the list results any records
- // that have already been soft deleted or are locked
- List<String> workflowStatesToFilter = new ArrayList<String>();
- workflowStatesToFilter.add(WorkflowClient.WORKFLOWSTATE_DELETED);
- workflowStatesToFilter.add(WorkflowClient.WORKFLOWSTATE_LOCKED);
- workflowStatesToFilter.add(WorkflowClient.WORKFLOWSTATE_LOCKED_DELETED);
- workflowStatesToFilter.add(WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED);
-
- LifeCycleFilter workflowStateFilter = new LifeCycleFilter(null, workflowStatesToFilter);
-
- // Perform the filtered query
- CoreSessionInterface session = new CoreSessionWrapper(docModel.getCoreSession());
- DocumentModelList matchingDocuments;
- try {
- matchingDocuments = session.query(queryString.toString(), workflowStateFilter);
- } catch (DocumentException ce) {
- logger.error("Error attempting to retrieve relation records where "
- + "record of type '" + docModel.getType() + "' with CSID " + csid
- + " is the subject or object of any relation: " + ce.getMessage());
- return;
- }
-
- // Cycle through the list results, soft deleting each matching relation record
- logger.info("Attempting to soft delete " + matchingDocuments.size() + " relation records pertaining to a soft deleted record.");
- for (DocumentModel doc : matchingDocuments) {
- doc.followTransition(WorkflowClient.WORKFLOWTRANSITION_DELETE);
- }
-
+ // Event must be a soft-delete event
+ if (isDocumentSoftDeletedEvent(eventContext)) {
+ return true;
}
-
+
+ // Exclude soft deletion events involving Relation records themselves
+ // from handling by this event handler.
+ DocumentEventContext docContext = (DocumentEventContext) eventContext;
+ DocumentModel docModel = docContext.getSourceDocument();
+ if (docModel != null && docModel.getType().startsWith(RELATION_DOCTYPE)) {
+ return false;
+ }
+
+ return false;
}
+
+ @Override
+ public void handleCSEvent(Event event) {
+ EventContext eventContext = event.getContext();
+ DocumentEventContext docContext = (DocumentEventContext) eventContext;
+ DocumentModel docModel = docContext.getSourceDocument();
+
+ // Retrieve a list of relation records, where the soft deleted
+ // document provided in the context of the current event is
+ // either the subject or object of any relation
+ String csid = docModel.getName();
+ String queryString;
+ try {
+ queryString =
+ String.format("SELECT * FROM Relation WHERE ecm:isProxy = 0 AND (%1$s='%3$s' OR %2$s='%3$s')",
+ RELATIONS_COMMON_SUBJECT_CSID_FIELD, RELATIONS_COMMON_OBJECT_CSID_FIELD, csid);
+ logger.trace("Query string=" + queryString);
+ } catch (IllegalFormatException ife) {
+ logger.warn("Construction of formatted query string failed: ", ife);
+ logger.warn("Actions in this event listener will NOT be performed, as a result of a previous Exception.");
+ return;
+ }
+
+ // Create a filter to exclude from the list results any records
+ // that have already been soft deleted or are locked
+ List<String> workflowStatesToFilter = new ArrayList<String>();
+ workflowStatesToFilter.add(WorkflowClient.WORKFLOWSTATE_DELETED);
+ workflowStatesToFilter.add(WorkflowClient.WORKFLOWSTATE_LOCKED);
+ workflowStatesToFilter.add(WorkflowClient.WORKFLOWSTATE_LOCKED_DELETED);
+ workflowStatesToFilter.add(WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED);
+
+ LifeCycleFilter workflowStateFilter = new LifeCycleFilter(null, workflowStatesToFilter);
+
+ // Perform the filtered query
+ CoreSessionInterface session = new CoreSessionWrapper(docModel.getCoreSession());
+ DocumentModelList matchingDocuments;
+ try {
+ matchingDocuments = session.query(queryString.toString(), workflowStateFilter);
+ } catch (DocumentException ce) {
+ logger.error("Error attempting to retrieve relation records where "
+ + "record of type '" + docModel.getType() + "' with CSID " + csid
+ + " is the subject or object of any relation: " + ce.getMessage());
+ return;
+ }
- // FIXME: Generic methods like the following might be split off
- // into an event utilities class. - ADR 2012-12-05
-
- /**
- * Identifies whether a supplied event concerns a document that has
- * been transitioned to the 'deleted' workflow state.
- *
- * @param eventContext an event context
- *
- * @return true if this event concerns a document that has
- * been transitioned to the 'deleted' workflow state.
- */
- private boolean isDocumentSoftDeletedEvent(EventContext eventContext) {
- boolean isSoftDeletedEvent = false;
-
- if (eventContext instanceof DocumentEventContext) {
- if (eventContext.getProperties().containsKey(WorkflowClient.WORKFLOWTRANSITION_TO)
- &&
- (eventContext.getProperties().get(WorkflowClient.WORKFLOWTRANSITION_TO).equals(WorkflowClient.WORKFLOWSTATE_DELETED)
- ||
- eventContext.getProperties().get(WorkflowClient.WORKFLOWTRANSITION_TO).equals(WorkflowClient.WORKFLOWSTATE_LOCKED_DELETED))) {
- isSoftDeletedEvent = true;
- }
+ // Cycle through the list results, soft deleting each matching relation record
+ logger.info("Attempting to soft delete " + matchingDocuments.size() + " relation records pertaining to a soft deleted record.");
+ for (DocumentModel doc : matchingDocuments) {
+ doc.followTransition(WorkflowClient.WORKFLOWTRANSITION_DELETE);
}
+ }
- return isSoftDeletedEvent;
+ @Override
+ public Log getLogger() {
+ return this.logger;
}
}
<dependency>
<groupId>org.nuxeo.ecm.core</groupId>
<artifactId>nuxeo-core-convert</artifactId>
- <version>${nuxeo.core.version}</version>
</dependency>
<dependency>
<groupId>org.nuxeo.ecm.platform</groupId>
<artifactId>nuxeo-platform-imaging-core</artifactId>
- <version>${nuxeo.platform.version}</version>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>org.collectionspace.services</groupId>
+ <artifactId>org.collectionspace.services.common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
</dependencies>
<build>
import java.util.Calendar;
import java.util.GregorianCalendar;
+import org.collectionspace.services.nuxeo.util.ThumbnailConstants;
import org.nuxeo.ecm.core.api.Blob;
import org.nuxeo.ecm.core.api.ClientException;
import org.nuxeo.ecm.core.api.CoreSession;
package org.collectionspace.services.nuxeo.extension.thumbnail;
-import java.io.Serializable;
-
+import org.collectionspace.services.nuxeo.util.ThumbnailConstants;
import org.nuxeo.ecm.core.api.ClientException;
import org.nuxeo.ecm.core.api.DocumentModel;
import java.io.Serializable;
import java.util.Map;
+import org.collectionspace.services.nuxeo.util.ThumbnailConstants;
import org.nuxeo.ecm.core.api.Blob;
import org.nuxeo.ecm.core.api.blobholder.BlobHolder;
import org.nuxeo.ecm.core.api.impl.blob.FileBlob;
package org.collectionspace.services.nuxeo.extension.thumbnail;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.collectionspace.services.nuxeo.listener.AbstractCSEventSyncListenerImpl;
+import org.collectionspace.services.nuxeo.util.ThumbnailConstants;
+
import org.nuxeo.ecm.core.api.Blob;
import org.nuxeo.ecm.core.api.ClientException;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.event.DocumentEventTypes;
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;
-public class UpdateThumbListener implements EventListener {
-
- public void handleEvent(Event event) throws ClientException {
+public class UpdateThumbListener extends AbstractCSEventSyncListenerImpl {
+ final Log logger = LogFactory.getLog(UpdateThumbListener.class);
+
+ @Override
+ public boolean shouldHandleEvent(Event event) {
+ EventContext ec = event.getContext();
+
+ return ec instanceof DocumentEventContext;
+ }
+
+ public void handleCSEvent(Event event) throws ClientException {
EventContext ec = event.getContext();
if (ec instanceof DocumentEventContext) {
DocumentEventContext context = (DocumentEventContext) ec;
}
}
}
+
+ @Override
+ public Log getLogger() {
+ return logger;
+ }
}
import org.collectionspace.services.collectionobject.nuxeo.CollectionObjectBotGardenConstants;
import org.collectionspace.services.collectionobject.nuxeo.CollectionObjectConstants;
import org.collectionspace.services.common.api.RefName;
+import org.collectionspace.services.common.api.Tools;
import org.collectionspace.services.common.invocable.InvocationResults;
import org.collectionspace.services.common.vocabulary.AuthorityResource;
import org.collectionspace.services.taxonomy.nuxeo.TaxonBotGardenConstants;
/**
* A batch job that sets the access code on taxonomy records. The single CSID context is supported.
- *
+ *
* If the document is a taxon record, the access codes of the taxon record and all of its descendant
* (narrower context) records are updated.
- *
+ *
* If the document is a collectionobject, the access codes of all taxon records referenced by the
* collectionobject's taxonomic identification are updated, and propagated up the taxon
* hierarchy to the ancestors (broader contexts) of each taxon record.
public UpdateAccessCodeBatchJob() {
this.setSupportedInvocationModes(Arrays.asList(INVOCATION_MODE_SINGLE));
}
-
+
@Override
public void run() {
setCompletionStatus(STATUS_MIN_PROGRESS);
-
+
try {
if (this.requestIsForInvocationModeSingle()) {
String csid = getInvocationContext().getSingleCSID();
-
+
if (StringUtils.isEmpty(csid)) {
throw new Exception("Missing context csid");
}
-
+
String docType = getInvocationContext().getDocType();
-
+
if (docType.equals(TaxonConstants.NUXEO_DOCTYPE)) {
setResults(updateAccessCode(csid, true));
//setResults(updateParentAccessCode(csid, true));
}
else {
throw new Exception("Unsupported document type: " + docType);
- }
+ }
}
else {
throw new Exception("Unsupported invocation mode: " + this.getInvocationContext().getMode());
}
-
+
setCompletionStatus(STATUS_COMPLETE);
}
catch(Exception e) {
setCompletionStatus(STATUS_ERROR);
setErrorInfo(new InvocationError(INT_ERROR_STATUS, e.getMessage()));
- }
+ }
}
-
-
+
+
/**
* Updates the access code of the specified taxon record.
- *
+ *
* @param taxonRefNameOrCsid The refname or csid of the taxon record.
* @param deep If true, update the access codes of all descendant (narrower context)
* taxon records. On a deep update, the access codes of all descendant
* records are updated first, before calculating the access code of the parent.
* This ensures that the access codes of children are up-to-date, and can be
* used to calculate an up-to-date value for the parent.
- *
+ *
* If false, only the specified taxon record is updated. The calculation
* of the access code uses the access codes of child taxon records, so
* an accurate result depends on the accuracy of the children's access codes.
* @throws URISyntaxException
* @throws DocumentException
*/
- public InvocationResults updateAccessCode(String taxonRefNameOrCsid, boolean deep) throws URISyntaxException, DocumentException {
+ public InvocationResults updateAccessCode(String taxonRefNameOrCsid, boolean deep) throws URISyntaxException, DocumentException, Exception {
UpdateAccessCodeResults updateResults = updateAccessCode(taxonRefNameOrCsid, deep, false);
-
+
InvocationResults results = new InvocationResults();
results.setNumAffected(updateResults.getNumAffected());
results.setUserNote(updateResults.isChanged() ? "access code changed to " + updateResults.getAccessCode() : "access code not changed");
-
+
return results;
}
-
+
/**
* Updates the access code of the parent (broader context) of the specified taxon record.
- *
+ *
* @param taxonCsid The csid of the taxon record.
* @param propagate If true, propagate the access code up the taxon hierarchy to
* all ancestors of the taxon record. The propagation stops when
* the new value of the access code is the same as the old value,
* or when a root node (a node with no broader context) is reached.
- *
+ *
* If false, update only the access code of the parent.
* @return The results of the invocation.
* @throws URISyntaxException
* @throws DocumentException
*/
- public InvocationResults updateParentAccessCode(String taxonCsid, boolean propagate) throws URISyntaxException, DocumentException {
+ public InvocationResults updateParentAccessCode(String taxonCsid, boolean propagate) throws URISyntaxException, DocumentException, Exception {
PoxPayloadOut taxonPayload = findTaxonByCsid(taxonCsid);
String taxonRefName = getFieldValue(taxonPayload, TaxonConstants.REFNAME_SCHEMA_NAME, TaxonConstants.REFNAME_FIELD_NAME);
String accessCode = getFieldValue(taxonPayload, TaxonBotGardenConstants.ACCESS_CODE_SCHEMA_NAME, TaxonBotGardenConstants.ACCESS_CODE_FIELD_NAME);
logger.debug("updating parent access code: taxonRefName=" + taxonRefName + " propagate=" + propagate + " accessCode=" + accessCode);
UpdateAccessCodeResults updateResults = updateParentAccessCode(taxonCsid, accessCode, propagate);
-
+
InvocationResults results = new InvocationResults();
results.setNumAffected(updateResults.getNumAffected());
results.setUserNote(results.getNumAffected() + " access codes changed");
-
+
return results;
}
-
+
/**
* Updates the access codes of all taxon records that are referenced in the taxonomic identification
* field of the specified collectionobject.
- *
+ *
* @param collectionObjectCsid The csid of the collectionobject.
* @param propagate If true, propagate the access code up the taxon hierarchy to
* the ancestors of each referenced taxon record. The propagation stops when
* the new value of the access code is the same as the old value,
* or when a root node (a node with no broader context) is reached.
- *
+ *
* If false, update only the access codes of the taxon records
* that are directly referenced.
* @return The results of the invocation.
* @throws URISyntaxException
* @throws DocumentException
*/
- public InvocationResults updateReferencedAccessCodes(String collectionObjectCsid, boolean propagate) throws URISyntaxException, DocumentException {
+ public InvocationResults updateReferencedAccessCodes(String collectionObjectCsid, boolean propagate) throws URISyntaxException, DocumentException, Exception {
PoxPayloadOut collectionObjectPayload = findCollectionObjectByCsid(collectionObjectCsid);
-
- String deadFlag = getFieldValue(collectionObjectPayload, CollectionObjectBotGardenConstants.DEAD_FLAG_SCHEMA_NAME,
+
+ String deadFlag = getFieldValue(collectionObjectPayload, CollectionObjectBotGardenConstants.DEAD_FLAG_SCHEMA_NAME,
CollectionObjectBotGardenConstants.DEAD_FLAG_FIELD_NAME);
boolean isAlive = (deadFlag == null) || (!deadFlag.equalsIgnoreCase("true"));
logger.debug("updating referenced access codes: collectionObjectCsid=" + collectionObjectCsid + " propagate=" + propagate + " isAlive=" + isAlive);
- List<String> taxonRefNames = getFieldValues(collectionObjectPayload, CollectionObjectBotGardenConstants.TAXON_SCHEMA_NAME,
+ List<String> taxonRefNames = getFieldValues(collectionObjectPayload, CollectionObjectBotGardenConstants.TAXON_SCHEMA_NAME,
CollectionObjectBotGardenConstants.TAXON_FIELD_NAME);
long numAffected = 0;
-
+
for (String taxonRefName : taxonRefNames) {
PoxPayloadOut taxonPayload = findTaxonByRefName(taxonRefName);
- UpdateAccessCodeResults updateResults = updateAccessCode(taxonPayload, false, isAlive);
-
- if (updateResults.isChanged()) {
- numAffected += updateResults.getNumAffected();
-
- if (propagate) {
- UpdateAccessCodeResults parentUpdateResults = updateParentAccessCode(getCsid(taxonPayload), updateResults.getAccessCode(), true);
-
- numAffected += parentUpdateResults.getNumAffected();
+ if (taxonPayload != null) {
+ UpdateAccessCodeResults updateResults = updateAccessCode(taxonPayload, false, isAlive);
+ if (updateResults.isChanged()) {
+ numAffected += updateResults.getNumAffected();
+
+ if (propagate) {
+ UpdateAccessCodeResults parentUpdateResults = updateParentAccessCode(getCsid(taxonPayload), updateResults.getAccessCode(), true);
+
+ numAffected += parentUpdateResults.getNumAffected();
+ }
+ }
+ } else {
+ if (Tools.isBlank(taxonRefName) == false) {
+ String msg = String.format("%s found that cataloging/object record CSID=%s references taxon '%s' which could not be found.",
+ getClass().getName(), collectionObjectCsid, taxonRefName);
+ logger.warn(msg);
}
}
}
-
+
InvocationResults results = new InvocationResults();
results.setNumAffected(numAffected);
results.setUserNote(numAffected + " access codes changed");
-
+
return results;
}
-
+
/**
* Updates the access code of the specified taxon record. The access code is determined by
* examining all collectionobjects that have a taxonomic identification that matches the
- * refname of the taxon record, as well as the access codes of child (narrower context)
+ * refname of the taxon record, as well as the access codes of child (narrower context)
* taxon records. If all referencing collectionobjects are dead (as determined
* by the dead flag), and all child taxon records are dead (as determined by their access
* codes), then the access code is set to Dead. If any matching collectionobjects
* are not dead, or any child taxons are not dead, and the access code is currently Dead,
* the access code is set to Unrestricted. Otherwise, the access code is not changed.
- *
+ *
* @param taxonPayload The services payload of the taxon record.
* @param deep If true, update the access code of all descendant taxon records.
* On a deep update, the access codes of all descendant
* to Unrestricted without examining any other records.
* @return The results of the update.
* @throws DocumentException
- * @throws URISyntaxException
+ * @throws URISyntaxException
*/
- public UpdateAccessCodeResults updateAccessCode(PoxPayloadOut taxonPayload, boolean deep, boolean knownAlive) throws URISyntaxException, DocumentException {
+ public UpdateAccessCodeResults updateAccessCode(PoxPayloadOut taxonPayload, boolean deep, boolean knownAlive) throws URISyntaxException, DocumentException, Exception {
UpdateAccessCodeResults results = new UpdateAccessCodeResults();
boolean foundAlive = knownAlive;
-
+
String taxonCsid = getCsid(taxonPayload);
String taxonRefName = getFieldValue(taxonPayload, TaxonConstants.REFNAME_SCHEMA_NAME, TaxonConstants.REFNAME_FIELD_NAME);
String accessCode = getFieldValue(taxonPayload, TaxonBotGardenConstants.ACCESS_CODE_SCHEMA_NAME, TaxonBotGardenConstants.ACCESS_CODE_FIELD_NAME);
logger.debug("updating access code: taxonRefName=" + taxonRefName + " deep=" + deep + " knownAlive=" + knownAlive);
-
+
if (accessCode == null) {
accessCode = "";
}
-
+
List<String> childTaxonCsids = findNarrower(taxonCsid);
-
+
if (deep) {
long numChildrenChanged = 0;
-
+
// Update the access code on all the children, and track whether any are alive.
-
+
for (String childTaxonCsid : childTaxonCsids) {
UpdateAccessCodeResults childResults = updateAccessCode(childTaxonCsid, true, false);
-
+
if (!childResults.isSoftDeleted()) {
String childAccessCode = childResults.getAccessCode();
boolean isChildAlive = !childAccessCode.equals(TaxonBotGardenConstants.ACCESS_CODE_DEAD_VALUE);
-
+
if (isChildAlive) {
foundAlive = true;
}
-
+
if (childResults.isChanged()) {
numChildrenChanged++;
}
}
}
-
+
results.setNumAffected(numChildrenChanged);
}
else {
if (!foundAlive) {
// Check if any of the children are alive.
-
+
for (String childTaxonCsid : childTaxonCsids) {
PoxPayloadOut childTaxonPayload = findTaxonByCsid(childTaxonCsid);
-
- String childAccessCode = getFieldValue(childTaxonPayload, TaxonBotGardenConstants.ACCESS_CODE_SCHEMA_NAME,
+
+ String childAccessCode = getFieldValue(childTaxonPayload, TaxonBotGardenConstants.ACCESS_CODE_SCHEMA_NAME,
TaxonBotGardenConstants.ACCESS_CODE_FIELD_NAME);
boolean isChildAlive = !childAccessCode.equals(TaxonBotGardenConstants.ACCESS_CODE_DEAD_VALUE);
-
+
if (isChildAlive) {
foundAlive = true;
break;
}
}
}
-
+
if (!foundAlive) {
// Check if any examples of this taxon are alive.
-
+
RefName.AuthorityItem item = RefName.AuthorityItem.parse(taxonRefName);
String vocabularyShortId = item.getParentShortIdentifier();
-
- List<String> collectionObjectCsids = findReferencingCollectionObjects(TaxonomyAuthorityClient.SERVICE_NAME, vocabularyShortId, taxonCsid,
+
+ List<String> collectionObjectCsids = findReferencingCollectionObjects(TaxonomyAuthorityClient.SERVICE_NAME, vocabularyShortId, taxonCsid,
CollectionObjectBotGardenConstants.TAXON_SCHEMA_NAME + ":" + TAXON_FIELD_NAME_WITHOUT_PATH);
-
+
for (String collectionObjectCsid : collectionObjectCsids) {
PoxPayloadOut collectionObjectPayload = findCollectionObjectByCsid(collectionObjectCsid);
-
- String deadFlag = getFieldValue(collectionObjectPayload, CollectionObjectBotGardenConstants.DEAD_FLAG_SCHEMA_NAME,
+
+ String deadFlag = getFieldValue(collectionObjectPayload, CollectionObjectBotGardenConstants.DEAD_FLAG_SCHEMA_NAME,
CollectionObjectBotGardenConstants.DEAD_FLAG_FIELD_NAME);
boolean isDead = (deadFlag != null) && (deadFlag.equalsIgnoreCase("true"));
-
+
if (!isDead) {
foundAlive = true;
break;
}
}
}
-
+
String newAccessCode;
// The access code only needs to be changed if:
//
// 1. There is a living example of the taxon, but the access code is dead.
// 2. There are no living examples, but the access code is not dead.
- //
- // Otherwise, the access code should stay the same. In particular, if there is a
+ //
+ // Otherwise, the access code should stay the same. In particular, if there is a
// living example, and the access code is not dead, the current value of unrestricted
// or restricted should be retained.
if (foundAlive && (StringUtils.isEmpty(accessCode) || accessCode.equals(TaxonBotGardenConstants.ACCESS_CODE_DEAD_VALUE))) {
- newAccessCode = TaxonBotGardenConstants.ACCESS_CODE_UNRESTRICTED_VALUE;
+ newAccessCode = TaxonBotGardenConstants.ACCESS_CODE_UNRESTRICTED_VALUE;
}
else if (!foundAlive) {
newAccessCode = TaxonBotGardenConstants.ACCESS_CODE_DEAD_VALUE;
else {
newAccessCode = accessCode;
}
-
+
if (!newAccessCode.equals(accessCode)) {
String inAuthority = getFieldValue(taxonPayload, TaxonConstants.IN_AUTHORITY_SCHEMA_NAME, TaxonConstants.IN_AUTHORITY_FIELD_NAME);
setAccessCode(inAuthority, taxonCsid, newAccessCode);
-
+
results.setChanged(true);
results.setNumAffected(results.getNumAffected() + 1);
}
results.setAccessCode(newAccessCode);
-
+
return results;
}
-
+
/**
* Updates the access code of the taxon record with the specified refname or csid.
- *
+ *
* @param taxonRefNameOrCsid
* @param deep
* @param knownAlive
* @throws URISyntaxException
* @throws DocumentException
*/
- public UpdateAccessCodeResults updateAccessCode(String taxonRefNameOrCsid, boolean deep, boolean knownAlive) throws URISyntaxException, DocumentException {
+ public UpdateAccessCodeResults updateAccessCode(String taxonRefNameOrCsid, boolean deep, boolean knownAlive) throws URISyntaxException, DocumentException, Exception {
PoxPayloadOut taxonPayload;
-
- if (RefName.AuthorityItem.parse(taxonRefNameOrCsid) == null) {
+
+ if (RefName.AuthorityItem.parse(taxonRefNameOrCsid) == null) {
taxonPayload = findTaxonByCsid(taxonRefNameOrCsid);
}
else {
taxonPayload = findTaxonByRefName(taxonRefNameOrCsid);
}
-
+
return updateAccessCode(taxonPayload, deep, knownAlive);
}
-
+
+ /**
+ * Updates the access code of the taxon record with the specified refname or csid, when a new
+ * child taxon is known to have been added.
+ *
+ * @param taxonRefNameOrCsid
+ * @param deep
+ * @param newChildCsid The csid of the newly added child.
+ * @return
+ * @throws URISyntaxException
+ * @throws DocumentException
+ */
+ public UpdateAccessCodeResults updateAccessCode(String taxonRefNameOrCsid, boolean deep, String newChildTaxonCsid) throws URISyntaxException, DocumentException, Exception {
+ PoxPayloadOut newChildTaxonPayload = findTaxonByCsid(newChildTaxonCsid);
+ String newChildTaxonAccessCode = getFieldValue(newChildTaxonPayload, TaxonBotGardenConstants.ACCESS_CODE_SCHEMA_NAME, TaxonBotGardenConstants.ACCESS_CODE_FIELD_NAME);
+
+ if (newChildTaxonAccessCode == null) {
+ newChildTaxonAccessCode = "";
+ }
+
+ boolean knownAlive = !newChildTaxonAccessCode.equals(TaxonBotGardenConstants.ACCESS_CODE_DEAD_VALUE);
+
+ return updateAccessCode(taxonRefNameOrCsid, deep, knownAlive);
+ }
+
/**
* Updates the access code of the parent (broader context) of the specified taxon record,
* whose access code is assumed to be a specified value.
- *
+ *
* @param taxonCsid The csid of the taxon record.
* @param accessCode The access code of the taxon record.
* @param propagate If true, propagate the access code up the taxon hierarchy to
* all ancestors of the taxon record. The propagation stops when
* the new value of the access code is the same as the old value,
* or when a root node (a node with no broader context) is reached.
- *
+ *
* If false, update only the access code of the parent.
* @return The results of the update.
* @throws URISyntaxException
* @throws DocumentException
*/
- public UpdateAccessCodeResults updateParentAccessCode(String taxonCsid, String accessCode, boolean propagate) throws URISyntaxException, DocumentException {
+ public UpdateAccessCodeResults updateParentAccessCode(String taxonCsid, String accessCode, boolean propagate) throws URISyntaxException, DocumentException, Exception {
UpdateAccessCodeResults results = new UpdateAccessCodeResults();
String parentTaxonCsid = findBroader(taxonCsid);
long numAffected = 0;
-
+
logger.debug("updating parent access code: taxonCsid=" + taxonCsid + " accessCode=" + accessCode + " propagate=" + propagate);
if (parentTaxonCsid != null) {
boolean isAlive = (accessCode == null) || !accessCode.equals(TaxonBotGardenConstants.ACCESS_CODE_DEAD_VALUE);
- UpdateAccessCodeResults parentUpdateResults = updateAccessCode(parentTaxonCsid, false, isAlive);
-
+ UpdateAccessCodeResults parentUpdateResults = updateAccessCode(parentTaxonCsid, false, isAlive);
+
if (parentUpdateResults.isChanged()) {
// Except for numAffected, the result fields are probably not all that useful in this situation.
// Set the changed flag to whether the immediate parent was changed, and the access code to
// the immediate parent's.
-
+
results.setAccessCode(parentUpdateResults.getAccessCode());
results.setChanged(true);
-
+
numAffected += parentUpdateResults.getNumAffected();
if (propagate) {
}
}
}
-
+
results.setNumAffected(numAffected);
-
+
return results;
}
-
+
/**
* Sets the access code of the specified taxon record to the specified value.
- *
+ *
* @param authorityCsid The csid of the authority containing the taxon record.
* @param taxonCsid The csid of the taxon record.
* @param accessCode The value of the access code.
- * @throws URISyntaxException
+ * @throws URISyntaxException
*/
private void setAccessCode(String authorityCsid, String taxonCsid, String accessCode) throws URISyntaxException {
- String updatePayload =
+ String updatePayload =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<document name=\"taxon\">" +
"<ns2:taxon_naturalhistory xmlns:ns2=\"http://collectionspace.org/services/taxonomy/domain/naturalhistory\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
"</document>";
AuthorityResource<?, ?> resource = (AuthorityResource<?, ?>) getResourceMap().get(TaxonomyAuthorityClient.SERVICE_NAME);
- resource.updateAuthorityItem(getResourceMap(), createUriInfo(), authorityCsid, taxonCsid, updatePayload);
+ resource.updateAuthorityItem(getServiceContext(), getResourceMap(), createUriInfo(), authorityCsid, taxonCsid, updatePayload);
}
-
- private class UpdateAccessCodeResults {
+
+ public class UpdateAccessCodeResults {
private boolean isSoftDeleted = false;
private boolean isChanged = false;
private String accessCode = null;
public void setChanged(boolean isChanged) {
this.isChanged = isChanged;
}
-
+
public String getAccessCode() {
return accessCode;
}
-
+
public void setAccessCode(String accessCode) {
this.accessCode = accessCode;
}
* @throws URISyntaxException
* @throws DocumentException
*/
- public InvocationResults updateReferencingRareFlags(String taxonCsid) throws URISyntaxException, DocumentException {
+ public InvocationResults updateReferencingRareFlags(String taxonCsid, String vocabularyCsid) throws URISyntaxException, DocumentException {
PoxPayloadOut taxonPayload = findTaxonByCsid(taxonCsid);
String taxonRefName = getFieldValue(taxonPayload, TaxonConstants.REFNAME_SCHEMA_NAME, TaxonConstants.REFNAME_FIELD_NAME);
return results;
}
+ public InvocationResults updateReferencingRareFlags(String taxonCsid) throws URISyntaxException, DocumentException, Exception {
+ return updateReferencingRareFlags(taxonCsid, null);
+ }
+
/**
* Updates the rare flag of the specified collectionobject.
*
<artifactId>org.collectionspace.services.config</artifactId>
<version>${project.version}</version>
</dependency>
- <dependency>
- <groupId>org.collectionspace.services</groupId>
- <artifactId>org.collectionspace.services.3rdparty.nuxeo.thumbnail</artifactId>
- <version>${project.version}</version>
- </dependency>
<dependency>
<groupId>org.collectionspace.services</groupId>
<artifactId>org.collectionspace.services.common-api</artifactId>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
- <version>${tomcat.version}</version>
<scope>provided</scope>
</dependency>
import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
-import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import org.nuxeo.ecm.platform.filemanager.service.extension.FileImporter;
import org.nuxeo.ecm.platform.filemanager.utils.FileManagerUtils;
import org.nuxeo.ecm.platform.types.TypeManager;
-import org.nuxeo.ecm.core.api.CoreSession;
import org.nuxeo.ecm.core.api.IdRef;
import org.nuxeo.ecm.core.api.NuxeoException;
import org.nuxeo.ecm.core.api.blobholder.BlobHolder;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.DocumentRef;
import org.nuxeo.ecm.core.api.PropertyException;
-import org.nuxeo.ecm.core.api.VersioningOption;
import org.nuxeo.ecm.core.blob.BlobManager;
import org.nuxeo.ecm.core.blob.BlobProvider;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.commons.io.IOUtils;
+
import org.collectionspace.services.client.PoxPayloadIn;
import org.collectionspace.services.client.PoxPayloadOut;
import org.collectionspace.services.common.FileUtilities;
import org.collectionspace.services.nuxeo.client.java.CommonList;
import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface;
import org.collectionspace.services.nuxeo.client.java.NuxeoRepositoryClientImpl;
-import org.collectionspace.services.nuxeo.extension.thumbnail.ThumbnailConstants;
import org.collectionspace.services.nuxeo.util.NuxeoUtils;
+import org.collectionspace.services.nuxeo.util.ThumbnailConstants;
import org.collectionspace.services.config.service.ListResultField;
/**
result.setMeasuredPartGroupList(measuredPartGroupList);
}
}
-
+
// Check to see if a thumbnail preview was created by Nuxeo
if (documentModel.hasFacet(ThumbnailConstants.THUMBNAIL_FACET)) {
String errorMsg = null;
logger.debug(errorMsg, e);
}
}
-
+
if (errorMsg == null) {
logger.info("A thumbnail preview was created for this document blob: " + thumbnailName);
} else {
import java.util.List;
import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.collectionspace.services.client.workflow.WorkflowClient;
import org.collectionspace.services.common.api.Tools;
import org.collectionspace.services.config.tenant.EventListenerConfig;
import org.collectionspace.services.config.tenant.Param;
+import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface;
+import org.collectionspace.services.nuxeo.util.NuxeoUtils;
import org.nuxeo.common.collections.ScopeType;
import org.nuxeo.common.collections.ScopedMap;
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.impl.DocumentEventContext;
public abstract class AbstractCSEventListenerImpl implements CSEventListener {
private static Map<String, List<String>> mapOfrepositoryNames = new HashMap<String, List<String>>(); // <className, repositoryName>
private static Map<String, Map<String, Map<String, String>>> eventListenerParamsMap = new HashMap<String, Map<String, Map<String, String>>>(); // <repositoryName, Map<EventListenerId, Map<key, value>>>
private static Map<String, String> nameMap = new HashMap<String, String>();
-
- public static final String DOCMODEL_CONTEXT_PROPERTY_PREFIX = ScopeType.DEFAULT.getScopePrefix();
+
+ // SQL clauses
+ private final static String NONVERSIONED_NONPROXY_DOCUMENT_WHERE_CLAUSE_FRAGMENT =
+ "AND ecm:isCheckedInVersion = 0"
+ + " AND ecm:isProxy = 0 ";
+ protected final static String ACTIVE_DOCUMENT_WHERE_CLAUSE_FRAGMENT =
+ "AND (ecm:currentLifeCycleState <> 'deleted') "
+ + NONVERSIONED_NONPROXY_DOCUMENT_WHERE_CLAUSE_FRAGMENT;
+ static final String DOCMODEL_CONTEXT_PROPERTY_PREFIX = ScopeType.DEFAULT.getScopePrefix();
public AbstractCSEventListenerImpl() {
// Intentionally left blank
@Override
public boolean isRegistered(Event event) {
boolean result = false;
-
+
if (event != null && event.getContext() != null) {
result = getRepositoryNameList().contains(event.getContext().getRepositoryName());
}
-
+
return result;
}
+
+ /*
+ * This method is meant to be the bottleneck for handling a Nuxeo document event.
+ */
+ final public void handleEvent(Event event) {
+ getLogger().trace(String.format("Eventlistener '%s' presenented with '%s' event.",
+ getClass().getName(), event.getName()));
+ boolean isRegistered = isRegistered(event);
+ try {
+ if (isRegistered && shouldHandleEvent(event)) {
+ handleCSEvent(event);
+ getLogger().debug(String.format("Eventlistener '%s' accepted '%s' event.",
+ getClass().getName(), event.getName()));
+ } else {
+ if (isRegistered) {
+ getLogger().debug(String.format("Eventlistener '%s' declined to handle '%s' event.",
+ getClass().getName(), event.getName()));
+ } else {
+ getLogger().trace(String.format("Eventlistener '%s' was not registered in the service bindings for the tenant with repo '%s'.",
+ getClass().getName(), event.getContext().getRepositoryName()));
+ }
+ }
+ } catch (Exception e) {
+ String errMsg = String.format("Eventlistener '%s' presenented with '%s' event but encountered an error: %s",
+ getClass().getName(), event.getName(), e.getMessage());
+ if (getLogger().isTraceEnabled()) {
+ getLogger().error(errMsg, e);
+ } else {
+ getLogger().error(errMsg);
+ }
+ }
+ }
+
/**
* An event listener can be registered by multiple tenants, so we keep track of that here.
- *
+ *
* @return - the list of tenants/repositories that an event listener is registered with.
*/
protected List<String> getRepositoryNameList() {
String key = this.getClass().getName();
List<String> result = mapOfrepositoryNames.get(key);
-
+
if (result == null) synchronized(this) {
result = new ArrayList<String>();
mapOfrepositoryNames.put(key, result);
}
-
+
return result;
}
-
+
/**
* The list of parameters (specified in a tenant's bindings) for event listeners
* @return
}
/**
- * Returns 'true' if this collection changed as a result of the call.
+ * Returns 'true' if this collection changed as a result of the call.
*/
@Override
public boolean register(String respositoryName, EventListenerConfig eventListenerConfig) {
boolean result = false;
-
+
// Using the repositoryName as a qualifier, register this event listener's name as specified in the tenant bindings.
setName(respositoryName, eventListenerConfig.getId());
-
+
// Register this event listener with the given repository name
if (getRepositoryNameList().add(respositoryName)) {
result = true;
}
-
+
if (eventListenerConfig.getParamList() != null) {
// Set this event listeners parameters, if any. Params are qualified with the repositoryName since multiple tenants might be registering the same event listener but with different params.
List<Param> paramList = eventListenerConfig.getParamList().getParam(); // values from the tenant bindings that we need to copy into the event listener
}
}
}
-
+
return result;
}
-
+
protected void setName(String repositoryName, String eventListenerName) {
nameMap.put(repositoryName, eventListenerName);
}
}
return result;
}
-
+
@Override
public String getName(String repositoryName) {
return nameMap.get(repositoryName);
}
+
+ //
+ // Return a property in the document model's transient context.
+ //
+ protected Serializable getContextPropertyValue(DocumentEventContext docEventContext, String key) {
+ return docEventContext.getProperties().get(key);
+ }
//
// Set a property in the document model's transient context.
@Override
public void setDocModelContextProperty(DocumentModel collectionObjectDocModel, String key, Serializable value) {
ScopedMap contextData = collectionObjectDocModel.getContextData();
- contextData.putIfAbsent(DOCMODEL_CONTEXT_PROPERTY_PREFIX + key, value);
+ contextData.putIfAbsent(DOCMODEL_CONTEXT_PROPERTY_PREFIX + key, value);
}
-
+
//
// Clear a property from the docModel's context
//
@Override
public void clearDocModelContextProperty(DocumentModel docModel, String key) {
ScopedMap contextData = docModel.getContextData();
- contextData.remove(DOCMODEL_CONTEXT_PROPERTY_PREFIX + key);
+ contextData.remove(DOCMODEL_CONTEXT_PROPERTY_PREFIX + key);
}
+ //
+ // Derived classes need to implement.
+ //
+ abstract protected Log getLogger();
+
+ //FIXME: Does not include all the sync-related "delete" workflow states
+ /**
+ * Identifies whether a supplied event concerns a document that has
+ * been transitioned to the 'deleted' workflow state.
+ *
+ * @param eventContext an event context
+ *
+ * @return true if this event concerns a document that has
+ * been transitioned to the 'deleted' workflow state.
+ */
+ protected boolean isDocumentSoftDeletedEvent(EventContext eventContext) {
+ boolean isSoftDeletedEvent = false;
+
+ if (eventContext instanceof DocumentEventContext) {
+ if (eventContext.getProperties().containsKey(WorkflowClient.WORKFLOWTRANSITION_TO)
+ &&
+ (eventContext.getProperties().get(WorkflowClient.WORKFLOWTRANSITION_TO).equals(WorkflowClient.WORKFLOWSTATE_DELETED)
+ ||
+ eventContext.getProperties().get(WorkflowClient.WORKFLOWTRANSITION_TO).equals(WorkflowClient.WORKFLOWSTATE_LOCKED_DELETED))) {
+ isSoftDeletedEvent = true;
+ }
+ }
+
+ return isSoftDeletedEvent;
+ }
+
+ /**
+ * 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.
+ */
+ protected static 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; currently, whether
+ * it is not in a 'deleted' workflow state.
+ *
+ * @param docModel
+ * @return true if the document is an active document; false if it is not.
+ */
+ protected static boolean isActiveDocument(DocumentModel docModel) {
+ return isActiveDocument(docModel, false, null);
+ }
+
+ protected static boolean isActiveDocument(DocumentModel docModel, boolean isAboutToBeRemovedEvent, String aboutToBeRemovedCsid) {
+ boolean isActiveDocument = false;
+
+ if (docModel != null) {
+ if (!docModel.getCurrentLifeCycleState().contains(WorkflowClient.WORKFLOWSTATE_DELETED)) {
+ isActiveDocument = true;
+ }
+ //
+ // 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;
+ }
+
+ /**
+ * Returns the current document model for a record identified by a CSID.
+ *
+ * Excludes documents which have been versioned (i.e. are a non-current
+ * version of a document), are a proxy for another document, or are
+ * un-retrievable via their CSIDs.
+ *
+ * @param session a repository session.
+ * @param csid a CollectionObject identifier (CSID)
+ * @return a document model for the document identified by the supplied
+ * CSID.
+ */
+ protected DocumentModel getCurrentDocModelFromCsid(CoreSessionInterface session, String csid) {
+ DocumentModelList docModelList = null;
+
+ if (Tools.isEmpty(csid)) {
+ return null;
+ }
+
+ try {
+ final String query = "SELECT * FROM "
+ + NuxeoUtils.BASE_DOCUMENT_TYPE
+ + " WHERE "
+ + NuxeoUtils.getByNameWhereClause(csid)
+ + " "
+ + NONVERSIONED_NONPROXY_DOCUMENT_WHERE_CLAUSE_FRAGMENT;
+ docModelList = session.query(query);
+ } catch (Exception e) {
+ getLogger().warn("Exception in query to get active document model for CSID: " + csid, e);
+ }
+
+ if (docModelList == null || docModelList.isEmpty()) {
+ getLogger().warn("Could not get active document models for CSID=" + csid);
+ return null;
+ } else if (docModelList.size() != 1) {
+ getLogger().error("Found more than 1 active document with CSID=" + csid);
+ return null;
+ }
+
+ return docModelList.get(0);
+ }
}
--- /dev/null
+package org.collectionspace.services.nuxeo.listener;
+
+import java.util.Iterator;
+
+import org.nuxeo.ecm.core.event.Event;
+import org.nuxeo.ecm.core.event.EventBundle;
+import org.nuxeo.ecm.core.event.PostCommitEventListener;
+
+public abstract class AbstractCSEventPostCommitListenerImpl extends AbstractCSEventListenerImpl implements PostCommitEventListener {
+
+ /**
+ * Subclasses need to override and return 'true' if they want to handle the event bundle
+ * @param eventBundle
+ * @return
+ */
+ public abstract boolean shouldHandleEventBundle(EventBundle eventBundle);
+
+ /*
+ * Process all the events in the bundle
+ */
+ @Override
+ public final void handleEvent(EventBundle eventBundle) {
+ if (shouldHandleEventBundle(eventBundle)) {
+ Iterator<Event> iter = eventBundle.iterator();
+ while (iter.hasNext()) {
+ this.handleEvent(iter.next());
+ }
+ }
+ }
+}
--- /dev/null
+package org.collectionspace.services.nuxeo.listener;
+
+import org.nuxeo.ecm.core.event.EventListener;
+
+public abstract class AbstractCSEventSyncListenerImpl extends AbstractCSEventListenerImpl implements EventListener {
+ // Intentionally blank. Needed so we can "implement" Nuxeo's synchronous EvenListener class
+}
import org.collectionspace.services.config.tenant.EventListenerConfig;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.event.Event;
-import org.nuxeo.ecm.core.event.EventListener;
-public interface CSEventListener extends EventListener {
+public interface CSEventListener {
/**
* Register ourself as an event listener for the named repository -the repo name corresponds to a specific tenant.
* @param respositoryName - The name of the Nuxeo repository which links us to a CollectionSpace tenant.
*/
boolean register(String respositoryName, EventListenerConfig eventListenerConfig);
+ /**
+ * If the listener wants to handle the event, it should return 'true'.
+ * @param event
+ * @return
+ */
+ boolean shouldHandleEvent(Event event);
+
+ /**
+ * Processing of the event.
+ */
+ void handleCSEvent(Event event);
+
/**
* Determines if we are a registered event listener for the given event.
* @param event
* Returns the name of the event listener as defined during registration -see register() method.
* @return
*/
- String getName(String repositoryName);
+ String getName(String repositoryName);
}
-package org.collectionspace.services.nuxeo.extension.thumbnail;
+package org.collectionspace.services.nuxeo.util;
public class ThumbnailConstants {
public static final String THUMBNAIL_SIZE_PARAMETER_NAME = "size";