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 */
017package org.apache.camel.component.timer;
018
019import java.util.Date;
020import java.util.Timer;
021
022import org.apache.camel.Component;
023import org.apache.camel.Consumer;
024import org.apache.camel.MultipleConsumersSupport;
025import org.apache.camel.Processor;
026import org.apache.camel.Producer;
027import org.apache.camel.RuntimeCamelException;
028import org.apache.camel.api.management.ManagedAttribute;
029import org.apache.camel.api.management.ManagedResource;
030import org.apache.camel.impl.DefaultEndpoint;
031import org.apache.camel.spi.Metadata;
032import org.apache.camel.spi.UriEndpoint;
033import org.apache.camel.spi.UriParam;
034import org.apache.camel.spi.UriPath;
035
036/**
037 * Represents a timer endpoint that can generate periodic inbound exchanges triggered by a timer.
038 *
039 * @version 
040 */
041@ManagedResource(description = "Managed TimerEndpoint")
042@UriEndpoint(scheme = "timer", syntax = "timer:timerName", consumerOnly = true, consumerClass = TimerConsumer.class, label = "core,scheduling")
043public class TimerEndpoint extends DefaultEndpoint implements MultipleConsumersSupport {
044    @UriPath @Metadata(required = "true")
045    private String timerName;
046    @UriParam
047    private Date time;
048    @UriParam(defaultValue = "1000")
049    private long period = 1000;
050    @UriParam(defaultValue = "1000")
051    private long delay = 1000;
052    @UriParam
053    private boolean fixedRate;
054    @UriParam(defaultValue = "true")
055    private boolean daemon = true;
056    @UriParam(defaultValue = "0")
057    private long repeatCount;
058    @UriParam
059    private Timer timer;
060
061    public TimerEndpoint() {
062    }
063
064    public TimerEndpoint(String uri, Component component, String timerName) {
065        super(uri, component);
066        this.timerName = timerName;
067    }
068    
069    protected TimerEndpoint(String endpointUri, Component component) {
070        super(endpointUri, component);
071    }
072
073    @Override
074    public TimerComponent getComponent() {
075        return (TimerComponent) super.getComponent();
076    }
077
078    public Producer createProducer() throws Exception {
079        throw new RuntimeCamelException("Cannot produce to a TimerEndpoint: " + getEndpointUri());
080    }
081
082    public Consumer createConsumer(Processor processor) throws Exception {
083        Consumer answer = new TimerConsumer(this, processor);
084        configureConsumer(answer);
085        return answer;
086    }
087
088    @Override
089    protected void doStart() throws Exception {
090        super.doStart();
091        // do nothing, the timer will be set when the first consumer will request it
092    }
093
094    @Override
095    protected void doStop() throws Exception {
096        setTimer(null);
097        super.doStop();
098    }
099
100    @ManagedAttribute
101    public boolean isMultipleConsumersSupported() {
102        return true;
103    }
104
105    @ManagedAttribute(description = "Timer Name")
106    public String getTimerName() {
107        if (timerName == null) {
108            timerName = getEndpointUri();
109        }
110        return timerName;
111    }
112
113    /**
114     * The name of the timer
115     */
116    @ManagedAttribute(description = "Timer Name")
117    public void setTimerName(String timerName) {
118        this.timerName = timerName;
119    }
120
121    @ManagedAttribute(description = "Timer Daemon")
122    public boolean isDaemon() {
123        return daemon;
124    }
125
126    /**
127     * Specifies whether or not the thread associated with the timer endpoint runs as a daemon.
128     * <p/>
129     * The default value is true.
130     */
131    @ManagedAttribute(description = "Timer Daemon")
132    public void setDaemon(boolean daemon) {
133        this.daemon = daemon;
134    }
135
136    @ManagedAttribute(description = "Timer Delay")
137    public long getDelay() {
138        return delay;
139    }
140
141    /**
142     * The number of milliseconds to wait before the first event is generated. Should not be used in conjunction with the time option.
143     * <p/>
144     * The default value is 1000.
145     */
146    @ManagedAttribute(description = "Timer Delay")
147    public void setDelay(long delay) {
148        this.delay = delay;
149    }
150
151    @ManagedAttribute(description = "Timer FixedRate")
152    public boolean isFixedRate() {
153        return fixedRate;
154    }
155
156    /**
157     * Events take place at approximately regular intervals, separated by the specified period.
158     */
159    @ManagedAttribute(description = "Timer FixedRate")
160    public void setFixedRate(boolean fixedRate) {
161        this.fixedRate = fixedRate;
162    }
163
164    @ManagedAttribute(description = "Timer Period")
165    public long getPeriod() {
166        return period;
167    }
168
169    /**
170     * If greater than 0, generate periodic events every period milliseconds.
171     * <p/>
172     * The default value is 1000.
173     */
174    @ManagedAttribute(description = "Timer Period")
175    public void setPeriod(long period) {
176        this.period = period;
177    }
178
179    @ManagedAttribute(description = "Repeat Count")
180    public long getRepeatCount() {
181        return repeatCount;
182    }
183
184    /**
185     * Specifies a maximum limit of number of fires.
186     * So if you set it to 1, the timer will only fire once.
187     * If you set it to 5, it will only fire five times.
188     * A value of zero or negative means fire forever.
189     */
190    @ManagedAttribute(description = "Repeat Count")
191    public void setRepeatCount(long repeatCount) {
192        this.repeatCount = repeatCount;
193    }
194
195    public Date getTime() {
196        return time;
197    }
198
199    /**
200     * A java.util.Date the first event should be generated. If using the URI, the pattern expected is: yyyy-MM-dd HH:mm:ss or yyyy-MM-dd'T'HH:mm:ss.
201     */
202    public void setTime(Date time) {
203        this.time = time;
204    }
205
206    @ManagedAttribute(description = "Singleton")
207    public boolean isSingleton() {
208        return true;
209    }
210
211    @ManagedAttribute(description = "Camel id")
212    public String getCamelId() {
213        return this.getCamelContext().getName();
214    }
215
216    @ManagedAttribute(description = "Camel ManagementName")
217    public String getCamelManagementName() {
218        return this.getCamelContext().getManagementName();
219    }
220
221    @ManagedAttribute(description = "Endpoint Uri")
222    public String getEndpointUri() {
223        return super.getEndpointUri();
224    }
225
226    @ManagedAttribute(description = "Endpoint State")
227    public String getState() {
228        return getStatus().name();
229    }
230
231    public Timer getTimer(TimerConsumer consumer) {
232        if (timer != null) {
233            // use custom timer
234            return timer;
235        }
236        return getComponent().getTimer(consumer);
237    }
238
239    /**
240     * To use a custom {@link Timer}
241     */
242    public void setTimer(Timer timer) {
243        this.timer = timer;
244    }
245
246    public void removeTimer(TimerConsumer consumer) {
247        if (timer == null) {
248            // only remove timer if we are not using a custom timer
249            getComponent().removeTimer(consumer);
250        }
251    }
252
253}