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              try {
81                  _scheduler = schedulerFactory.getScheduler();
82              }
83              catch (Exception e1) {
84                  quartzLocalService.checkQuartzTables();
85  
86                  _scheduler = schedulerFactory.getScheduler();
87              }
88          }
89          catch (Exception e2) {
90              _log.error("Unable to initialize engine", e2);
91          }
92      }
93  
94      public List<SchedulerRequest> getScheduledJobs(String groupName)
95          throws SchedulerException {
96  
97          if (!PropsValues.SCHEDULER_ENABLED) {
98              return new ArrayList<SchedulerRequest>();
99          }
100 
101         try {
102             String[] jobNames = _scheduler.getJobNames(groupName);
103 
104             List<SchedulerRequest> requests = new ArrayList<SchedulerRequest>();
105 
106             for (String jobName : jobNames) {
107                 JobDetail jobDetail = _scheduler.getJobDetail(
108                     jobName, groupName);
109 
110                 JobDataMap jobDataMap = jobDetail.getJobDataMap();
111 
112                 String description = jobDataMap.getString(DESCRIPTION);
113                 String messageBody = jobDataMap.getString(MESSAGE_BODY);
114 
115                 CronTrigger cronTrigger = (CronTrigger)_scheduler.getTrigger(
116                     jobName, groupName);
117 
118                 SchedulerRequest schedulerRequest = new SchedulerRequest(
119                     null, jobName, groupName, cronTrigger.getCronExpression(),
120                     cronTrigger.getStartTime(), cronTrigger.getEndTime(),
121                     description, null, messageBody);
122 
123                 requests.add(schedulerRequest);
124             }
125 
126             return requests;
127         }
128         catch (org.quartz.SchedulerException se) {
129             throw new SchedulerException("Unable to retrieve job", se);
130         }
131     }
132 
133     public void schedule(
134             String groupName, String cronText, Date startDate, Date endDate,
135             String description, String destination, String messageBody)
136         throws SchedulerException {
137 
138         if (!PropsValues.SCHEDULER_ENABLED) {
139             return;
140         }
141 
142         try {
143             String jobName = PortalUUIDUtil.generate();
144 
145             CronTrigger cronTrigger = new CronTrigger(
146                 jobName, groupName, cronText);
147 
148             if (startDate != null) {
149                 cronTrigger.setStartTime(startDate);
150             }
151 
152             if (endDate != null) {
153                 cronTrigger.setEndTime(endDate);
154             }
155 
156             JobDetail jobDetail = new JobDetail(
157                 jobName, groupName, MessageSenderJob.class);
158 
159             JobDataMap jobDataMap = jobDetail.getJobDataMap();
160 
161             jobDataMap.put(DESCRIPTION, description);
162             jobDataMap.put(DESTINATION, destination);
163             jobDataMap.put(MESSAGE_BODY, messageBody);
164 
165             _scheduler.scheduleJob(jobDetail, cronTrigger);
166         }
167         catch (ObjectAlreadyExistsException oare) {
168             if (_log.isInfoEnabled()) {
169                 _log.info("Message is already scheduled");
170             }
171         }
172         catch (ParseException pe) {
173             throw new SchedulerException("Unable to parse cron text", pe);
174         }
175         catch (org.quartz.SchedulerException se) {
176             throw new SchedulerException("Unable to scheduled job", se);
177         }
178     }
179 
180     public void shutdown() throws SchedulerException {
181         if (!PropsValues.SCHEDULER_ENABLED) {
182             return;
183         }
184 
185         try {
186             _scheduler.shutdown(false);
187         }
188         catch (org.quartz.SchedulerException se) {
189             throw new SchedulerException("Unable to shutdown scheduler", se);
190         }
191     }
192 
193     public void start() throws SchedulerException {
194         if (!PropsValues.SCHEDULER_ENABLED) {
195             return;
196         }
197 
198         try {
199             _scheduler.start();
200         }
201         catch (org.quartz.SchedulerException se) {
202             throw new SchedulerException("Unable to start scheduler", se);
203         }
204     }
205 
206     public void unschedule(String jobName, String groupName)
207         throws SchedulerException {
208 
209         if (!PropsValues.SCHEDULER_ENABLED) {
210             return;
211         }
212 
213         try {
214             _scheduler.unscheduleJob(jobName, groupName);
215         }
216         catch (org.quartz.SchedulerException se) {
217             throw new SchedulerException(
218                 "Unable to unschedule job {jobName=" + jobName +
219                     ", groupName=" + groupName + "}",
220                 se);
221         }
222     }
223 
224     @BeanReference(name = "com.liferay.portal.service.QuartzLocalService.impl")
225     protected QuartzLocalService quartzLocalService;
226 
227     private Log _log = LogFactoryUtil.getLog(QuartzSchedulerEngineImpl.class);
228 
229     private Scheduler _scheduler;
230 
231 }