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

File WatchListJob.java

 

Coverage histogram

../../../../../img/srcFileCovDistChart8.png
54% of files have more coverage

Code metrics

6
34
7
1
203
96
11
0.32
4.86
7
1.57

Classes

Class Line # Actions
WatchListJob 52 34 0% 11 10
0.7872340778.7%
 

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.internal.job;
21   
22    import java.util.Collection;
23    import java.util.Date;
24    import java.util.HashMap;
25    import java.util.List;
26    import java.util.Map;
27   
28    import org.quartz.Job;
29    import org.quartz.JobDataMap;
30    import org.quartz.JobExecutionContext;
31    import org.quartz.JobExecutionException;
32    import org.slf4j.Logger;
33    import org.slf4j.LoggerFactory;
34    import org.xwiki.watchlist.internal.DefaultWatchListNotifier;
35    import org.xwiki.watchlist.internal.WatchListEventMatcher;
36    import org.xwiki.watchlist.internal.api.WatchList;
37    import org.xwiki.watchlist.internal.api.WatchListEvent;
38    import org.xwiki.watchlist.internal.documents.WatchListJobClassDocumentInitializer;
39    import org.xwiki.watchlist.internal.notification.WatchListEventMimeMessageFactory;
40   
41    import com.xpn.xwiki.XWikiException;
42    import com.xpn.xwiki.doc.XWikiDocument;
43    import com.xpn.xwiki.objects.BaseObject;
44    import com.xpn.xwiki.plugin.scheduler.AbstractJob;
45    import com.xpn.xwiki.web.Utils;
46   
47    /**
48    * WatchList abstract implementation of Quartz's Job.
49    *
50    * @version $Id: 2e1ba48a94e19157a871e1b9b114b80026cf5a54 $
51    */
 
52    public class WatchListJob extends AbstractJob implements Job
53    {
54    /**
55    * Wiki page which contains the default watchlist email template.
56    */
57    public static final String DEFAULT_EMAIL_TEMPLATE = "XWiki.WatchListMessage";
58   
59    /**
60    * Logger.
61    */
62    private static final Logger LOGGER = LoggerFactory.getLogger(WatchListJob.class);
63   
64    /**
65    * Scheduler Job XObject.
66    */
67    private BaseObject schedulerJobObject;
68   
69    /**
70    * Watchlist Job XObject.
71    */
72    private BaseObject watchListJobObject;
73   
74    /**
75    * Caller component.
76    */
77    private WatchList watchlist;
78   
79    /**
80    * Sets objects required by the Job : XWiki, XWikiContext, WatchListPlugin, etc.
81    *
82    * @param jobContext Context of the request
83    * @throws Exception when the init of components fails
84    */
 
85  1 toggle public void init(JobExecutionContext jobContext) throws Exception
86    {
87  1 JobDataMap data = jobContext.getJobDetail().getJobDataMap();
88   
89  1 this.watchlist = Utils.getComponent(WatchList.class);
90  1 this.schedulerJobObject = (BaseObject) data.get("xjob");
91  1 this.watchListJobObject =
92    getXWikiContext().getWiki().getDocument(this.schedulerJobObject.getDocumentReference(), getXWikiContext())
93    .getXObject(WatchListJobClassDocumentInitializer.DOCUMENT_REFERENCE);
94    }
95   
96    /**
97    * @return ID of the job
98    */
 
99  0 toggle public String getId()
100    {
101  0 String className = this.getClass().getName();
102  0 return className.substring(className.lastIndexOf(".") + 1);
103    }
104   
105    /**
106    * @return the previous job fire time
107    */
 
108  1 toggle private Date getPreviousFireTime()
109    {
110  1 return this.watchListJobObject.getDateValue(WatchListJobClassDocumentInitializer.LAST_FIRE_TIME_FIELD);
111    }
112   
113    /**
114    * Save the date of the execution in the watchlist job object.
115    *
116    * @throws XWikiException if the job document can't be retrieved or if the save action fails
117    */
 
118  1 toggle private void setPreviousFireTime() throws XWikiException
119    {
120  1 XWikiDocument doc =
121    getXWikiContext().getWiki().getDocument(this.watchListJobObject.getDocumentReference(), getXWikiContext());
122   
123  1 this.watchListJobObject.setDateValue(WatchListJobClassDocumentInitializer.LAST_FIRE_TIME_FIELD, new Date());
124   
125    // Prevent version changes
126  1 doc.setMetaDataDirty(false);
127  1 doc.setContentDirty(false);
128   
129  1 getXWikiContext().getWiki().saveDocument(doc, "Updated last fire time", true, getXWikiContext());
130    }
131   
132    /**
133    * Retrieves all the XWiki.XWikiUsers who have requested to be notified by changes, i.e. who have an Object of class
134    * WATCHLIST_CLASS attached AND who have chosen the current job for their notifications.
135    *
136    * @return a collection of document names pointing to the XWikiUsers wishing to get notified.
137    */
 
138  2 toggle private Collection<String> getSubscribers()
139    {
140  2 return this.watchlist.getStore().getSubscribers(this.schedulerJobObject.getName());
141    }
142   
143    /**
144    * @return true if this job has subscribers, false otherwise
145    */
 
146  1 toggle private boolean hasSubscribers()
147    {
148  1 Collection<String> subscribers = getSubscribers();
149   
150  1 return !subscribers.isEmpty();
151    }
152   
153    /**
154    * Method called from the scheduler.
155    *
156    * @param jobContext Context of the request
157    * @throws JobExecutionException if the job execution fails.
158    */
 
159  1 toggle @Override
160    public void executeJob(JobExecutionContext jobContext) throws JobExecutionException
161    {
162  1 try {
163  1 init(jobContext);
164   
165  1 if (this.watchListJobObject == null) {
166  0 return;
167    }
168   
169  1 Collection<String> subscribers = getSubscribers();
170   
171    // Stop here if nobody is interested.
172  1 if (!hasSubscribers()) {
173  0 return;
174    }
175   
176    // Determine what happened since the last execution for everybody.
177  1 Date previousFireTime = getPreviousFireTime();
178  1 WatchListEventMatcher eventMatcher = Utils.getComponent(WatchListEventMatcher.class);
179  1 List<WatchListEvent> events = eventMatcher.getEventsSince(previousFireTime);
180  1 setPreviousFireTime();
181   
182    // Stop here if nothing happened in the meantime.
183  1 if (events.size() == 0) {
184  0 return;
185    }
186   
187    // Notify all the interested subscribers of the events that occurred.
188    // When processing the events, a subscriber will only be notified of events that interest him.
189  1 Map<String, Object> notificationData = new HashMap<>();
190  1 notificationData.put(DefaultWatchListNotifier.PREVIOUS_FIRE_TIME_VARIABLE, previousFireTime);
191   
192  1 String mailTemplate =
193    this.watchListJobObject.getStringValue(WatchListJobClassDocumentInitializer.TEMPLATE_FIELD);
194  1 notificationData.put(WatchListEventMimeMessageFactory.TEMPLATE_PARAMETER, mailTemplate);
195   
196    // Send the notification for processing.
197  1 this.watchlist.getNotifier().sendNotification(subscribers, events, notificationData);
198    } catch (Exception e) {
199    // We're in a job, we don't throw exceptions
200  0 LOGGER.error("Exception while running job", e);
201    }
202    }
203    }