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