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

File WatchListScriptService.java

 

Coverage histogram

../../../../img/srcFileCovDistChart7.png
64% of files have more coverage

Code metrics

4
70
17
1
350
172
28
0.4
4.12
17
1.65

Classes

Class Line # Actions
WatchListScriptService 58 70 0% 28 28
0.692307769.2%
 

Contributing tests

No tests hitting this source file were found.

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.script;
21   
22    import java.util.ArrayList;
23    import java.util.Collection;
24    import java.util.Collections;
25    import java.util.List;
26   
27    import javax.inject.Inject;
28    import javax.inject.Named;
29    import javax.inject.Provider;
30    import javax.inject.Singleton;
31   
32    import org.xwiki.component.annotation.Component;
33    import org.xwiki.context.Execution;
34    import org.xwiki.script.service.ScriptService;
35    import org.xwiki.security.authorization.AccessDeniedException;
36    import org.xwiki.security.authorization.ContextualAuthorizationManager;
37    import org.xwiki.security.authorization.Right;
38    import org.xwiki.watchlist.internal.DefaultWatchListStore;
39    import org.xwiki.watchlist.internal.api.WatchList;
40    import org.xwiki.watchlist.internal.api.WatchedElementType;
41   
42    import com.sun.syndication.feed.synd.SyndFeed;
43    import com.xpn.xwiki.XWikiContext;
44    import com.xpn.xwiki.doc.XWikiDocument;
45   
46    /**
47    * Script service that offers WatchList features to XWiki. These feature allow users to build lists of pages and spaces
48    * they want to follow. At a frequency chosen by the user XWiki will send an email notification to him with a list of
49    * the elements that has been modified since the last notification. This is the wrapper accessible from in-document
50    * scripts.
51    *
52    * @version $Id: fcb0bc42245270a977940ef38b862e0559f09359 $
53    * @since 7.0RC1
54    */
55    @Component
56    @Named("watchlist")
57    @Singleton
 
