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 }