1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.search.solr.internal

File SolrIndexEventListener.java

 

Coverage histogram

../../../../../img/srcFileCovDistChart9.png
38% of files have more coverage

Code metrics

22
41
3
1
174
106
18
0.44
13.67
3
6

Classes

Class Line # Actions
SolrIndexEventListener 66 41 0% 18 8
0.878787987.9%
 

Contributing tests

This file is covered by 1 test. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.search.solr.internal;
21   
22    import java.util.Arrays;
23    import java.util.List;
24    import java.util.Locale;
25   
26    import javax.inject.Inject;
27    import javax.inject.Named;
28    import javax.inject.Provider;
29    import javax.inject.Singleton;
30   
31    import org.slf4j.Logger;
32    import org.xwiki.bridge.event.DocumentCreatedEvent;
33    import org.xwiki.bridge.event.DocumentDeletedEvent;
34    import org.xwiki.bridge.event.DocumentUpdatedEvent;
35    import org.xwiki.bridge.event.WikiDeletedEvent;
36    import org.xwiki.component.annotation.Component;
37    import org.xwiki.model.reference.DocumentReference;
38    import org.xwiki.model.reference.WikiReference;
39    import org.xwiki.observation.EventListener;
40    import org.xwiki.observation.event.Event;
41    import org.xwiki.search.solr.internal.api.SolrIndexer;
42   
43    import com.xpn.xwiki.doc.XWikiAttachment;
44    import com.xpn.xwiki.doc.XWikiDocument;
45    import com.xpn.xwiki.internal.event.AbstractAttachmentEvent;
46    import com.xpn.xwiki.internal.event.AttachmentAddedEvent;
47    import com.xpn.xwiki.internal.event.AttachmentDeletedEvent;
48    import com.xpn.xwiki.internal.event.AttachmentUpdatedEvent;
49    import com.xpn.xwiki.internal.event.EntityEvent;
50    import com.xpn.xwiki.internal.event.XObjectAddedEvent;
51    import com.xpn.xwiki.internal.event.XObjectDeletedEvent;
52    import com.xpn.xwiki.internal.event.XObjectPropertyAddedEvent;
53    import com.xpn.xwiki.internal.event.XObjectPropertyDeletedEvent;
54    import com.xpn.xwiki.internal.event.XObjectPropertyUpdatedEvent;
55    import com.xpn.xwiki.internal.event.XObjectUpdatedEvent;
56   
57    /**
58    * Event listener that monitors changes in the wiki and updates the Solr index accordingly.
59    *
60    * @version $Id: b73e28a20f31608113d6dcf58e6656e41ce8dc58 $
61    * @since 5.1M2
62    */
63    @Component
64    @Named("solr.update")
65    @Singleton
 
