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.model;
018    
019    import java.util.concurrent.ExecutorService;
020    import java.util.concurrent.ScheduledExecutorService;
021    import javax.xml.bind.annotation.XmlAccessType;
022    import javax.xml.bind.annotation.XmlAccessorType;
023    import javax.xml.bind.annotation.XmlAttribute;
024    import javax.xml.bind.annotation.XmlRootElement;
025    import javax.xml.bind.annotation.XmlTransient;
026    
027    import org.apache.camel.Expression;
028    import org.apache.camel.Processor;
029    import org.apache.camel.builder.ExpressionBuilder;
030    import org.apache.camel.model.language.ExpressionDefinition;
031    import org.apache.camel.processor.Delayer;
032    import org.apache.camel.spi.RouteContext;
033    
034    /**
035     * Represents an XML <delay/> element
036     *
037     * @version 
038     */
039    @XmlRootElement(name = "delay")
040    @XmlAccessorType(XmlAccessType.FIELD)
041    public class DelayDefinition extends ExpressionNode implements ExecutorServiceAwareDefinition<DelayDefinition> {
042    
043        // TODO: Camel 3.0 Should extend NoOutputExpressionNode
044    
045        @XmlTransient
046        private ExecutorService executorService;
047        @XmlAttribute
048        private String executorServiceRef;
049        @XmlAttribute
050        private Boolean asyncDelayed;
051        @XmlAttribute
052        private Boolean callerRunsWhenRejected;
053    
054        public DelayDefinition() {
055        }
056    
057        public DelayDefinition(Expression delay) {
058            super(delay);
059        }
060    
061        @Override
062        public String getLabel() {
063            return "delay[" + getExpression() + "]";
064        }
065    
066        @Override
067        public String getShortName() {
068            return "delay";
069        }
070    
071        @Override
072        public String toString() {
073            return "Delay[" + getExpression() + " -> " + getOutputs() + "]";
074        }
075    
076        @Override
077        public Processor createProcessor(RouteContext routeContext) throws Exception {
078            Processor childProcessor = this.createChildProcessor(routeContext, false);
079            Expression delay = createAbsoluteTimeDelayExpression(routeContext);
080    
081            boolean shutdownThreadPool = ProcessorDefinitionHelper.willCreateNewThreadPool(routeContext, this, isAsyncDelayed());
082            ScheduledExecutorService threadPool = ProcessorDefinitionHelper.getConfiguredScheduledExecutorService(routeContext, "Delay", this, isAsyncDelayed());
083    
084            Delayer answer = new Delayer(routeContext.getCamelContext(), childProcessor, delay, threadPool, shutdownThreadPool);
085            if (getAsyncDelayed() != null) {
086                answer.setAsyncDelayed(getAsyncDelayed());
087            }
088            if (getCallerRunsWhenRejected() == null) {
089                // should be default true
090                answer.setCallerRunsWhenRejected(true);
091            } else {
092                answer.setCallerRunsWhenRejected(getCallerRunsWhenRejected());
093            }
094            return answer;
095        }
096    
097        private Expression createAbsoluteTimeDelayExpression(RouteContext routeContext) {
098            ExpressionDefinition expr = getExpression();
099            if (expr != null) {
100                return expr.createExpression(routeContext);
101            }
102            return null;
103        }
104    
105        // Fluent API
106        // -------------------------------------------------------------------------
107    
108        /**
109         * Sets the delay time in millis to delay
110         *
111         * @param delay delay time in millis
112         * @return the builder
113         */
114        public DelayDefinition delayTime(Long delay) {
115            setExpression(ExpressionNodeHelper.toExpressionDefinition(ExpressionBuilder.constantExpression(delay)));
116            return this;
117        }
118    
119        /**
120         * Whether or not the caller should run the task when it was rejected by the thread pool.
121         * <p/>
122         * Is by default <tt>true</tt>
123         *
124         * @param callerRunsWhenRejected whether or not the caller should run
125         * @return the builder
126         */
127        public DelayDefinition callerRunsWhenRejected(boolean callerRunsWhenRejected) {
128            setCallerRunsWhenRejected(callerRunsWhenRejected);
129            return this;
130        }
131    
132        /**
133         * Enables asynchronous delay which means the thread will <b>noy</b> block while delaying.
134         *
135         * @return the builder
136         */
137        public DelayDefinition asyncDelayed() {
138            setAsyncDelayed(true);
139            return this;
140        }
141    
142        public DelayDefinition executorService(ExecutorService executorService) {
143            setExecutorService(executorService);
144            return this;
145        }
146    
147        public DelayDefinition executorServiceRef(String executorServiceRef) {
148            setExecutorServiceRef(executorServiceRef);
149            return this;
150        }
151    
152        // Properties
153        // -------------------------------------------------------------------------
154    
155        public Boolean getAsyncDelayed() {
156            return asyncDelayed;
157        }
158    
159        public void setAsyncDelayed(Boolean asyncDelayed) {
160            this.asyncDelayed = asyncDelayed;
161        }
162    
163        public boolean isAsyncDelayed() {
164            return asyncDelayed != null && asyncDelayed;
165        }
166    
167        public Boolean getCallerRunsWhenRejected() {
168            return callerRunsWhenRejected;
169        }
170    
171        public void setCallerRunsWhenRejected(Boolean callerRunsWhenRejected) {
172            this.callerRunsWhenRejected = callerRunsWhenRejected;
173        }
174    
175        public ExecutorService getExecutorService() {
176            return executorService;
177        }
178    
179        public void setExecutorService(ExecutorService executorService) {
180            this.executorService = executorService;
181        }
182    
183        public String getExecutorServiceRef() {
184            return executorServiceRef;
185        }
186    
187        public void setExecutorServiceRef(String executorServiceRef) {
188            this.executorServiceRef = executorServiceRef;
189        }
190    }