001package org.apache.turbine.services.schedule;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.util.Date;
023import java.util.concurrent.atomic.AtomicBoolean;
024
025import org.apache.commons.lang3.StringUtils;
026import org.apache.turbine.modules.ScheduledJobLoader;
027import org.apache.turbine.util.TurbineException;
028import org.quartz.Job;
029import org.quartz.JobBuilder;
030import org.quartz.JobDetail;
031import org.quartz.JobExecutionContext;
032import org.quartz.JobExecutionException;
033import org.quartz.Trigger;
034import org.quartz.core.QuartzScheduler;
035
036/**
037 * This implements a Turbine scheduled job model for the {@link QuartzScheduler}.
038 *
039 * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a>
040 */
041public class JobEntryQuartz implements JobEntry, Job
042{
043    private int jobId;
044    private Trigger jobTrigger;
045    private JobDetail jobDetail;
046    private String task;
047    private boolean isnew = true;
048    private AtomicBoolean active = new AtomicBoolean(false);
049
050    /**
051     * the default Quartz schedule group name for Turbine jobs
052     */
053    public static final String DEFAULT_JOB_GROUP_NAME = "TURBINE";
054
055    /**
056     * Default constructor
057     */
058    public JobEntryQuartz()
059    {
060        super();
061    }
062
063    /**
064     * Constructor
065     *
066     * @param jobTrigger Job time table
067     */
068    public JobEntryQuartz(Trigger jobTrigger)
069    {
070        this(jobTrigger, JobBuilder
071                .newJob(JobEntryQuartz.class)
072                .withIdentity(jobTrigger.getJobKey().getName(), DEFAULT_JOB_GROUP_NAME).build());
073    }
074
075    /**
076     * Constructor
077     *
078     * @param jobTrigger Job time table
079     * @param jobDetail job details
080     */
081    public JobEntryQuartz(Trigger jobTrigger, JobDetail jobDetail)
082    {
083        this();
084        setTask(jobTrigger.getJobKey().getName());
085        this.jobTrigger = jobTrigger;
086        this.jobDetail = jobDetail;
087    }
088
089    /**
090     * Return true, if the entry is not yet persisted
091     */
092    @Override
093    public boolean isNew()
094    {
095        boolean _isnew = isnew;
096        isnew = false;
097        return _isnew;
098    }
099
100    /**
101     * Get the value of jobId.
102     *
103     * @return int
104     */
105    @Override
106    public int getJobId()
107    {
108        return jobId;
109    }
110
111    /**
112     * Set the value of jobId.
113     *
114     * @param v new value
115     */
116    @Override
117    public void setJobId(int v)
118    {
119        this.jobId = v;
120    }
121
122    /**
123     * Get the value of task.
124     *
125     * @return String
126     */
127    @Override
128    public String getTask()
129    {
130        return task;
131    }
132
133    /**
134     * Set the value of task.
135     *
136     * @param v new value
137     */
138    @Override
139    public void setTask(String v)
140    {
141        this.task = v;
142    }
143
144    /**
145     * @return the jobTrigger
146     */
147    public Trigger getJobTrigger()
148    {
149        return jobTrigger;
150    }
151
152    /**
153     * @param jobTrigger the jobTrigger to set
154     */
155    public void setJobTrigger(Trigger jobTrigger)
156    {
157        this.jobTrigger = jobTrigger;
158    }
159
160    /**
161     * @return the jobDetail
162     */
163    public JobDetail getJobDetail()
164    {
165        return jobDetail;
166    }
167
168    /**
169     * @see java.lang.Comparable#compareTo(java.lang.Object)
170     */
171    @Override
172    public int compareTo(JobEntry o)
173    {
174        return jobTrigger.compareTo(((JobEntryQuartz)o).getJobTrigger());
175    }
176
177    /**
178     * @see org.apache.turbine.services.schedule.JobEntry#setActive(boolean)
179     */
180    @Override
181    public void setActive(boolean isActive)
182    {
183        this.active.set(isActive);
184    }
185
186    /**
187     * @see org.apache.turbine.services.schedule.JobEntry#isActive()
188     */
189    @Override
190    public boolean isActive()
191    {
192        return active.get();
193    }
194
195    /**
196     * @see org.apache.turbine.services.schedule.JobEntry#getNextRuntime()
197     */
198    @Override
199    public long getNextRuntime()
200    {
201        return getNextRunDate().getTime();
202    }
203
204    /**
205     * @see org.apache.turbine.services.schedule.JobEntry#getNextRunDate()
206     */
207    @Override
208    public Date getNextRunDate()
209    {
210        return jobTrigger.getNextFireTime();
211    }
212
213    /**
214     * @see org.apache.turbine.services.schedule.JobEntry#getNextRunAsString()
215     */
216    @Override
217    public String getNextRunAsString()
218    {
219        return getNextRunDate().toString();
220    }
221
222    /**
223     * @see org.apache.turbine.services.schedule.JobEntry#calcRunTime()
224     */
225    @Override
226    public void calcRunTime() throws TurbineException
227    {
228        // do nothing
229    }
230
231    /**
232     * @see org.quartz.Job#execute(org.quartz.JobExecutionContext)
233     */
234    @Override
235    public void execute(JobExecutionContext context) throws JobExecutionException
236    {
237        if (active.compareAndSet(false, true) == false)
238        {
239            return;
240        }
241
242        try
243        {
244            String task = getTask();
245            if (StringUtils.isEmpty(task))
246            {
247                // This happens when the job is configured in the Quartz configuration file
248                task = context.getJobDetail().getKey().getName();
249            }
250            ScheduledJobLoader.getInstance().exec(this, task);
251        }
252        catch (Exception e)
253        {
254            throw new JobExecutionException("Error executing scheduled job #" +
255                    getJobId() + ", task: " + getTask(), e);
256        }
257        finally
258        {
259            active.compareAndSet(true, false);
260        }
261    }
262}