66    public class SolrIndexEventListener implements EventListener
67    {
68    /**
69    * The events to listen to that trigger the index update.
70    */
71    private static final List<Event> EVENTS = Arrays.<Event> asList(new DocumentUpdatedEvent(),
72    new DocumentCreatedEvent(), new DocumentDeletedEvent(), new AttachmentAddedEvent(),
73    new AttachmentDeletedEvent(), new AttachmentUpdatedEvent(), new XObjectAddedEvent(), new XObjectDeletedEvent(),
74    new XObjectUpdatedEvent(), new XObjectPropertyAddedEvent(), new XObjectPropertyDeletedEvent(),
75    new XObjectPropertyUpdatedEvent(), new WikiDeletedEvent());
76   
77    /**
78    * Logging framework.
79    */
80    @Inject
81    protected Logger logger;
82   
83    /**
84    * The solr index.
85    * <p>
86    * Lazily initialize the {@link SolrIndexer} to not initialize it too early.
87    */
88    @Inject
89    private Provider<SolrIndexer> solrIndexer;
90   
 
91  3 toggle @Override
92    public List<Event> getEvents()
93    {
94  3 return EVENTS;
95    }
96   
 
97  66 toggle @Override
98    public String getName()
99    {
100  66 return this.getClass().getName();
101    }
102   
 
103  1490 toggle @Override
104    public void onEvent(Event event, Object source, Object data)
105    {
106  1490 try {
107  1490 if (event instanceof DocumentUpdatedEvent) {
108  172 XWikiDocument document = (XWikiDocument) source;
109   
110  172 this.solrIndexer.get().index(document.getDocumentReferenceWithLocale(), false);
111  1318 } else if (event instanceof DocumentCreatedEvent) {
112  155 XWikiDocument document = (XWikiDocument) source;
113   
114  155 if (!Locale.ROOT.equals(document.getLocale())) {
115    // If a new translation is added to a document reindex the whole document (could be optimized a bit
116    // by reindexing only the parent locales but that would always include objects and attachments
117    // anyway)
118  2 this.solrIndexer.get().index(new DocumentReference(document.getDocumentReference(), null), true);
119    } else {
120  153 this.solrIndexer.get().index(document.getDocumentReferenceWithLocale(), false);
121    }
122  1163 } else if (event instanceof DocumentDeletedEvent) {
123  44 XWikiDocument document = ((XWikiDocument) source).getOriginalDocument();
124   
125    // We must pass the document reference with the REAL locale because when the indexer is going to delete
126    // the document from the Solr index (later, on a different thread) the real locale won't be accessible
127    // anymore since the XWiki document has been already deleted from the database. The real locale (taken
128    // from the XWiki document) is used to compute the id of the Solr document when the document reference
129    // locale is ROOT (i.e. for default document translations).
130    // Otherwise the document won't be deleted from the Solr index (because the computed id won't match any
131    // document from the Solr index) and we're going to have deleted documents that are still in the Solr
132    // index. These documents will be filtered from the search results but not from the facet counts.
133    // See XWIKI-10003: Cache problem with Solr facet filter results count
134  44 this.solrIndexer.get().delete(
135    new DocumentReference(document.getDocumentReference(), document.getRealLocale()), false);
136  1119 } else if (event instanceof AttachmentUpdatedEvent || event instanceof AttachmentAddedEvent) {
137  40 XWikiDocument document = (XWikiDocument) source;
138  40 String fileName = ((AbstractAttachmentEvent) event).getName();
139  40 XWikiAttachment attachment = document.getAttachment(fileName);
140   
141  40 this.solrIndexer.get().index(attachment.getReference(), false);
142  1079 } else if (event instanceof AttachmentDeletedEvent) {
143  17 XWikiDocument document = ((XWikiDocument) source).getOriginalDocument();
144  17 String fileName = ((AbstractAttachmentEvent) event).getName();
145  17 XWikiAttachment attachment = document.getAttachment(fileName);
146   
147  17 this.solrIndexer.get().delete(attachment.getReference(), false);
148  1062 } else if (event instanceof XObjectUpdatedEvent || event instanceof XObjectAddedEvent) {
149  176 EntityEvent entityEvent = (EntityEvent) event;
150   
151  176 this.solrIndexer.get().index(entityEvent.getReference(), false);
152  886 } else if (event instanceof XObjectDeletedEvent) {
153  52 EntityEvent entityEvent = (EntityEvent) event;
154   
155  52 this.solrIndexer.get().delete(entityEvent.getReference(), false);
156  834 } else if (event instanceof XObjectPropertyUpdatedEvent || event instanceof XObjectPropertyAddedEvent) {
157  513 EntityEvent entityEvent = (EntityEvent) event;
158   
159  513 this.solrIndexer.get().index(entityEvent.getReference(), false);
160  321 } else if (event instanceof XObjectPropertyDeletedEvent) {
161  321 EntityEvent entityEvent = (EntityEvent) event;
162   
163  321 this.solrIndexer.get().delete(entityEvent.getReference(), false);
164  0 } else if (event instanceof WikiDeletedEvent) {
165  0 String wikiName = (String) source;
166  0 WikiReference wikiReference = new WikiReference(wikiName);
167   
168  0 this.solrIndexer.get().delete(wikiReference, false);
169    }
170    } catch (Exception e) {
171  0 this.logger.error("Failed to handle event [{}] with source [{}]", event, source, e);
172    }
173    }
174    }