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

File AutomaticWatchModeListener.java

 

Coverage histogram

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

Code metrics

6
30
5
1
176
96
13
0.43
6
5
2.6

Classes

Class Line # Actions
AutomaticWatchModeListener 57 30 0% 13 4
0.90243990.2%
 

Contributing tests

This file is covered by 3 tests. .

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.watchlist.internal;
21   
22    import java.util.ArrayList;
23    import java.util.List;
24   
25    import javax.inject.Inject;
26    import javax.inject.Named;
27    import javax.inject.Singleton;
28   
29    import org.slf4j.Logger;
30    import org.xwiki.bridge.event.DocumentCreatedEvent;
31    import org.xwiki.bridge.event.DocumentUpdatedEvent;
32    import org.xwiki.bridge.event.WikiCreatingEvent;
33    import org.xwiki.component.annotation.Component;
34    import org.xwiki.job.event.JobEvent;
35    import org.xwiki.model.reference.DocumentReference;
36    import org.xwiki.observation.AbstractEventListener;
37    import org.xwiki.observation.ObservationContext;
38    import org.xwiki.observation.event.BeginEvent;
39    import org.xwiki.observation.event.Event;
40    import org.xwiki.watchlist.internal.api.AutomaticWatchMode;
41    import org.xwiki.watchlist.internal.api.WatchListStore;
42    import org.xwiki.watchlist.internal.api.WatchedElementType;
43   
44    import com.xpn.xwiki.XWikiContext;
45    import com.xpn.xwiki.XWikiException;
46    import com.xpn.xwiki.doc.XWikiDocument;
47    import com.xpn.xwiki.internal.event.XARImportingEvent;
48   
49    /**
50    * Automatically watch modified documents.
51    *
52    * @version $Id: c369ffadfb6c7ed918d5c6388d3c88015be9aece $
53    */
54    @Component
55    @Named(AutomaticWatchModeListener.LISTENER_NAME)
56    @Singleton
 
57    public class AutomaticWatchModeListener extends AbstractEventListener
58    {
59    /**
60    * The name of the listener.
61    */
62    public static final String LISTENER_NAME = "AutomaticWatchModeListener";
63   
64    /**
65    * The skipped events group matcher.
66    */
67    public static final BeginEvent SKIPPED_EVENTS = new BeginEvent()
68    {
 
69  138 toggle @Override
70    public boolean matches(Object otherEvent)
71    {
72    // 1. Skip bulk user actions as do not reflect expressed interest in the particular pages.
73   
74    // 2. Skip events coming from background jobs, since they are not attributed and are not relevant to a
75    // particular user's behavior. E.g.: XWiki initialization job (mandatory document initializers, plugin
76    // initializers, etc.)
77   
78  138 return otherEvent instanceof WikiCreatingEvent || otherEvent instanceof XARImportingEvent
79    || otherEvent instanceof JobEvent;
80    }
81    };
82   
83    /**
84    * The events to match.
85    */
86    private static final List<Event> LISTENER_EVENTS = new ArrayList<Event>()
87    {
 
88  2 toggle {
89  2 add(new DocumentCreatedEvent());
90  2 add(new DocumentUpdatedEvent());
91    }
92    };
93   
94    /**
95    * Logging helper object.
96    */
97    @Inject
98    private Logger logger;
99   
100    /**
101    * The watchlist storage manager.
102    */
103    @Inject
104    private WatchListStore store;
105   
106    /**
107    * Used to detect if certain events are not independent, i.e. executed in the context of other events, case in which
108    * they should be skipped.
109    */
110    @Inject
111    private ObservationContext observationContext;
112   
113    /**
114    * Default constructor.
115    */
 
116  4 toggle public AutomaticWatchModeListener()
117    {
118  4 super(LISTENER_NAME, LISTENER_EVENTS);
119    }
120   
 
121  74 toggle @Override
122    public void onEvent(Event event, Object source, Object data)
123    {
124  74 XWikiDocument currentDoc = (XWikiDocument) source;
125  74 XWikiContext context = (XWikiContext) data;
126   
127    // Does not auto-watch updated or created documents when they are in the context of other events.
128  74 if (!observationContext.isIn(SKIPPED_EVENTS)) {
129  62 documentModifiedHandler(event, currentDoc, context);
130    }
131    }
132   
133    /**
134    * Automatically watch modified document depending on the configuration.
135    *
136    * @param event the observation event we check for a deleted document event
137    * @param currentDoc document version after event occurred
138    * @param context the XWiki context
139    */
 
140  62 toggle private void documentModifiedHandler(Event event, XWikiDocument currentDoc, XWikiContext context)
141    {
142  62 String user = currentDoc.getContentAuthor();
143  62 DocumentReference userReference = currentDoc.getContentAuthorReference();
144   
145    // Avoid handling guests or the superadmin user.
146  62 if (userReference == null || !context.getWiki().exists(userReference, context)) {
147  13 return;
148    }
149   
150    // Determine if the current event should be registered, based on the user's prefereces.
151  49 boolean register = false;
152   
153  49 AutomaticWatchMode mode = this.store.getAutomaticWatchMode(user);
154  49 switch (mode) {
155  1 case ALL:
156  1 register = true;
157  1 break;
158  36 case MAJOR:
159  36 register = !currentDoc.isMinorEdit();
160  36 break;
161  0 case NEW:
162  0 register = event instanceof DocumentCreatedEvent;
163  0 break;
164  12 default:
165  12 break;
166    }
167   
168  49 if (register) {
169  12 try {
170  12 this.store.addWatchedElement(user, currentDoc.getPrefixedFullName(), WatchedElementType.DOCUMENT);
171    } catch (XWikiException e) {
172  0 logger.warn("Failed to watch document [{}] for user [{}]", currentDoc.getPrefixedFullName(), user, e);
173    }
174    }
175    }
176    }