1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package com.xpn.xwiki.plugin.scheduler

File SchedulerPluginApi.java

 

Coverage histogram

../../../../../img/srcFileCovDistChart6.png
69% of files have more coverage

Code metrics

0
81
20
1
360
194
37
0.46
4.05
20
1.85

Classes

Class Line # Actions
SchedulerPluginApi 47 81 0% 37 45
0.5544554655.4%
 

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 com.xpn.xwiki.plugin.scheduler;
21   
22    import java.util.Date;
23    import java.util.List;
24   
25    import org.quartz.SchedulerException;
26    import org.slf4j.Logger;
27    import org.slf4j.LoggerFactory;
28   
29    import com.xpn.xwiki.XWikiContext;
30    import com.xpn.xwiki.XWikiException;
31    import com.xpn.xwiki.api.Document;
32    import com.xpn.xwiki.api.Object;
33    import com.xpn.xwiki.doc.XWikiDocument;
34    import com.xpn.xwiki.objects.BaseObject;
35    import com.xpn.xwiki.plugin.PluginApi;
36   
37    /**
38    * A Scheduler plugin to plan execution of Jobs from XWiki with cron expressions. The plugin uses Quartz's scheduling
39    * library. <p> Jobs are represented by {@link com.xpn.xwiki.api.Object} XObjects, instances of the
40    * {@link SchedulerPlugin#XWIKI_JOB_CLASS} XClass. These XObjects do store a job name, the implementation class name of
41    * the job to be executed, the cron expression to precise when the job should be fired, and possibly a groovy script
42    * with the job's program. <p> The plugin offers a {@link GroovyJob} Groovy Job wrapper to execute groovy scripts
43    * (typically for use inside the Wiki), but can also be used with any Java class implementing {@link org.quartz.Job}
44    *
45    * @version $Id: e5c7325b85806541bfb2202a280f603a0de6f2b8 $
46    */
 
