]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
f645744e99770f68e0d33d4a49e1c2c8be526228
[tmp/jakarta-migration.git] /
1 package org.collectionspace.services.listener;
2
3 import java.util.List;
4
5 import org.apache.commons.collections.ListUtils;
6 import org.apache.commons.lang3.StringUtils;
7
8 import org.slf4j.Logger;
9 import org.slf4j.LoggerFactory;
10
11 import org.collectionspace.services.nuxeo.listener.AbstractCSEventPostCommitListenerImpl;
12 import org.nuxeo.ecm.core.api.DocumentModel;
13 import org.nuxeo.ecm.core.api.LifeCycleConstants;
14 import org.nuxeo.ecm.core.api.event.DocumentEventTypes;
15 import org.nuxeo.ecm.core.event.Event;
16 import org.nuxeo.ecm.core.event.EventBundle;
17 import org.nuxeo.ecm.core.event.impl.DocumentEventContext;
18 import org.nuxeo.elasticsearch.ElasticSearchComponent;
19 import org.nuxeo.elasticsearch.api.ElasticSearchService;
20 import org.nuxeo.runtime.api.Framework;
21
22 /**
23  * Event listener that triggers reindexing of records in Elasticsearch when an associated record
24  * is created/updated/deleted. When a record is created or updated Nuxeo will automatically
25  * reindex it in ElasticSearch, but Nuxeo does not know about other records that may also need to
26  * be reindexed; for example, if a related record denormalizes data from the updated record at
27  * index time.
28  */
29 public class Reindex extends AbstractCSEventPostCommitListenerImpl {
30         private static final Logger logger = LoggerFactory.getLogger(Reindex.class);
31
32     // FIXME: This listener runs asynchronously post-commit, so that reindexing records after a
33     // save does not hold up the save.
34
35     public static final String PREV_COVERAGE_KEY = "Reindex.PREV_COVERAGE";
36     public static final String PREV_PUBLISH_TO_KEY = "Reindex.PREV_PUBLISH_TO";
37     public static final String ELASTICSEARCH_ENABLED_PROP = "elasticsearch.enabled";
38     
39         @Override
40         public boolean shouldHandleEventBundle(EventBundle eventBundle) {
41         if (Framework.isBooleanPropertyTrue(ELASTICSEARCH_ENABLED_PROP) && eventBundle.size() > 0) {
42                 return true;
43         }
44         
45         return false;
46         }
47         
48         @Override
49         public boolean shouldHandleEvent(Event event) {
50         DocumentEventContext eventContext = (DocumentEventContext) event.getContext();
51         DocumentModel doc = eventContext.getSourceDocument();
52         String docType = doc.getType();
53         
54         if (docType.startsWith("Media")) {
55                 return true;
56         }
57         
58         return false;
59         }
60
61         @Override
62         @SuppressWarnings("unchecked")
63         public void handleCSEvent(Event event) {
64         DocumentEventContext eventContext = (DocumentEventContext) event.getContext();
65         DocumentModel doc = eventContext.getSourceDocument();
66         String eventName = event.getName();
67
68         // When a media record is created, reindex the material item that is referenced by its
69         // coverage field.
70         
71         // When a media record is updated and the coverage changed, reindex both the old and new
72         // referenced material items.
73
74         // When a media record is deleted, reindex the material item that was referenced by its
75         // coverage field.
76         
77         // TODO: Make this configurable. This is currently hardcoded to the needs of the material
78         // profile/Material Order application.
79         
80         if (
81             eventName.equals(DocumentEventTypes.DOCUMENT_CREATED) ||
82             eventName.equals(DocumentEventTypes.DOCUMENT_UPDATED)
83         ) {
84             String prevCoverage = (String) eventContext.getProperty(PREV_COVERAGE_KEY);
85             String coverage = (String) doc.getProperty("media_common", "coverage");
86
87             List<String> prevPublishTo = (List<String>) eventContext.getProperty(PREV_PUBLISH_TO_KEY);
88             List<String> publishTo = (List<String>) doc.getProperty("media_materials", "publishToList");
89
90             if (doc.getCurrentLifeCycleState().equals(LifeCycleConstants.DELETED_STATE)) {
91                 reindex(doc.getRepositoryName(), coverage);
92             }
93             else if (
94                 !ListUtils.isEqualList(prevPublishTo, publishTo) ||
95                 !StringUtils.equals(prevCoverage, coverage)
96             ) {
97                 if (!StringUtils.equals(prevCoverage, coverage)) {
98                     reindex(doc.getRepositoryName(), prevCoverage);
99                 }
100
101                 reindex(doc.getRepositoryName(), coverage);
102             }
103         }
104         else if (eventName.equals(DocumentEventTypes.DOCUMENT_REMOVED)) {
105             String prevCoverage = (String) eventContext.getProperty(PREV_COVERAGE_KEY);
106
107             reindex(doc.getRepositoryName(), prevCoverage);
108         }
109         }
110
111         @Override
112         protected Logger getLogger() {
113                 return logger;
114         }
115
116     private void reindex(String repositoryName, String refName) {
117         if (StringUtils.isEmpty(refName)) {
118             return;
119         }
120
121         String escapedRefName = refName.replace("'", "\\'");
122         String query = String.format("SELECT ecm:uuid FROM Materialitem WHERE collectionspace_core:refName = '%s'", escapedRefName);
123
124         ElasticSearchComponent es = (ElasticSearchComponent) Framework.getService(ElasticSearchService.class);
125         es.runReindexingWorker(repositoryName, query);
126     }
127 }