View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.transport.quartz.config;
8   
9   import org.mule.MessageExchangePattern;
10  import org.mule.api.MuleException;
11  import org.mule.api.annotations.Schedule;
12  import org.mule.api.annotations.meta.Channel;
13  import org.mule.api.annotations.meta.ChannelType;
14  import org.mule.api.endpoint.InboundEndpoint;
15  import org.mule.config.endpoint.AbstractEndpointAnnotationParser;
16  import org.mule.config.endpoint.AnnotatedEndpointData;
17  import org.mule.transport.quartz.QuartzConnector;
18  import org.mule.transport.quartz.jobs.EventGeneratorJobConfig;
19  import org.mule.util.CollectionUtils;
20  import org.mule.util.StringUtils;
21  import org.mule.util.UUID;
22  
23  import java.lang.annotation.Annotation;
24  import java.lang.reflect.Member;
25  import java.util.ArrayList;
26  import java.util.Collections;
27  import java.util.List;
28  import java.util.Map;
29  
30  /**
31   * Creates a Quartz inbound endpoint for a service
32   */
33  public class ScheduleAnnotationParser extends AbstractEndpointAnnotationParser
34  {
35  
36      @Override
37      public InboundEndpoint parseInboundEndpoint(Annotation annotation, Map metaInfo) throws MuleException
38      {
39          Schedule schedule = (Schedule) annotation;
40          ScheduleConfigBuilder builder = lookupConfig(schedule.config(), ScheduleConfigBuilder.class);
41          if (builder != null)
42          {
43              return builder.buildScheduler();
44          }
45          else
46          {
47              return super.parseInboundEndpoint(annotation, Collections.emptyMap());
48          }
49      }
50  
51      protected AnnotatedEndpointData createEndpointData(Annotation annotation) throws MuleException
52      {
53          //This will only get called if there is no config builder configured
54          Schedule schedule = (Schedule) annotation;
55  
56          String uri = "quartz://schedule" + UUID.getUUID();
57          AnnotatedEndpointData epData = new AnnotatedEndpointData(MessageExchangePattern.ONE_WAY, ChannelType.Inbound, annotation);
58  
59          epData.setProperties(convertProperties(getProperties(schedule)));
60          //By default the scheduler should only use a single thread
61          //TODO configure threads
62          String threads = (String) epData.getProperties().get("threads");
63          if (threads == null)
64          {
65              threads = "1";
66              epData.getProperties().put("threads", threads);
67          }
68          epData.setAddress(uri);
69          epData.setConnector(getConnector());
70          //Create event generator job
71          EventGeneratorJobConfig config = new EventGeneratorJobConfig();
72          config.setStateful(threads.equals("1"));
73          epData.getProperties().put(QuartzConnector.PROPERTY_JOB_CONFIG, config);
74          return epData;
75      }
76  
77  
78      protected String[] getProperties(Schedule schedule) throws MuleException
79      {
80          List<String> props = new ArrayList<String>(2);
81          if (StringUtils.isNotBlank(schedule.cron()))
82          {
83              props.add(QuartzConnector.PROPERTY_CRON_EXPRESSION + "=" + schedule.cron());
84          }
85          else if (schedule.interval() > -1)
86          {
87              props.add(QuartzConnector.PROPERTY_REPEAT_INTERVAL + "=" + schedule.interval());
88  
89              if (schedule.startDelay() > -1)
90              {
91                  props.add(QuartzConnector.PROPERTY_START_DELAY +"=" + schedule.startDelay());
92              }
93          }
94          else
95          {
96              throw new IllegalArgumentException("cron or repeatInterval must be set");
97          }
98          return CollectionUtils.toArrayOfComponentType(props, String.class);
99  
100     }
101 
102     protected String getIdentifier()
103     {
104         return Schedule.class.getAnnotation(Channel.class).identifer();
105     }
106 
107     protected QuartzConnector getConnector() throws MuleException
108     {
109         QuartzConnector connector = new QuartzConnector(muleContext);
110         connector.setName("scheduler." + connector.hashCode());
111         muleContext.getRegistry().registerConnector(connector);
112         return connector;
113     }
114 
115     /**
116      * Validates that this parser can parse the supplied annotation.  Only returns true if the clazz is not an interface
117      * and the annotation is an instance of {@link org.mule.api.annotations.Schedule}
118      *
119      * @param annotation the annotation being processed
120      * @param clazz      the class on which the annotation was found
121      * @param member     the member on which the annotation was found inside the class.  this is only set when the annotation
122      *                   was either set on a {@link java.lang.reflect.Method}, {@link java.lang.reflect.Field} or {@link java.lang.reflect.Constructor}
123      *                   class members, otherwise this value is null.
124      * @return true if this parser supports the current annotation and the clazz is not an interface
125      * @throws IllegalArgumentException if the class parameter is an interface
126      */
127     @Override
128     public boolean supports(Annotation annotation, Class clazz, Member member)
129     {
130         return !clazz.isInterface() && super.supports(annotation, clazz, member);
131     }
132 }