47    public class SchedulerPluginApi extends PluginApi<SchedulerPlugin>
48    {
49    /**
50    * Log object to log messages in this class.
51    */
52    private static final Logger LOGGER = LoggerFactory.getLogger(SchedulerPluginApi.class);
53   
 
54  25 toggle public SchedulerPluginApi(SchedulerPlugin plugin, XWikiContext context)
55    {
56  25 super(plugin, context);
57    }
58   
59    /**
60    * Return the trigger state of the given {@link com.xpn.xwiki.plugin.scheduler.SchedulerPlugin#XWIKI_JOB_CLASS}
61    * XObject job. Possible values are : None (the trigger does not exists yet, or has been deleted), Normal, Blocked,
62    * Complete, Error and Paused
63    *
64    * @param object the XObject job to give the state of
65    * @return a String representing this state
66    */
 
67  0 toggle public String getStatus(Object object)
68    {
69  0 try {
70  0 return getJobStatus(object.getXWikiObject()).getValue();
71    } catch (Exception e) {
72  0 this.context.put("error", e.getMessage());
73  0 return null;
74    }
75    }
76   
77    /**
78    * Return the trigger state as a ${@link JobState}, that holds both the integer trigger's inner value of the state
79    * and a String as a human readable representation of that state
80    */
 
81  0 toggle public JobState getJobStatus(BaseObject object) throws SchedulerException
82    {
83  0 return getProtectedPlugin().getJobStatus(object, this.context);
84    }
85   
 
86  26 toggle public JobState getJobStatus(Object object) throws SchedulerException, SchedulerPluginException
87    {
88  26 return getProtectedPlugin().getJobStatus(retrieveBaseObject(object), this.context);
89    }
90   
91    /**
92    * This function allow to retrieve a com.xpn.xwiki.objects.BaseObject from a com.xpn.xwiki.api.Object without that
93    * the current user needs programming rights (as in com.xpn.xwiki.api.Object#getXWikiObject(). The function is used
94    * internally by this api class and allows wiki users to call methods from the scheduler without having programming
95    * right. The programming right is only needed at script execution time.
96    *
97    * @return object the unwrapped version of the passed api object
98    */
 
99  48 toggle private BaseObject retrieveBaseObject(Object object) throws SchedulerPluginException
100    {
101  48 String docName = object.getName();
102  48 int objNb = object.getNumber();
103  48 try {
104   
105  48 XWikiDocument jobHolder = this.context.getWiki().getDocument(docName, this.context);
106  48 BaseObject jobObject = jobHolder.getXObject(SchedulerPlugin.XWIKI_JOB_CLASSREFERENCE, objNb);
107  48 return jobObject;
108    } catch (XWikiException e) {
109  0 throw new SchedulerPluginException(SchedulerPluginException.ERROR_SCHEDULERPLUGIN_UNABLE_TO_RETRIEVE_JOB,
110    "Job in document [" + docName + "] with object number [" + objNb + "] could not be retrieved.", e);
111    }
112    }
113   
114    /**
115    * Schedule the given XObject to be executed according to its parameters. Errors are returned in the context map.
116    * Scheduling can be called for example: <code> #if($xwiki.scheduler.scheduleJob($job)!=true)
117    * #error($xcontext.get("error") #else #info("Job scheduled") #end </code>
118    * Where $job is an XObject, instance of the {@link SchedulerPlugin#XWIKI_JOB_CLASS} XClass
119    *
120    * @param object the XObject to be scheduled, an instance of the XClass XWiki.SchedulerJobClass
121    * @return true on success, false on failure
122    */
 
123  1 toggle public boolean scheduleJob(Object object)
124    {
125  1 try {
126  1 return scheduleJob(retrieveBaseObject(object));
127    } catch (Exception e) {
128    // we don't need to push the exception message in the context here
129    // as it should already have been pushed by the throwing exception
130  0 return false;
131    }
132    }
133   
 
134  1 toggle public boolean scheduleJob(BaseObject object)
135    {
136  1 try {
137  1 getProtectedPlugin().scheduleJob(object, this.context);
138  1 return true;
139    } catch (Exception e) {
140  0 this.context.put("error", e.getMessage());
141  0 return false;
142    }
143    }
144   
145    /**
146    * Schedule all {@link com.xpn.xwiki.plugin.scheduler.SchedulerPlugin#XWIKI_JOB_CLASS} XObjects stored inside the
147    * given Wiki document, according to each XObject own parameters.
148    *
149    * @param document the document holding the XObjects Jobs to be scheduled
150    * @return true on success, false on failure.
151    */
 
152  0 toggle public boolean scheduleJobs(Document document)
153    {
154  0 boolean result = true;
155  0 try {
156  0 XWikiDocument doc = this.context.getWiki().getDocument(document.getFullName(), this.context);
157  0 List<BaseObject> objects = doc.getXObjects(SchedulerPlugin.XWIKI_JOB_CLASSREFERENCE);
158  0 for (BaseObject object : objects) {
159  0 result &= scheduleJob(object);
160    }
161    } catch (Exception e) {
162  0 this.context.put("error", e.getMessage());
163  0 return false;
164    }
165  0 return result;
166    }
167   
168    /**
169    * Pause the given XObject job by pausing all of its current triggers. Can be called the same way as
170    * {@link #scheduleJob(Object)}
171    *
172    * @param object the wrapped XObject Job to be paused
173    * @return true on success, false on failure.
174    */
 
175  1 toggle public boolean pauseJob(Object object)
176    {
177  1 try {
178  1 return pauseJob(retrieveBaseObject(object));
179    } catch (Exception e) {
180    // we don't need to push the exception message in the context here
181    // as it should already have been pushed by the throwing exception
182  0 return false;
183    }
184    }
185   
 
186  1 toggle public boolean pauseJob(BaseObject object)
187    {
188  1 try {
189  1 getProtectedPlugin().pauseJob(object, this.context);
190  1 LOGGER.debug("Pause Job: [{}]", object.getStringValue("jobName"));
191  1 return true;
192    } catch (XWikiException e) {
193  0 this.context.put("error", e.getMessage());
194  0 return false;
195    }
196    }
197   
198    /**
199    * Resume a XObject job that is in a {@link JobState#STATE_PAUSED} state. Can be called the same way as
200    * {@link #scheduleJob(Object)}
201    *
202    * @param object the wrapped XObject Job to be paused
203    * @return true on success, false on failure.
204    */
 
205  1 toggle public boolean resumeJob(Object object)
206    {
207  1 try {
208  1 return resumeJob(retrieveBaseObject(object));
209    } catch (Exception e) {
210    // we don't need to push the exception message in the context here
211    // as it should already have been pushed by the throwing exception
212  0 return false;
213    }
214    }
215   
 
216  1 toggle public boolean resumeJob(BaseObject object)
217    {
218  1 try {
219  1 getProtectedPlugin().resumeJob(object, this.context);
220  1 LOGGER.debug("Resume Job: [{}]", object.getStringValue("jobName"));
221  1 return true;
222    } catch (XWikiException e) {
223  0 this.context.put("error", e.getMessage());
224  0 return false;
225    }
226    }
227   
228    /**
229    * Unschedule a XObject job by deleting it from the jobs table. Can be called the same way as
230    * {@link #scheduleJob(Object)}
231    *
232    * @param object the wrapped XObject Job to be paused
233    * @return true on success, false on failure.
234    */
 
235  1 toggle public boolean unscheduleJob(Object object)
236    {
237  1 try {
238  1 return unscheduleJob(retrieveBaseObject(object));
239    } catch (Exception e) {
240    // we don't need to push the exception message in the context here
241    // as it should already have been pushed by the throwing exception
242  0 return false;
243    }
244    }
245   
 
246  1 toggle public boolean unscheduleJob(BaseObject object)
247    {
248  1 try {
249  1 getProtectedPlugin().unscheduleJob(object, this.context);
250  1 LOGGER.debug("Delete Job: [{}]", object.getStringValue("jobName"));
251  1 return true;
252    } catch (XWikiException e) {
253  0 this.context.put("error", e.getMessage());
254  0 return false;
255    }
256    }
257   
258    /**
259    * Trigger a XObject job (execute it now).
260    *
261    * @param object the wrapped XObject Job to be triggered
262    * @return true on success, false on failure.
263    */
 
264  2 toggle public boolean triggerJob(Object object)
265    {
266  2 try {
267  2 return triggerJob(retrieveBaseObject(object));
268    } catch (Exception e) {
269    // we don't need to push the exception message in the context here
270    // as it should already have been pushed by the throwing exception
271  0 return false;
272    }
273    }
274   
275    /**
276    * Trigger a BaseObject job (execute it now).
277    *
278    * @param object the BaseObject Job to be triggered
279    * @return true on success, false on failure.
280    */
 
281  2 toggle public boolean triggerJob(BaseObject object)
282    {
283  2 try {
284  2 getProtectedPlugin().triggerJob(object, this.context);
285  2 LOGGER.debug("Trigger Job: [{}]", object.getStringValue("jobName"));
286  2 return true;
287    } catch (XWikiException e) {
288  0 this.context.put("error", e.getMessage());
289  0 return false;
290    }
291    }
292   
293    /**
294    * Give, for a XObject job in a {@link JobState#STATE_NORMAL} state, the previous date at which the job has been
295    * executed, the fire time is not computed from the CRON expression, this method will return null if the .
296    *
297    * @param object the wrapped XObject for which to give the fire time
298    * @return the date the job has been executed
299    */
 
300  0 toggle public Date getPreviousFireTime(Object object)
301    {
302  0 try {
303  0 return getPreviousFireTime(retrieveBaseObject(object));
304    } catch (Exception e) {
305    // we don't need to push the exception message in the context here
306    // as it should already have been pushed by the throwing exception
307  0 return null;
308    }
309    }
310   
311    /**
312    * Give, for a BaseObject job in a {@link JobState#STATE_NORMAL} state, the previous date at which the job has been
313    * executed. Note that this method does not compute a date from the CRON expression, it only returns a date value
314    * which is set each time the job is executed. If the job has never been fired this method will return null.
315    *
316    * @param object the BaseObject for which to give the fire time
317    * @return the date the job has been executed
318    */
 
319  0 toggle public Date getPreviousFireTime(BaseObject object)
320    {
321  0 try {
322  0 return getProtectedPlugin().getPreviousFireTime(object, this.context);
323    } catch (SchedulerPluginException e) {
324  0 this.context.put("error", e.getMessage());
325  0 return null;
326    }
327    }
328   
329    /**
330    * Give, for a XObject job in a {@link JobState#STATE_NORMAL} state, the next date at which the job will be
331    * executed, according to its cron expression. Errors are returned in the context map. Can be called for example:
332    * <code> #set($firetime = $xwiki.scheduler.getNextFireTime($job))
333    * #if (!$firetime || $firetime=="") #error($xcontext.get("error") #else #info("Fire time :
334    * $firetime") #end </code>
335    * Where $job is an XObject, instance of the {@link SchedulerPlugin#XWIKI_JOB_CLASS} XClass
336    *
337    * @param object the wrapped XObject for which to give the fire date
338    * @return the date the job will be executed
339    */
 
340  16 toggle public Date getNextFireTime(Object object)
341    {
342  16 try {
343  16 return getNextFireTime(retrieveBaseObject(object));
344    } catch (Exception e) {
345    // we don't need to push the exception message in the context here
346    // as it should already have been pushed by the throwing exception
347  0 return null;
348    }
349    }
350   
 
351  16 toggle public Date getNextFireTime(BaseObject object)
352    {
353  16 try {
354  16 return getProtectedPlugin().getNextFireTime(object, this.context);
355    } catch (SchedulerPluginException e) {
356  0 this.context.put("error", e.getMessage());
357  0 return null;
358    }
359    }
360    }