001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.camel.component.quartz;
018
019 import java.net.URI;
020 import java.text.ParseException;
021 import java.util.Map;
022
023 import org.apache.camel.CamelContext;
024 import org.apache.camel.impl.DefaultComponent;
025 import org.apache.camel.util.IntrospectionSupport;
026 import org.apache.camel.util.ObjectHelper;
027 import org.apache.commons.logging.Log;
028 import org.apache.commons.logging.LogFactory;
029 import org.quartz.CronTrigger;
030 import org.quartz.JobDetail;
031 import org.quartz.Scheduler;
032 import org.quartz.SchedulerException;
033 import org.quartz.SchedulerFactory;
034 import org.quartz.SimpleTrigger;
035 import org.quartz.Trigger;
036 import org.quartz.impl.StdSchedulerFactory;
037
038 /**
039 * A <a href="http://camel.apache.org/quartz.html">Quartz Component</a>
040 * <p/>
041 * For a bried tutorial on setting cron expression see
042 * <a href="http://www.opensymphony.com/quartz/wikidocs/CronTriggers%20Tutorial.html">Quartz cron tutorial</a>.
043 *
044 * @version $Revision:520964 $
045 */
046 public class QuartzComponent extends DefaultComponent {
047 private static final transient Log LOG = LogFactory.getLog(QuartzComponent.class);
048 private SchedulerFactory factory;
049 private Scheduler scheduler;
050 private Map<Trigger, JobDetail> triggers;
051
052 public QuartzComponent() {
053 }
054
055 public QuartzComponent(final CamelContext context) {
056 super(context);
057 }
058
059 @Override
060 protected QuartzEndpoint createEndpoint(final String uri, final String remaining, final Map parameters) throws Exception {
061 QuartzEndpoint answer = new QuartzEndpoint(uri, this, getScheduler());
062
063 // lets split the remaining into a group/name
064 URI u = new URI(uri);
065 String path = ObjectHelper.after(u.getPath(), "/");
066 String host = u.getHost();
067 String cron = getAndRemoveParameter(parameters, "cron", String.class);
068
069 // group can be optional, if so set it to Camel
070 String name;
071 String group;
072 if (ObjectHelper.isNotEmpty(path) && ObjectHelper.isNotEmpty(host)) {
073 group = host;
074 name = path;
075 } else {
076 group = "Camel";
077 name = host;
078 }
079
080 // create the trigger either cron or simple
081 Trigger trigger;
082 if (ObjectHelper.isNotEmpty(cron)) {
083 trigger = createCronTrigger(cron);
084 } else {
085 trigger = new SimpleTrigger();
086 }
087 answer.setTrigger(trigger);
088
089 trigger.setName(name);
090 trigger.setGroup(group);
091
092 Map triggerParameters = IntrospectionSupport.extractProperties(parameters, "trigger.");
093 Map jobParameters = IntrospectionSupport.extractProperties(parameters, "job.");
094
095 setProperties(trigger, triggerParameters);
096 setProperties(answer.getJobDetail(), jobParameters);
097
098 return answer;
099 }
100
101 protected CronTrigger createCronTrigger(String path) throws ParseException {
102 // replace + back to space so its a cron expression
103 path = path.replaceAll("\\+", " ");
104 CronTrigger cron = new CronTrigger();
105 cron.setCronExpression(path);
106 return cron;
107 }
108
109 @Override
110 protected void doStart() throws Exception {
111 super.doStart();
112 if (scheduler == null) {
113 scheduler = getScheduler();
114 }
115 if (LOG.isDebugEnabled()) {
116 LOG.debug("Starting Quartz scheduler: " + scheduler.getSchedulerName());
117 }
118 scheduler.start();
119 }
120
121 @Override
122 protected void doStop() throws Exception {
123 if (scheduler != null) {
124 if (LOG.isDebugEnabled()) {
125 LOG.debug("Shutting down Quartz scheduler: " + scheduler.getSchedulerName());
126 }
127 scheduler.shutdown();
128 }
129 super.doStop();
130 }
131
132 // Properties
133 // -------------------------------------------------------------------------
134 public SchedulerFactory getFactory() {
135 if (factory == null) {
136 factory = createSchedulerFactory();
137 }
138 return factory;
139 }
140
141 public void setFactory(final SchedulerFactory factory) {
142 this.factory = factory;
143 }
144
145 public Scheduler getScheduler() throws SchedulerException {
146 if (scheduler == null) {
147 scheduler = createScheduler();
148 }
149 return scheduler;
150 }
151
152 public void setScheduler(final Scheduler scheduler) {
153 this.scheduler = scheduler;
154 }
155
156 public Map<Trigger, JobDetail> getTriggers() {
157 return triggers;
158 }
159
160 public void setTriggers(final Map<Trigger, JobDetail> triggers) {
161 this.triggers = triggers;
162 }
163
164 // Implementation methods
165 // -------------------------------------------------------------------------
166 protected SchedulerFactory createSchedulerFactory() {
167 return new StdSchedulerFactory();
168 }
169
170 protected Scheduler createScheduler() throws SchedulerException {
171 Scheduler scheduler = getFactory().getScheduler();
172 scheduler.getContext().put(QuartzConstants.QUARTZ_CAMEL_CONTEXT, getCamelContext());
173 return scheduler;
174 }
175 }