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.ArrayList;
020    import java.util.List;
021    import java.util.concurrent.ExecutorService;
022    import javax.xml.bind.annotation.XmlAccessType;
023    import javax.xml.bind.annotation.XmlAccessorType;
024    import javax.xml.bind.annotation.XmlAttribute;
025    import javax.xml.bind.annotation.XmlRootElement;
026    import javax.xml.bind.annotation.XmlTransient;
027    
028    import org.apache.camel.Endpoint;
029    import org.apache.camel.ExchangePattern;
030    import org.apache.camel.Processor;
031    import org.apache.camel.processor.SendAsyncProcessor;
032    import org.apache.camel.processor.UnitOfWorkProcessor;
033    import org.apache.camel.spi.RouteContext;
034    import org.apache.camel.util.concurrent.ExecutorServiceHelper;
035    
036    /**
037     * Represents an XML <to/> element
038     *
039     * @version $Revision: 890241 $
040     */
041    @XmlRootElement(name = "to")
042    @XmlAccessorType(XmlAccessType.FIELD)
043    public class ToDefinition extends SendDefinition<ToDefinition> {
044        @XmlTransient
045        private final List<ProcessorDefinition> outputs = new ArrayList<ProcessorDefinition>();
046        @XmlAttribute(required = false)
047        private ExchangePattern pattern;
048        @XmlAttribute(required = false)
049        private Boolean async = Boolean.FALSE;
050        @XmlTransient
051        private ExecutorService executorService;
052        @XmlAttribute(required = false)
053        private String executorServiceRef;
054        @XmlAttribute(required = false)
055        private Integer poolSize;
056    
057        public ToDefinition() {
058        }
059    
060        public ToDefinition(String uri) {
061            setUri(uri);
062        }
063    
064        public ToDefinition(Endpoint endpoint) {
065            setEndpoint(endpoint);
066        }
067    
068        public ToDefinition(String uri, ExchangePattern pattern) {
069            this(uri);
070            this.pattern = pattern;
071        }
072    
073        public ToDefinition(Endpoint endpoint, ExchangePattern pattern) {
074            this(endpoint);
075            this.pattern = pattern;
076        }
077    
078        @Override
079        public List<ProcessorDefinition> getOutputs() {
080            return outputs;
081        }
082    
083        @Override
084        public Processor createProcessor(RouteContext routeContext) throws Exception {
085            if (async == null || !async) {
086                // when sync then let super create the processor
087                return super.createProcessor(routeContext);
088            }
089    
090            if (executorServiceRef != null) {
091                executorService = routeContext.lookup(executorServiceRef, ExecutorService.class);
092            }
093            if (executorService == null && poolSize != null) {
094                executorService = ExecutorServiceHelper.newScheduledThreadPool(poolSize, "ToAsync[" + getLabel() + "]", true);
095            }
096    
097            // create the child processor which is the async route
098            Processor childProcessor = routeContext.createProcessor(this);
099    
100            // wrap it in a unit of work so the route that comes next is also done in a unit of work
101            UnitOfWorkProcessor uow = new UnitOfWorkProcessor(routeContext, childProcessor);
102    
103            // create async processor
104            Endpoint endpoint = resolveEndpoint(routeContext);
105    
106            SendAsyncProcessor async = new SendAsyncProcessor(endpoint, getPattern(), uow);
107            if (executorService != null) {
108                async.setExecutorService(executorService);
109            }
110            if (poolSize != null) {
111                async.setPoolSize(poolSize);
112            }
113    
114            return async;
115        }
116    
117        @Override
118        public String toString() {
119            if (async != null && async) {
120                return "ToAsync[" + getLabel() + "] -> " + getOutputs();
121            } else {
122                return "To[" + getLabel() + "]";
123            }
124        }
125    
126        @Override
127        public String getShortName() {
128            return "to";
129        }
130    
131        @Override
132        public ExchangePattern getPattern() {
133            return pattern;
134        }
135    
136        public Boolean isAsync() {
137            return async;
138        }
139    
140        public void setAsync(Boolean async) {
141            this.async = async;
142        }
143    
144        public Integer getPoolSize() {
145            return poolSize;
146        }
147    
148        public void setPoolSize(Integer poolSize) {
149            this.poolSize = poolSize;
150        }
151    
152        public ExecutorService getExecutorService() {
153            return executorService;
154        }
155    
156        public void setExecutorService(ExecutorService executorService) {
157            this.executorService = executorService;
158        }
159    
160        public String getExecutorServiceRef() {
161            return executorServiceRef;
162        }
163    
164        public void setExecutorServiceRef(String executorServiceRef) {
165            this.executorServiceRef = executorServiceRef;
166        }
167    
168        /**
169         * Sets the optional {@link ExchangePattern} used to invoke this endpoint
170         */
171        public void setPattern(ExchangePattern pattern) {
172            this.pattern = pattern;
173        }
174    
175        /**
176         * Setting the executor service for executing the async routing.
177         *
178         * @return the builder
179         */
180        public ToDefinition executorService(ExecutorService executorService) {
181            setExecutorService(executorService);
182            return this;
183        }
184    
185        /**
186         * Setting the executor service for executing the async routing.
187         *
188         * @return the builder
189         */
190        public ToDefinition executorServiceRef(String executorServiceRef) {
191            setExecutorServiceRef(executorServiceRef);
192            return this;
193        }
194    
195        /**
196         * Setting the core pool size for the underlying {@link java.util.concurrent.ExecutorService}.
197         *
198         * @return the builder
199         */
200        public ToDefinition poolSize(int poolSize) {
201            setPoolSize(poolSize);
202            return this;
203        }
204    }