1 package org.collectionspace.services.listener;
3 import java.io.Serializable;
4 import java.util.ArrayList;
5 import java.util.Arrays;
6 import java.util.Iterator;
9 import org.slf4j.Logger;
10 import org.slf4j.LoggerFactory;
12 import org.collectionspace.services.nuxeo.listener.AbstractCSEventSyncListenerImpl;
13 import org.nuxeo.ecm.core.api.CoreSession;
14 import org.nuxeo.ecm.core.api.DocumentModel;
15 import org.nuxeo.ecm.core.api.DocumentModelList;
16 import org.nuxeo.ecm.core.api.event.CoreEventConstants;
17 import org.nuxeo.ecm.core.api.event.DocumentEventTypes;
18 import org.nuxeo.ecm.core.event.Event;
19 import org.nuxeo.ecm.core.event.impl.DocumentEventContext;
20 import org.nuxeo.runtime.api.Framework;
23 * Event listener that stores the values of fields of interest before documents are updated or
24 * deleted. This is necessary because the previous/deleted document model will not be available
25 * to a post-modification/deletion event listener. Storing the previous/deleted values allows
26 * the post-modification/deletion event listener to take action if a field value was changed,
27 * or if a document was deleted that had a certain field value.
29 * This is a separate class from the Reindex listener, because the Reindex listener should be
30 * async and post-commit, so it must implement PostCommitEventListener. This listener must be
31 * synchronous and pre-commit, so it must implement EventListener. Nuxeo does not support
32 * a single class that implements both PostCommitEventListener and EventListener (such a listener
33 * will only run synchronously).
35 public class ReindexSupport extends AbstractCSEventSyncListenerImpl {
36 private static final Logger logger = LoggerFactory.getLogger(ReindexSupport.class);
39 public boolean shouldHandleEvent(Event event) {
40 DocumentEventContext eventContext = (DocumentEventContext) event.getContext();
42 if (Framework.isBooleanPropertyTrue(Reindex.ELASTICSEARCH_ENABLED_PROP) && eventContext instanceof DocumentEventContext) {
43 DocumentModel doc = eventContext.getSourceDocument();
44 String docType = doc.getType();
47 docType.startsWith("Media")
48 || docType.startsWith("Relation")
49 || docType.startsWith("Acquisition")
59 @SuppressWarnings("unchecked")
60 public void handleCSEvent(Event event) {
61 // TODO: Make this configurable. This is currently hardcoded to the needs of the standard
64 // For core/all profiles:
65 // - When a media record is about to be updated, store the value of the publishToList
68 // For materials profile:
69 // - When a media record is about to be updated, store the value of the coverage field.
70 // - When a media record is about to be removed, store the value of the coverage field.
72 DocumentEventContext eventContext = (DocumentEventContext) event.getContext();
73 DocumentModel doc = eventContext.getSourceDocument();
74 String docType = doc.getType();
75 String eventName = event.getName();
77 if (docType.startsWith("Media")) {
78 if (eventName.equals(DocumentEventTypes.BEFORE_DOC_UPDATE)) {
79 DocumentModel previousDoc = (DocumentModel) eventContext.getProperty(CoreEventConstants.PREVIOUS_DOCUMENT_MODEL);
80 String coverage = (String) previousDoc.getProperty("media_common", "coverage");
82 // Materials profile had publishToList defined in a local extension schema before
83 // that field was added to the common schema.
85 List<String> publishTo = (List<String>) previousDoc.getProperty(
86 previousDoc.hasSchema("media_materials") ? "media_materials" : "media_common",
89 eventContext.setProperty(Reindex.PREV_COVERAGE_KEY, coverage);
90 eventContext.setProperty(Reindex.PREV_PUBLISH_TO_KEY, (Serializable) publishTo);
92 else if (eventName.equals(DocumentEventTypes.ABOUT_TO_REMOVE)) {
93 String coverage = (String) doc.getProperty("media_common", "coverage");
95 eventContext.setProperty(Reindex.PREV_COVERAGE_KEY, coverage);
97 storePrevRelatedCollectionObjects(eventContext, doc);
100 else if (docType.startsWith("Acquisition")) {
101 if (eventName.equals(DocumentEventTypes.BEFORE_DOC_UPDATE)) {
102 DocumentModel previousDoc = (DocumentModel) eventContext.getProperty(CoreEventConstants.PREVIOUS_DOCUMENT_MODEL);
103 String creditLine = (String) previousDoc.getProperty("acquisitions_common", "creditLine");
105 eventContext.setProperty(Reindex.PREV_CREDIT_LINE_KEY, creditLine);
107 else if (eventName.equals(DocumentEventTypes.ABOUT_TO_REMOVE)) {
108 storePrevRelatedCollectionObjects(eventContext, doc);
111 else if (docType.startsWith("Relation")) {
112 if (eventName.equals(DocumentEventTypes.ABOUT_TO_REMOVE)) {
113 String subjectDocumentType = (String) doc.getProperty("relations_common", "subjectDocumentType");
114 String objectDocumentType = (String) doc.getProperty("relations_common", "objectDocumentType");
117 (subjectDocumentType.equals("Media") || subjectDocumentType.equals("Acquisition"))
118 && objectDocumentType.equals("CollectionObject")
120 String collectionObjectCsid = (String) doc.getProperty("relations_common", "objectCsid");
122 eventContext.setProperty(Reindex.PREV_RELATED_COLLECTION_OBJECT_CSID_KEY, (Serializable) Arrays.asList(collectionObjectCsid));
128 private void storePrevRelatedCollectionObjects(DocumentEventContext eventContext, DocumentModel doc) {
129 CoreSession session = doc.getCoreSession();
130 String tenantId = (String) doc.getProperty("collectionspace_core", "tenantId");
131 String csid = doc.getName();
133 String relatedRecordQuery = String.format("SELECT * FROM Relation WHERE relations_common:subjectCsid = '%s' AND relations_common:objectDocumentType = 'CollectionObject' AND ecm:currentLifeCycleState = 'project' AND collectionspace_core:tenantId = '%s'", csid, tenantId);
134 DocumentModelList relationDocs = session.query(relatedRecordQuery);
135 List<String> collectionObjectCsids = new ArrayList<String>();
137 if (relationDocs.size() > 0) {
138 Iterator<DocumentModel> iterator = relationDocs.iterator();
140 while (iterator.hasNext()) {
141 DocumentModel relationDoc = iterator.next();
142 String collectionObjectCsid = (String) relationDoc.getProperty("relations_common", "objectCsid");
144 collectionObjectCsids.add(collectionObjectCsid);
148 eventContext.setProperty(Reindex.PREV_RELATED_COLLECTION_OBJECT_CSID_KEY, (Serializable) collectionObjectCsids);
152 public Logger getLogger() {