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.Collections;
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.Expression;
029 import org.apache.camel.Processor;
030 import org.apache.camel.model.language.ExpressionDefinition;
031 import org.apache.camel.processor.RecipientList;
032 import org.apache.camel.processor.aggregate.AggregationStrategy;
033 import org.apache.camel.processor.aggregate.UseLatestAggregationStrategy;
034 import org.apache.camel.spi.RouteContext;
035 import org.apache.camel.util.concurrent.ExecutorServiceHelper;
036
037 /**
038 * Represents an XML <recipientList/> element
039 *
040 * @version $Revision: 887262 $
041 */
042 @XmlRootElement(name = "recipientList")
043 @XmlAccessorType(XmlAccessType.FIELD)
044 public class RecipientListDefinition extends ExpressionNode {
045
046 @XmlTransient
047 private AggregationStrategy aggregationStrategy;
048 @XmlTransient
049 private ExecutorService executorService;
050 @XmlAttribute(required = false)
051 private String delimiter;
052 @XmlAttribute(required = false)
053 private Boolean parallelProcessing;
054 @XmlAttribute(required = false)
055 private String strategyRef;
056 @XmlAttribute(required = false)
057 private String executorServiceRef;
058 @XmlAttribute(required = false)
059 private Boolean stopOnException;
060
061 public RecipientListDefinition() {
062 }
063
064 public RecipientListDefinition(ExpressionDefinition expression) {
065 super(expression);
066 }
067
068 public RecipientListDefinition(Expression expression) {
069 super(expression);
070 }
071
072 @Override
073 public String toString() {
074 return "RecipientList[" + getExpression() + "]";
075 }
076
077 @Override
078 public String getShortName() {
079 return "recipientList";
080 }
081
082 @Override
083 public Processor createProcessor(RouteContext routeContext) throws Exception {
084 Expression expression = getExpression().createExpression(routeContext);
085
086 RecipientList answer;
087 if (delimiter != null) {
088 answer = new RecipientList(expression, delimiter);
089 } else {
090 answer = new RecipientList(expression);
091 }
092
093 if (parallelProcessing != null) {
094 answer.setParallelProcessing(isParallelProcessing());
095 }
096 if (stopOnException != null) {
097 answer.setStopOnException(isStopOnException());
098 }
099
100 answer.setAggregationStrategy(createAggregationStrategy(routeContext));
101 answer.setExecutorService(createExecutorService(routeContext));
102
103 return answer;
104 }
105
106 private AggregationStrategy createAggregationStrategy(RouteContext routeContext) {
107 if (aggregationStrategy == null && strategyRef != null) {
108 aggregationStrategy = routeContext.lookup(strategyRef, AggregationStrategy.class);
109 }
110 if (aggregationStrategy == null) {
111 // fallback to use latest
112 aggregationStrategy = new UseLatestAggregationStrategy();
113 }
114 return aggregationStrategy;
115 }
116
117 private ExecutorService createExecutorService(RouteContext routeContext) {
118 if (executorService == null && executorServiceRef != null) {
119 executorService = routeContext.lookup(executorServiceRef, ExecutorService.class);
120 }
121 if (executorService == null) {
122 // fall back and use default
123 executorService = ExecutorServiceHelper.newScheduledThreadPool(10, "RecipientList", true);
124 }
125 return executorService;
126 }
127
128 @Override
129 @SuppressWarnings("unchecked")
130 public List<ProcessorDefinition> getOutputs() {
131 return Collections.EMPTY_LIST;
132 }
133
134 @Override
135 public void addOutput(ProcessorDefinition processorType) {
136 // add it to the parent as a recipient list does not support outputs
137 getParent().addOutput(processorType);
138 }
139
140 // Fluent API
141 // -------------------------------------------------------------------------
142
143 /**
144 * Set the aggregationStrategy
145 *
146 * @return the builder
147 */
148 public RecipientListDefinition aggregationStrategy(AggregationStrategy aggregationStrategy) {
149 setAggregationStrategy(aggregationStrategy);
150 return this;
151 }
152
153 /**
154 * Doing the splitting work in parallel
155 *
156 * @return the builder
157 */
158 public RecipientListDefinition parallelProcessing() {
159 setParallelProcessing(true);
160 return this;
161 }
162
163 /**
164 * Will now stop further processing if an exception occurred during processing of an
165 * {@link org.apache.camel.Exchange} and the caused exception will be thrown.
166 * <p/>
167 * The default behavior is to <b>not</b> stop but continue processing till the end
168 *
169 * @return the builder
170 */
171 public RecipientListDefinition stopOnException() {
172 setStopOnException(true);
173 return this;
174 }
175
176 /**
177 * Setting the executor service for executing the sending to the recipients.
178 *
179 * @param executorService the executor service
180 * @return the builder
181 */
182 public RecipientListDefinition executorService(ExecutorService executorService) {
183 setExecutorService(executorService);
184 return this;
185 }
186
187 // Properties
188 //-------------------------------------------------------------------------
189
190 public String getDelimiter() {
191 return delimiter;
192 }
193
194 public void setDelimiter(String delimiter) {
195 this.delimiter = delimiter;
196 }
197
198 public Boolean isParallelProcessing() {
199 return parallelProcessing;
200 }
201
202 public void setParallelProcessing(Boolean parallelProcessing) {
203 this.parallelProcessing = parallelProcessing;
204 }
205
206 public String getStrategyRef() {
207 return strategyRef;
208 }
209
210 public void setStrategyRef(String strategyRef) {
211 this.strategyRef = strategyRef;
212 }
213
214 public String getExecutorServiceRef() {
215 return executorServiceRef;
216 }
217
218 public void setExecutorServiceRef(String executorServiceRef) {
219 this.executorServiceRef = executorServiceRef;
220 }
221
222 public Boolean isStopOnException() {
223 return stopOnException;
224 }
225
226 public void setStopOnException(Boolean stopOnException) {
227 this.stopOnException = stopOnException;
228 }
229
230 public AggregationStrategy getAggregationStrategy() {
231 return aggregationStrategy;
232 }
233
234 public void setAggregationStrategy(AggregationStrategy aggregationStrategy) {
235 this.aggregationStrategy = aggregationStrategy;
236 }
237
238 public ExecutorService getExecutorService() {
239 return executorService;
240 }
241
242 public void setExecutorService(ExecutorService executorService) {
243 this.executorService = executorService;
244 }
245 }