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