58    public class WatchListScriptService implements ScriptService
59    {
60    private static final String ERROR_KEY = "scriptservice.watchlist.error";
61   
62    @Inject
63    private Provider<XWikiContext> contextProvider;
64   
65    @Inject
66    private WatchList watchlist;
67   
68    @Inject
69    private ContextualAuthorizationManager authorizationManager;
70   
71    @Inject
72    private Execution execution;
73   
74    /**
75    * @param type the type of element, as defined by {@link WatchedElementType}
76    * @return true if the current (context) element of the specified type is watched by the current user, false
77    * otherwise or in case of error.
78    */
 
79  246 toggle public boolean isWatched(WatchedElementType type)
80    {
81  246 return isWatched(null, type);
82    }
83   
84    /**
85    * @param element the element to check. A {@code null} value will fallback on the current element for the specified
86    * type
87    * @param type the type of element, as defined by {@link WatchedElementType}
88    * @return true if the specified element of the specified type is watched by the current user, false otherwise or in
89    * case of error.
90    */
 
91  248 toggle public boolean isWatched(String element, WatchedElementType type)
92    {
93  248 XWikiContext context = contextProvider.get();
94   
95  248 try {
96  248 String safeElement = getSafeElement(element, type);
97   
98  248 return watchlist.getStore().isWatched(safeElement, context.getUser(), type);
99    } catch (Exception e) {
100  6 setError(e);
101  6 return false;
102    }
103    }
104   
105    /**
106    * @param element the element to check
107    * @param type the type of element to check
108    * @return the given element if it is not {@code null} or {@link #getCurrentElementOfType(WatchedElementType)}
109    * instead
110    */
 
111  258 toggle private String getSafeElement(String element, WatchedElementType type)
112    {
113  258 String safeElement = element;
114  258 if (safeElement == null) {
115  250 safeElement = getCurrentElementOfType(type);
116    }
117   
118  258 return safeElement;
119    }
120   
121    /**
122    * @param type the type of element, as defined by {@link WatchedElementType}
123    * @return the current (context) element of the specified type
124    */
 
125  250 toggle private String getCurrentElementOfType(WatchedElementType type)
126    {
127  250 XWikiContext context = contextProvider.get();
128  250 XWikiDocument currentDocument = context.getDoc();
129   
130  250 String element = null;
131  250 switch (type) {
132  83 case DOCUMENT:
133  83 element = currentDocument.getPrefixedFullName();
134  83 break;
135  84 case SPACE:
136  84 element = context.getWikiId() + DefaultWatchListStore.WIKI_SPACE_SEP + currentDocument.getSpace();
137  84 break;
138  83 case WIKI:
139  83 element = context.getWikiId();
140  83 break;
141  0 case USER:
142  0 element = context.getUser();
143  0 break;
144  0 default:
145  0 break;
146    }
147   
148  250 return element;
149    }
150   
151    /**
152    * Add the specified element to the current user's WatchList.
153    *
154    * @param element the element to add. A {@code null} value will fallback on the current element for the specified
155    * type
156    * @param type the type of element, as defined by {@link WatchedElementType}
157    * @return true if the specified element wasn't already in the current user's WatchList, false otherwise or in case
158    * of an error
159    */
 
160  5 toggle public boolean addWatchedElement(String element, WatchedElementType type)
161    {
162  5 return addWatchedElement(null, element, type);
163    }
164   
165    /**
166    * Adds the specified element to the specified user's WatchList.
167    *
168    * @param user the user to add the element to. If specified, the current user's admin rights will be checked and, if
169    * they are not present, the operation will fail. A {@code null} value will fallback on the current user
170    * @param element the element to add. A {@code null} value will fallback on the current element for the specified
171    * type
172    * @param type the type of element, as defined by {@link WatchedElementType}
173    * @return true if the specified element wasn't already in the specified user's WatchList, false otherwise or in
174    * case of an error
175    */
 
176  5 toggle public boolean addWatchedElement(String user, String element, WatchedElementType type)
177    {
178  5 XWikiContext context = contextProvider.get();
179   
180  5 try {
181  5 String safeUser = getSafeUser(user, context);
182  5 String safeElement = getSafeElement(element, type);
183   
184  5 return watchlist.getStore().addWatchedElement(safeUser, safeElement, type);
185    } catch (Exception e) {
186  0 setError(e);
187  0 return false;
188    }
189    }
190   
191    /**
192    * @param user the user to check
193    * @param context the context to use
194    * @return the given user if it is not {@code null} or the current context user instead
195    * @throws AccessDeniedException if a user was specified, but the current user executing this code does not have
196    * admin rights to act upon the given user
197    */
 
198  10 toggle private String getSafeUser(String user, XWikiContext context) throws AccessDeniedException
199    {
200  10 String safeUser = user;
201   
202  10 if (safeUser == null) {
203  10 safeUser = context.getUser();
204    } else {
205  0 authorizationManager.checkAccess(Right.ADMIN);
206    }
207   
208  10 return safeUser;
209    }
210   
211    /**
212    * Removed the specified element from the current user's WatchList.
213    *
214    * @param element the element to remove. A {@code null} value will fallback on the current element for the specified
215    * type
216    * @param type the type of element, as defined by {@link WatchedElementType}
217    * @return true if the element was in the WatchList and has been removed, false otherwise or in case of an error
218    */
 
219  5 toggle public boolean removeWatchedElement(String element, WatchedElementType type)
220    {
221  5 return removeWatchedElement(null, element, type);
222    }
223   
224    /**
225    * Allows Administrators to remove the specified element from the specified user's WatchList.
226    *
227    * @param user the user to remove the element from. If specified, the current user's admin rights will be checked
228    * and, if they are not present, the operation will fail. A {@code null} value will fallback on the
229    * current user
230    * @param element the element to remove. A {@code null} value will fallback on the current element for the specified
231    * type
232    * @param type the type of element, as defined by {@link WatchedElementType}
233    * @return true if the element was in the WatchList and has been removed, false otherwise or in case of an error
234    */
 
235  5 toggle public boolean removeWatchedElement(String user, String element, WatchedElementType type)
236    {
237  5 XWikiContext context = contextProvider.get();
238   
239  5 try {
240  5 String safeUser = getSafeUser(user, context);
241  5 String safeElement = getSafeElement(element, type);
242   
243  5 return watchlist.getStore().removeWatchedElement(safeUser, safeElement, type);
244    } catch (Exception e) {
245  0 setError(e);
246  0 return false;
247    }
248    }
249   
250    /**
251    * @param type the type of element, as defined by {@link WatchedElementType}
252    * @return the elements of the specified type that are watched by the current user. An empty list may also be
253    * returned in case of error.
254    */
 
255  73 toggle public Collection<String> getWatchedElements(WatchedElementType type)
256    {
257  73 XWikiContext context = contextProvider.get();
258   
259  73 try {
260  73 return watchlist.getStore().getWatchedElements(context.getUser(), type);
261    } catch (Exception e) {
262  0 setError(e);
263  0 return Collections.emptyList();
264    }
265    }
266   
267    /**
268    * Get the elements (wikis + spaces + documents + users) watched by the current user.
269    *
270    * @return the list of the elements in the user's WatchList. An empty list may also be returned in case of error.
271    */
 
272  0 toggle public List<String> getWatchedElements()
273    {
274  0 List<String> elements = new ArrayList<String>();
275  0 for (WatchedElementType type : WatchedElementType.values()) {
276  0 elements.addAll(getWatchedElements(type));
277    }
278   
279  0 return elements;
280    }
281   
282    /**
283    * @param entryNumber number of entries to retrieve
284    * @return the watchlist RSS feed for the current user
285    */
 
286  0 toggle public SyndFeed getFeed(int entryNumber)
287    {
288  0 XWikiContext context = contextProvider.get();
289   
290  0 return getFeed(context.getUser(), entryNumber);
291    }
292   
293    /**
294    * @param user the user to retreive the RSS for
295    * @param entryNumber number of entries to retrieve
296    * @return the watchlist RSS feed for the given user
297    */
 
298  0 toggle public SyndFeed getFeed(String user, int entryNumber)
299    {
300  0 try {
301  0 return watchlist.getFeedManager().getFeed(user, entryNumber);
302    } catch (Exception e) {
303  0 setError(e);
304  0 return null;
305    }
306    }
307   
308    /**
309    * Get the list of available notification intervals IDs. This can contain both IDs and document full names, example:
310    * ("realtime", "Scheduler.WatchListHourlyNotifier", etc.).
311    *
312    * @return the list of available notification intervals. An empty list may also be returned in case of error.
313    */
 
314  16 toggle public List<String> getIntervals()
315    {
316  16 return watchlist.getStore().getIntervals();
317    }
318   
319    /**
320    * Get the notification interval preference of a user.
321    *
322    * @param user the user to check
323    * @return the notification interval ID, which can be either an ID or a scheduler job document name
324    */
 
325  16 toggle public String getInterval(String user)
326    {
327  16 return watchlist.getStore().getInterval(user);
328    }
329   
330    /**
331    * Get the error generated while performing the previously called action.
332    *
333    * @return the exception or {@code null} if no exception was thrown
334    */
 
335  0 toggle public Exception getLastError()
336    {
337  0 return (Exception) this.execution.getContext().getProperty(ERROR_KEY);
338    }
339   
340    /**
341    * Store a caught exception in the context, so that it can be later retrieved using {@link #getLastError()}.
342    *
343    * @param e the exception to store, can be {@code null} to clear the previously stored exception
344    * @see #getLastError()
345    */
 
346  6 toggle protected void setError(Exception e)
347    {
348  6 this.execution.getContext().setProperty(ERROR_KEY, e);
349    }
350    }