View Javadoc

1   /*
2    * $Id: QuartzMessageDispatcher.java 19191 2010-08-25 21:05:23Z tcarlson $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.transport.quartz;
12  
13  import org.mule.DefaultMuleMessage;
14  import org.mule.api.MuleEvent;
15  import org.mule.api.MuleMessage;
16  import org.mule.api.endpoint.OutboundEndpoint;
17  import org.mule.config.i18n.CoreMessages;
18  import org.mule.transport.AbstractMessageDispatcher;
19  import org.mule.transport.NullPayload;
20  import org.mule.transport.quartz.config.JobConfig;
21  import org.mule.transport.quartz.i18n.QuartzMessages;
22  import org.mule.transport.quartz.jobs.CustomJob;
23  import org.mule.transport.quartz.jobs.CustomJobConfig;
24  import org.mule.transport.quartz.jobs.CustomJobFromMessageConfig;
25  import org.mule.transport.quartz.jobs.ScheduledDispatchJobConfig;
26  
27  import java.util.Date;
28  
29  import org.quartz.CronTrigger;
30  import org.quartz.Job;
31  import org.quartz.JobDataMap;
32  import org.quartz.JobDetail;
33  import org.quartz.Scheduler;
34  import org.quartz.SimpleTrigger;
35  import org.quartz.Trigger;
36  
37  /**
38   * Can schedule a Job with the Quartz scheduler. The event must contain the Job to
39   * invoke or have it set as a property. Time trigger properties can be set on the
40   * event to control how and when the event is fired.
41   */
42  public class QuartzMessageDispatcher extends AbstractMessageDispatcher
43  {
44  
45      public QuartzMessageDispatcher(OutboundEndpoint endpoint)
46      {
47          super(endpoint);
48      }
49  
50      @Override
51      protected void doDispose()
52      {
53          // template method
54      }
55  
56      @Override
57      protected void doDispatch(MuleEvent event) throws Exception
58      {
59          JobConfig jobConfig = (JobConfig) endpoint.getProperty(QuartzConnector.PROPERTY_JOB_CONFIG);
60          if (jobConfig == null)
61          {
62              throw new IllegalArgumentException(CoreMessages.objectIsNull(QuartzConnector.PROPERTY_JOB_CONFIG).getMessage());
63          }
64  
65          JobDetail jobDetail = new JobDetail();
66          // make the job name unique per endpoint (MULE-753)
67          jobDetail.setName(event.getEndpoint().getEndpointURI().getAddress() + "-" + event.getId());
68  
69          JobDataMap jobDataMap = new JobDataMap();
70          MuleMessage msg = event.getMessage();
71          // populate from invocation and outbound scopes only
72          for (String key : msg.getInvocationPropertyNames())
73          {
74              jobDataMap.put(key, msg.getInvocationProperty(key));
75          }
76          for (String key : msg.getOutboundPropertyNames())
77          {
78              jobDataMap.put(key, msg.getOutboundProperty(key));
79          }
80  
81          if (jobConfig instanceof ScheduledDispatchJobConfig) 
82          {
83              ScheduledDispatchJobConfig scheduledDispatchJobConfig = (ScheduledDispatchJobConfig) jobConfig;
84              String endpointRef = event.getMuleContext().getExpressionManager().parse(
85                  scheduledDispatchJobConfig.getEndpointRef(), event.getMessage());
86  
87              jobDataMap.put("endpointRef", endpointRef);
88          }
89          jobDetail.setJobDataMap(jobDataMap);
90  
91          Job job = null;
92          // work out what we're actually calling
93          Object payload = event.getMessage().getPayload();
94  
95          if(jobConfig instanceof CustomJobConfig)
96          {
97              job = ((CustomJobConfig) jobConfig).getJob();
98          }
99          else if(jobConfig instanceof CustomJobFromMessageConfig)
100         {
101             job = ((CustomJobFromMessageConfig) jobConfig).getJob(msg);
102             //rewrite the jobConfig to the real Jobconfig on the message
103             jobConfig = ((CustomJobFromMessageConfig) jobConfig).getJobConfig(msg);
104         }
105 
106         jobDataMap.put(QuartzConnector.PROPERTY_JOB_CONFIG, jobConfig);        
107         jobDetail.setJobClass(jobConfig.getJobClass());
108         // If there has been a job created or found then we default to a customJob configuration
109         if (job != null)
110         {
111             jobDataMap.put(QuartzConnector.PROPERTY_JOB_OBJECT, job);
112             jobDetail.setJobClass(CustomJob.class);
113         }
114        
115         // The payload will be ignored by the CustomJob - don't know why we need it here
116         //RM: The custom job may want the message and the Job type may not be delegating job
117         jobDataMap.put(QuartzConnector.PROPERTY_PAYLOAD, payload);
118 
119         Trigger trigger;
120         String cronExpression = jobDataMap.getString(QuartzConnector.PROPERTY_CRON_EXPRESSION);
121         String repeatInterval = jobDataMap.getString(QuartzConnector.PROPERTY_REPEAT_INTERVAL);
122         String repeatCount = jobDataMap.getString(QuartzConnector.PROPERTY_REPEAT_COUNT);
123         String startDelay = jobDataMap.getString(QuartzConnector.PROPERTY_START_DELAY);
124         String groupName = jobConfig.getGroupName();
125         String jobGroupName = jobConfig.getJobGroupName();
126 
127         if (groupName == null)
128         {
129             groupName = QuartzConnector.DEFAULT_GROUP_NAME;
130         }
131         if (jobGroupName == null)
132         {
133             jobGroupName = groupName;
134         }
135 
136         jobDetail.setGroup(groupName);
137 
138         if (cronExpression != null)
139         {
140             CronTrigger ctrigger = new CronTrigger();
141             ctrigger.setCronExpression(cronExpression);
142             trigger = ctrigger;
143         }
144         else if (repeatInterval != null)
145         {
146             SimpleTrigger strigger = new SimpleTrigger();
147             strigger.setRepeatInterval(Long.parseLong(repeatInterval));
148             if (repeatCount != null)
149             {
150                 strigger.setRepeatCount(Integer.parseInt(repeatCount));
151             }
152             else
153             {
154                 strigger.setRepeatCount(-1);
155             }
156             trigger = strigger;
157         }
158         else
159         {
160             throw new IllegalArgumentException(
161                 QuartzMessages.cronExpressionOrIntervalMustBeSet().getMessage());
162         }
163         trigger.setName(event.getEndpoint().getEndpointURI().toString() + "-" + event.getId());
164         trigger.setGroup(groupName);
165         trigger.setJobName(jobDetail.getName());
166         trigger.setJobGroup(jobGroupName);
167 
168         Scheduler scheduler = ((QuartzConnector) this.getConnector()).getQuartzScheduler();
169 
170         // Minimize the the time window capturing the start time and scheduling the job.
171         long start = System.currentTimeMillis();
172         if (startDelay != null)
173         {
174             start += Long.parseLong(startDelay);
175         }
176         trigger.setStartTime(new Date(start));
177 
178         scheduler.scheduleJob(jobDetail, trigger);
179     }
180 
181     @Override
182     protected MuleMessage doSend(MuleEvent event) throws Exception
183     {
184         doDispatch(event);
185         return new DefaultMuleMessage(NullPayload.getInstance(), connector.getMuleContext());
186     }
187 
188     @Override
189     protected void doConnect() throws Exception
190     {
191         // template method
192     }
193 
194     @Override
195     protected void doDisconnect() throws Exception
196     {
197         // template method
198     }
199 
200 }