1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17   * SOFTWARE.
18   */
19  
20  package com.liferay.portal.scheduler.quartz;
21  
22  import com.liferay.portal.kernel.annotation.BeanReference;
23  import com.liferay.portal.kernel.log.Log;
24  import com.liferay.portal.kernel.log.LogFactoryUtil;
25  import com.liferay.portal.kernel.scheduler.SchedulerEngine;
26  import com.liferay.portal.kernel.scheduler.SchedulerException;
27  import com.liferay.portal.kernel.scheduler.messaging.SchedulerRequest;
28  import com.liferay.portal.kernel.uuid.PortalUUIDUtil;
29  import com.liferay.portal.scheduler.job.MessageSenderJob;
30  import com.liferay.portal.service.QuartzLocalService;
31  import com.liferay.portal.util.PropsUtil;
32  import com.liferay.portal.util.PropsValues;
33  
34  import java.text.ParseException;
35  
36  import java.util.ArrayList;
37  import java.util.Date;
38  import java.util.Enumeration;
39  import java.util.List;
40  import java.util.Properties;
41  
42  import org.quartz.CronTrigger;
43  import org.quartz.JobDataMap;
44  import org.quartz.JobDetail;
45  import org.quartz.ObjectAlreadyExistsException;
46  import org.quartz.Scheduler;
47  import org.quartz.impl.StdSchedulerFactory;
48  
49  /**
50   * <a href="QuartzSchedulerEngineImpl.java.html"><b><i>View Source</i></b></a>
51   *
52   * @author Michael C. Han
53   * @author Bruno Farache
54   *
55   */
56  public class QuartzSchedulerEngineImpl implements SchedulerEngine {
57  
58      public void afterPropertiesSet() {
59          try {
60              if (!PropsValues.SCHEDULER_ENABLED) {
61                  return;
62              }
63  
64              Properties props = new Properties();
65  
66              Enumeration<Object> enu = PropsUtil.getProperties().keys();
67  
68              while (enu.hasMoreElements()) {
69                  String key = (String)enu.nextElement();
70  
71                  if (key.startsWith("org.quartz.")) {
72                      props.setProperty(key, PropsUtil.get(key));
73                  }
74              }
75  
76              StdSchedulerFactory schedulerFactory = new StdSchedulerFactory();
77  
78              schedulerFactory.initialize(props);
79  
80              quartzLocalService.checkQuartzTables();
81  
82              _scheduler = schedulerFactory.getScheduler();
83          }
84          catch (Exception e) {
85              _log.error("Unable to initialize engine", e);
86          }
87      }
88  
89      public List<SchedulerRequest> getScheduledJobs(String groupName)
90          throws SchedulerException {
91  
92          if (!PropsValues.SCHEDULER_ENABLED) {
93              return new ArrayList<SchedulerRequest>();
94          }
95  
96          try {
97              String[] jobNames = _scheduler.getJobNames(groupName);
98  
99              List<SchedulerRequest> requests = new ArrayList<SchedulerRequest>();
100 
101             for (String jobName : jobNames) {
102                 JobDetail jobDetail = _scheduler.getJobDetail(
103                     jobName, groupName);
104 
105                 JobDataMap jobDataMap = jobDetail.getJobDataMap();
106 
107                 String description = jobDataMap.getString(DESCRIPTION);
108                 String messageBody = jobDataMap.getString(MESSAGE_BODY);
109 
110                 CronTrigger cronTrigger = (CronTrigger)_scheduler.getTrigger(
111                     jobName, groupName);
112 
113                 SchedulerRequest schedulerRequest = new SchedulerRequest(
114                     null, jobName, groupName, cronTrigger.getCronExpression(),
115                     cronTrigger.getStartTime(), cronTrigger.getEndTime(),
116                     description, null, messageBody);
117 
118                 requests.add(schedulerRequest);
119             }
120 
121             return requests;
122         }
123         catch (org.quartz.SchedulerException se) {
124             throw new SchedulerException("Unable to retrieve job", se);
125         }
126     }
127 
128     public void schedule(
129             String groupName, String cronText, Date startDate, Date endDate,
130             String description, String destination, String messageBody)
131         throws SchedulerException {
132 
133         if (!PropsValues.SCHEDULER_ENABLED) {
134             return;
135         }
136 
137         try {
138             String jobName = PortalUUIDUtil.generate();
139 
140             CronTrigger cronTrigger = new CronTrigger(
141                 jobName, groupName, cronText);
142 
143             if (startDate != null) {
144                 cronTrigger.setStartTime(startDate);
145             }
146 
147             if (endDate != null) {
148                 cronTrigger.setEndTime(endDate);
149             }
150 
151             JobDetail jobDetail = new JobDetail(
152                 jobName, groupName, MessageSenderJob.class);
153 
154             JobDataMap jobDataMap = jobDetail.getJobDataMap();
155 
156             jobDataMap.put(DESCRIPTION, description);
157             jobDataMap.put(DESTINATION, destination);
158             jobDataMap.put(MESSAGE_BODY, messageBody);
159 
160             _scheduler.scheduleJob(jobDetail, cronTrigger);
161         }
162         catch (ObjectAlreadyExistsException oare) {
163             if (_log.isInfoEnabled()) {
164                 _log.info("Message is already scheduled");
165             }
166         }
167         catch (ParseException pe) {
168             throw new SchedulerException("Unable to parse cron text", pe);
169         }
170         catch (org.quartz.SchedulerException se) {
171             throw new SchedulerException("Unable to scheduled job", se);
172         }
173     }
174 
175     public void shutdown() throws SchedulerException {
176         if (!PropsValues.SCHEDULER_ENABLED) {
177             return;
178         }
179 
180         try {
181             _scheduler.shutdown(false);
182         }
183         catch (org.quartz.SchedulerException se) {
184             throw new SchedulerException("Unable to shutdown scheduler", se);
185         }
186     }
187 
188     public void start() throws SchedulerException {
189         if (!PropsValues.SCHEDULER_ENABLED) {
190             return;
191         }
192 
193         try {
194             _scheduler.start();
195         }
196         catch (org.quartz.SchedulerException se) {
197             throw new SchedulerException("Unable to start scheduler", se);
198         }
199     }
200 
201     public void unschedule(String jobName, String groupName)
202         throws SchedulerException {
203 
204         if (!PropsValues.SCHEDULER_ENABLED) {
205             return;
206         }
207 
208         try {
209             _scheduler.unscheduleJob(jobName, groupName);
210         }
211         catch (org.quartz.SchedulerException se) {
212             throw new SchedulerException(
213                 "Unable to unschedule job {jobName=" + jobName +
214                     ", groupName=" + groupName + "}",
215                 se);
216         }
217     }
218 
219     @BeanReference(name = "com.liferay.portal.service.QuartzLocalService.impl")
220     protected QuartzLocalService quartzLocalService;
221 
222     private Log _log = LogFactoryUtil.getLog(QuartzSchedulerEngineImpl.class);
223 
224     private Scheduler _scheduler;
225 
226 }