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.Arrays;
021 import java.util.Collection;
022 import java.util.Collections;
023 import java.util.Comparator;
024 import java.util.Iterator;
025 import java.util.LinkedList;
026 import java.util.List;
027 import java.util.concurrent.TimeUnit;
028
029 import javax.xml.bind.annotation.XmlAccessType;
030 import javax.xml.bind.annotation.XmlAccessorType;
031 import javax.xml.bind.annotation.XmlTransient;
032
033 import org.apache.camel.Channel;
034 import org.apache.camel.Endpoint;
035 import org.apache.camel.ExchangePattern;
036 import org.apache.camel.Expression;
037 import org.apache.camel.LoggingLevel;
038 import org.apache.camel.Predicate;
039 import org.apache.camel.Processor;
040 import org.apache.camel.Route;
041 import org.apache.camel.builder.DataFormatClause;
042 import org.apache.camel.builder.ErrorHandlerBuilder;
043 import org.apache.camel.builder.ErrorHandlerBuilderRef;
044 import org.apache.camel.builder.ExpressionBuilder;
045 import org.apache.camel.builder.ExpressionClause;
046 import org.apache.camel.builder.ProcessorBuilder;
047 import org.apache.camel.language.simple.SimpleLanguage;
048 import org.apache.camel.model.language.ConstantExpression;
049 import org.apache.camel.model.language.ExpressionDefinition;
050 import org.apache.camel.model.language.LanguageExpression;
051 import org.apache.camel.processor.DefaultChannel;
052 import org.apache.camel.processor.InterceptEndpointProcessor;
053 import org.apache.camel.processor.Pipeline;
054 import org.apache.camel.processor.aggregate.AggregationCollection;
055 import org.apache.camel.processor.aggregate.AggregationStrategy;
056 import org.apache.camel.processor.interceptor.Delayer;
057 import org.apache.camel.processor.interceptor.HandleFault;
058 import org.apache.camel.processor.interceptor.StreamCaching;
059 import org.apache.camel.processor.loadbalancer.LoadBalancer;
060 import org.apache.camel.spi.DataFormat;
061 import org.apache.camel.spi.IdempotentRepository;
062 import org.apache.camel.spi.InterceptStrategy;
063 import org.apache.camel.spi.LifecycleStrategy;
064 import org.apache.camel.spi.Policy;
065 import org.apache.camel.spi.RouteContext;
066 import org.apache.camel.spi.TransactedPolicy;
067 import org.apache.commons.logging.Log;
068 import org.apache.commons.logging.LogFactory;
069
070 import static org.apache.camel.builder.Builder.body;
071
072 /**
073 * Base class for processor types that most XML types extend.
074 *
075 * @version $Revision: 896185 $
076 */
077 @XmlAccessorType(XmlAccessType.PROPERTY)
078 public abstract class ProcessorDefinition<Type extends ProcessorDefinition> extends OptionalIdentifiedDefinition implements Block {
079 protected final transient Log log = LogFactory.getLog(getClass());
080 protected ErrorHandlerBuilder errorHandlerBuilder;
081 protected String errorHandlerRef;
082 private NodeFactory nodeFactory;
083 private final LinkedList<Block> blocks = new LinkedList<Block>();
084 private ProcessorDefinition<?> parent;
085 private final List<InterceptStrategy> interceptStrategies = new ArrayList<InterceptStrategy>();
086
087 // else to use an optional attribute in JAXB2
088 public abstract List<ProcessorDefinition> getOutputs();
089
090 /**
091 * Whether this model is abstract or not.
092 * <p/>
093 * An abstract model is something that is used for configuring cross cutting concerns such as
094 * error handling, transaction policies, interceptors etc.
095 * <p/>
096 * Regular definitions is what is part of the route, such as ToDefinition, WireTapDefinition and the likes.
097 * <p/>
098 * Will by default return <tt>false</tt> to indicate regular definition, so all the abstract definitions
099 * must override this method and return <tt>true</tt> instead.
100 * <p/>
101 * This information is used in camel-spring to let Camel work a bit on the model provided by JAXB from the
102 * Spring XML file. This is needed to handle those cross cutting concerns properly. The Java DSL does not
103 * have this issue as it can work this out directly using the fluent builder methods.
104 *
105 * @return <tt>true</tt> for abstract, otherwise <tt>false</tt> for regular.
106 */
107 public boolean isAbstract() {
108 return false;
109 }
110
111 public Processor createProcessor(RouteContext routeContext) throws Exception {
112 throw new UnsupportedOperationException("Not implemented yet for class: " + getClass().getName());
113 }
114
115 public Processor createOutputsProcessor(RouteContext routeContext) throws Exception {
116 Collection<ProcessorDefinition> outputs = getOutputs();
117 return createOutputsProcessor(routeContext, outputs);
118 }
119
120 public void addOutput(ProcessorDefinition processorType) {
121 processorType.setParent(this);
122 configureChild(processorType);
123 if (blocks.isEmpty()) {
124 getOutputs().add(processorType);
125 } else {
126 Block block = blocks.getLast();
127 block.addOutput(processorType);
128 }
129 }
130
131 public void clearOutput() {
132 getOutputs().clear();
133 blocks.clear();
134 }
135
136 public void addRoutes(RouteContext routeContext, Collection<Route> routes) throws Exception {
137 Processor processor = makeProcessor(routeContext);
138 if (processor == null) {
139 // no processor to add
140 return;
141 }
142
143 if (!routeContext.isRouteAdded()) {
144 boolean endpointInterceptor = false;
145
146 // are we routing to an endpoint interceptor, if so we should not add it as an event driven
147 // processor as we use the producer to trigger the interceptor
148 if (processor instanceof Channel) {
149 Channel channel = (Channel) processor;
150 Processor next = channel.getNextProcessor();
151 if (next instanceof InterceptEndpointProcessor) {
152 endpointInterceptor = true;
153 }
154 }
155
156 // only add regular processors as event driven
157 if (endpointInterceptor) {
158 if (log.isDebugEnabled()) {
159 log.debug("Endpoint interceptor should not be added as an event driven consumer route: " + processor);
160 }
161 } else {
162 if (log.isTraceEnabled()) {
163 log.trace("Adding event driven processor: " + processor);
164 }
165 routeContext.addEventDrivenProcessor(processor);
166 }
167
168 }
169 }
170
171 /**
172 * Wraps the child processor in whatever necessary interceptors and error handlers
173 */
174 public Processor wrapProcessor(RouteContext routeContext, Processor processor) throws Exception {
175 // dont double wrap
176 if (processor instanceof Channel) {
177 return processor;
178 }
179 return wrapChannel(routeContext, processor, null);
180 }
181
182 protected Processor wrapChannel(RouteContext routeContext, Processor processor, ProcessorDefinition child) throws Exception {
183 // put a channel in between this and each output to control the route flow logic
184 Channel channel = createChannel(routeContext);
185 channel.setNextProcessor(processor);
186
187 // add interceptor strategies to the channel must be in this order: camel context, route context, local
188 addInterceptStrategies(routeContext, channel, routeContext.getCamelContext().getInterceptStrategies());
189 addInterceptStrategies(routeContext, channel, routeContext.getInterceptStrategies());
190 if (routeContext.getManagedInterceptStrategy() != null) {
191 channel.addInterceptStrategy(routeContext.getManagedInterceptStrategy());
192 }
193 addInterceptStrategies(routeContext, channel, this.getInterceptStrategies());
194
195 // must do this ugly cast to avoid compiler error on HP-UX
196 ProcessorDefinition defn = (ProcessorDefinition) this;
197
198 // set the child before init the channel
199 channel.setChildDefinition(child);
200 channel.initChannel(defn, routeContext);
201
202 // set the error handler, must be done after init as we can set the error handler as first in the chain
203 if (defn instanceof TryDefinition || defn instanceof CatchDefinition || defn instanceof FinallyDefinition) {
204 // do not use error handler for try .. catch .. finally blocks as it will handle errors itself
205 return channel;
206 } else if (defn instanceof MulticastDefinition || defn instanceof RecipientListDefinition) {
207 // do not use error handler for multicast or recipientlist based as it offers fine grained error handlers for its outputs
208 return channel;
209 } else {
210 // regular definition so add the error handler
211 Processor output = channel.getOutput();
212 Processor errorHandler = wrapInErrorHandler(routeContext, getErrorHandlerBuilder(), output);
213 // set error handler on channel
214 channel.setErrorHandler(errorHandler);
215
216 return channel;
217 }
218 }
219
220 /**
221 * Wraps the given output in an error handler
222 *
223 * @param routeContext the route context
224 * @param output the output
225 * @return the output wrapped with the error handler
226 * @throws Exception can be thrown if failed to create error handler builder
227 */
228 protected Processor wrapInErrorHandler(RouteContext routeContext, ErrorHandlerBuilder builder, Processor output) throws Exception {
229 // create error handler
230 Processor errorHandler = builder.createErrorHandler(routeContext, output);
231
232 // invoke lifecycles so we can manage this error handler builder
233 for (LifecycleStrategy strategy : routeContext.getCamelContext().getLifecycleStrategies()) {
234 strategy.onErrorHandlerAdd(routeContext, errorHandler, builder);
235 }
236
237 return errorHandler;
238 }
239
240 /**
241 * Adds the given list of interceptors to the channel.
242 *
243 * @param routeContext the route context
244 * @param channel the channel to add strategies
245 * @param strategies list of strategies to add.
246 */
247 protected void addInterceptStrategies(RouteContext routeContext, Channel channel, List<InterceptStrategy> strategies) {
248 for (InterceptStrategy strategy : strategies) {
249 if (!routeContext.isStreamCaching() && strategy instanceof StreamCaching) {
250 // stream cache is disabled so we should not add it
251 continue;
252 }
253 if (!routeContext.isHandleFault() && strategy instanceof HandleFault) {
254 // handle fault is disabled so we should not add it
255 continue;
256 }
257 if (strategy instanceof Delayer) {
258 if (routeContext.getDelayer() == null || routeContext.getDelayer() <= 0) {
259 // delayer is disabled so we should not add it
260 continue;
261 } else {
262 // replace existing delayer as delayer have individual configuration
263 Iterator<InterceptStrategy> it = channel.getInterceptStrategies().iterator();
264 while (it.hasNext()) {
265 InterceptStrategy existing = it.next();
266 if (existing instanceof Delayer) {
267 it.remove();
268 }
269 }
270 // add the new correct delayer
271 channel.addInterceptStrategy(strategy);
272 continue;
273 }
274 }
275
276 // add strategy
277 channel.addInterceptStrategy(strategy);
278 }
279 }
280
281 /**
282 * Creates a new instance of some kind of composite processor which defaults
283 * to using a {@link Pipeline} but derived classes could change the behaviour
284 */
285 protected Processor createCompositeProcessor(RouteContext routeContext, List<Processor> list) throws Exception {
286 return new Pipeline(list);
287 }
288
289 /**
290 * Creates a new instance of the {@link Channel}.
291 */
292 protected Channel createChannel(RouteContext routeContext) throws Exception {
293 return new DefaultChannel();
294 }
295
296 protected Processor createOutputsProcessor(RouteContext routeContext, Collection<ProcessorDefinition> outputs) throws Exception {
297 List<Processor> list = new ArrayList<Processor>();
298 for (ProcessorDefinition<?> output : outputs) {
299 Processor processor = output.createProcessor(routeContext);
300 if (output instanceof Channel && processor == null) {
301 continue;
302 }
303
304 Processor channel = wrapChannel(routeContext, processor, output);
305 list.add(channel);
306 }
307
308 // if more than one output wrap than in a composite processor else just keep it as is
309 Processor processor = null;
310 if (!list.isEmpty()) {
311 if (list.size() == 1) {
312 processor = list.get(0);
313 } else {
314 processor = createCompositeProcessor(routeContext, list);
315 }
316 }
317
318 return processor;
319 }
320
321 /**
322 * Creates the processor and wraps it in any necessary interceptors and error handlers
323 */
324 protected Processor makeProcessor(RouteContext routeContext) throws Exception {
325 Processor processor = createProcessor(routeContext);
326 if (processor == null) {
327 // no processor to make
328 return null;
329 }
330 return wrapProcessor(routeContext, processor);
331 }
332
333 protected ErrorHandlerBuilder createErrorHandlerBuilder() {
334 if (errorHandlerRef != null) {
335 return new ErrorHandlerBuilderRef(errorHandlerRef);
336 }
337
338 // return a reference to the default error handler
339 return new ErrorHandlerBuilderRef(ErrorHandlerBuilderRef.DEFAULT_ERROR_HANDLER_BUILDER);
340 }
341
342 protected void configureChild(ProcessorDefinition output) {
343 output.setNodeFactory(getNodeFactory());
344 output.setErrorHandlerBuilder(getErrorHandlerBuilder());
345 }
346
347 // Fluent API
348 // -------------------------------------------------------------------------
349
350 /**
351 * Sends the exchange to the given endpoint
352 *
353 * @param uri the endpoint to send to
354 * @return the builder
355 */
356 @SuppressWarnings("unchecked")
357 public Type to(String uri) {
358 addOutput(new ToDefinition(uri));
359 return (Type) this;
360 }
361
362 /**
363 * Sends the exchange to the given endpoint
364 *
365 * @param uri the String formatted endpoint uri to send to
366 * @param args arguments for the string formatting of the uri
367 * @return the builder
368 */
369 @SuppressWarnings("unchecked")
370 public Type toF(String uri, Object... args) {
371 addOutput(new ToDefinition(String.format(uri, args)));
372 return (Type) this;
373 }
374
375
376 /**
377 * Sends the exchange to the given endpoint
378 *
379 * @param endpoint the endpoint to send to
380 * @return the builder
381 */
382 @SuppressWarnings("unchecked")
383 public Type to(Endpoint endpoint) {
384 addOutput(new ToDefinition(endpoint));
385 return (Type) this;
386 }
387
388 /**
389 * Sends the exchange with certain exchange pattern to the given endpoint
390 *
391 * @param pattern the pattern to use for the message exchange
392 * @param uri the endpoint to send to
393 * @return the builder
394 */
395 @SuppressWarnings("unchecked")
396 public Type to(ExchangePattern pattern, String uri) {
397 addOutput(new ToDefinition(uri, pattern));
398 return (Type) this;
399 }
400
401
402 /**
403 * Sends the exchange with certain exchange pattern to the given endpoint
404 *
405 * @param pattern the pattern to use for the message exchange
406 * @param endpoint the endpoint to send to
407 * @return the builder
408 */
409 @SuppressWarnings("unchecked")
410 public Type to(ExchangePattern pattern, Endpoint endpoint) {
411 addOutput(new ToDefinition(endpoint, pattern));
412 return (Type) this;
413 }
414
415 /**
416 * Sends the exchange to a list of endpoints
417 *
418 * @param uris list of endpoints to send to
419 * @return the builder
420 */
421 @SuppressWarnings("unchecked")
422 public Type to(String... uris) {
423 for (String uri : uris) {
424 addOutput(new ToDefinition(uri));
425 }
426 return (Type) this;
427 }
428
429
430 /**
431 * Sends the exchange to a list of endpoints
432 *
433 * @param endpoints list of endpoints to send to
434 * @return the builder
435 */
436 @SuppressWarnings("unchecked")
437 public Type to(Endpoint... endpoints) {
438 for (Endpoint endpoint : endpoints) {
439 addOutput(new ToDefinition(endpoint));
440 }
441 return (Type) this;
442 }
443
444 /**
445 * Sends the exchange to a list of endpoints
446 *
447 * @param endpoints list of endpoints to send to
448 * @return the builder
449 */
450 @SuppressWarnings("unchecked")
451 public Type to(Iterable<Endpoint> endpoints) {
452 for (Endpoint endpoint : endpoints) {
453 addOutput(new ToDefinition(endpoint));
454 }
455 return (Type) this;
456 }
457
458
459 /**
460 * Sends the exchange to a list of endpoints
461 *
462 * @param pattern the pattern to use for the message exchanges
463 * @param uris list of endpoints to send to
464 * @return the builder
465 */
466 @SuppressWarnings("unchecked")
467 public Type to(ExchangePattern pattern, String... uris) {
468 for (String uri : uris) {
469 addOutput(new ToDefinition(uri, pattern));
470 }
471 return (Type) this;
472 }
473
474 /**
475 * Sends the exchange to a list of endpoints
476 *
477 * @param pattern the pattern to use for the message exchanges
478 * @param endpoints list of endpoints to send to
479 * @return the builder
480 */
481 @SuppressWarnings("unchecked")
482 public Type to(ExchangePattern pattern, Endpoint... endpoints) {
483 for (Endpoint endpoint : endpoints) {
484 addOutput(new ToDefinition(endpoint, pattern));
485 }
486 return (Type) this;
487 }
488
489 /**
490 * Sends the exchange to a list of endpoints
491 *
492 * @param pattern the pattern to use for the message exchanges
493 * @param endpoints list of endpoints to send to
494 * @return the builder
495 */
496 @SuppressWarnings("unchecked")
497 public Type to(ExchangePattern pattern, Iterable<Endpoint> endpoints) {
498 for (Endpoint endpoint : endpoints) {
499 addOutput(new ToDefinition(endpoint, pattern));
500 }
501 return (Type) this;
502 }
503
504 /**
505 * Sends the exchange to the given endpoint using synchronous mode.
506 *
507 * @param uri the endpoint to send to
508 * @return the builder
509 * @see org.apache.camel.AsyncProcessor
510 */
511 public ToDefinition toAsync(String uri) {
512 ToDefinition answer = new ToDefinition(uri);
513 answer.setAsync(true);
514 addOutput(answer);
515 // must push a block so we have a child route for the async reply
516 // routing which is separated from the caller route
517 pushBlock(answer);
518 return answer;
519 }
520
521 /**
522 * Sends the exchange to the given endpoint using synchronous mode.
523 *
524 * @param uri the endpoint to send to
525 * @param poolSize the core pool size
526 * @return the builder
527 * @see org.apache.camel.AsyncProcessor
528 */
529 public ToDefinition toAsync(String uri, int poolSize) {
530 ToDefinition answer = new ToDefinition(uri);
531 answer.setAsync(true);
532 answer.setPoolSize(poolSize);
533 addOutput(answer);
534 // must push a block so we have a child route for the async reply
535 // routing which is separated from the caller route
536 pushBlock(answer);
537 return answer;
538 }
539
540 /**
541 * Sends the exchange to the given endpoint using synchronous mode.
542 *
543 * @param endpoint the endpoint to send to
544 * @return the builder
545 * @see org.apache.camel.AsyncProcessor
546 */
547 public ToDefinition toAsync(Endpoint endpoint) {
548 ToDefinition answer = new ToDefinition(endpoint);
549 answer.setAsync(true);
550 addOutput(answer);
551 // must push a block so we have a child route for the async reply
552 // routing which is separated from the caller route
553 pushBlock(answer);
554 return answer;
555 }
556
557 /**
558 * Sends the exchange to the given endpoint using synchronous mode.
559 *
560 * @param endpoint the endpoint to send to
561 * @param poolSize the core pool size
562 * @return the builder
563 * @see org.apache.camel.AsyncProcessor
564 */
565 public ToDefinition toAsync(Endpoint endpoint, int poolSize) {
566 ToDefinition answer = new ToDefinition(endpoint);
567 answer.setAsync(true);
568 answer.setPoolSize(poolSize);
569 addOutput(answer);
570 // must push a block so we have a child route for the async reply
571 // routing which is separated from the caller route
572 pushBlock(answer);
573 return answer;
574 }
575
576 /**
577 * <a href="http://camel.apache.org/exchange-pattern.html">ExchangePattern:</a>
578 * set the ExchangePattern {@link ExchangePattern} into the exchange
579 *
580 * @param exchangePattern instance of {@link ExchangePattern}
581 * @return the builder
582 */
583 @SuppressWarnings("unchecked")
584 public Type setExchangePattern(ExchangePattern exchangePattern) {
585 addOutput(new SetExchangePatternDefinition(exchangePattern));
586 return (Type) this;
587 }
588
589 /**
590 * <a href="http://camel.apache.org/exchange-pattern.html">ExchangePattern:</a>
591 * set the exchange's ExchangePattern {@link ExchangePattern} to be InOnly
592 *
593 *
594 * @return the builder
595 */
596 public Type inOnly() {
597 return setExchangePattern(ExchangePattern.InOnly);
598 }
599
600 /**
601 * Sends the message to the given endpoint using an
602 * <a href="http://camel.apache.org/event-message.html">Event Message</a> or
603 * <a href="http://camel.apache.org/exchange-pattern.html">InOnly exchange pattern</a>
604 *
605 * @param uri The endpoint uri which is used for sending the exchange
606 * @return the builder
607 */
608 public Type inOnly(String uri) {
609 return to(ExchangePattern.InOnly, uri);
610 }
611
612 /**
613 * Sends the message to the given endpoint using an
614 * <a href="http://camel.apache.org/event-message.html">Event Message</a> or
615 * <a href="http://camel.apache.org/exchange-pattern.html">InOnly exchange pattern</a>
616 *
617 * @param endpoint The endpoint which is used for sending the exchange
618 * @return the builder
619 */
620 public Type inOnly(Endpoint endpoint) {
621 return to(ExchangePattern.InOnly, endpoint);
622 }
623
624
625 /**
626 * Sends the message to the given endpoints using an
627 * <a href="http://camel.apache.org/event-message.html">Event Message</a> or
628 * <a href="http://camel.apache.org/exchange-pattern.html">InOnly exchange pattern</a>
629 *
630 * @param uris list of endpoints to send to
631 * @return the builder
632 */
633 public Type inOnly(String... uris) {
634 return to(ExchangePattern.InOnly, uris);
635 }
636
637
638 /**
639 * Sends the message to the given endpoints using an
640 * <a href="http://camel.apache.org/event-message.html">Event Message</a> or
641 * <a href="http://camel.apache.org/exchange-pattern.html">InOnly exchange pattern</a>
642 *
643 * @param endpoints list of endpoints to send to
644 * @return the builder
645 */
646 public Type inOnly(Endpoint... endpoints) {
647 return to(ExchangePattern.InOnly, endpoints);
648 }
649
650 /**
651 * Sends the message to the given endpoints using an
652 * <a href="http://camel.apache.org/event-message.html">Event Message</a> or
653 * <a href="http://camel.apache.org/exchange-pattern.html">InOnly exchange pattern</a>
654 *
655 * @param endpoints list of endpoints to send to
656 * @return the builder
657 */
658 public Type inOnly(Iterable<Endpoint> endpoints) {
659 return to(ExchangePattern.InOnly, endpoints);
660 }
661
662
663 /**
664 * <a href="http://camel.apache.org/exchange-pattern.html">ExchangePattern:</a>
665 * set the exchange's ExchangePattern {@link ExchangePattern} to be InOut
666 *
667 *
668 * @return the builder
669 */
670 public Type inOut() {
671 return setExchangePattern(ExchangePattern.InOut);
672 }
673
674 /**
675 * Sends the message to the given endpoint using an
676 * <a href="http://camel.apache.org/request-reply.html">Request Reply</a> or
677 * <a href="http://camel.apache.org/exchange-pattern.html">InOut exchange pattern</a>
678 *
679 * @param uri The endpoint uri which is used for sending the exchange
680 * @return the builder
681 */
682 public Type inOut(String uri) {
683 return to(ExchangePattern.InOut, uri);
684 }
685
686
687 /**
688 * Sends the message to the given endpoint using an
689 * <a href="http://camel.apache.org/request-reply.html">Request Reply</a> or
690 * <a href="http://camel.apache.org/exchange-pattern.html">InOut exchange pattern</a>
691 *
692 * @param endpoint The endpoint which is used for sending the exchange
693 * @return the builder
694 */
695 public Type inOut(Endpoint endpoint) {
696 return to(ExchangePattern.InOut, endpoint);
697 }
698
699 /**
700 * Sends the message to the given endpoints using an
701 * <a href="http://camel.apache.org/request-reply.html">Request Reply</a> or
702 * <a href="http://camel.apache.org/exchange-pattern.html">InOut exchange pattern</a>
703 *
704 * @param uris list of endpoints to send to
705 * @return the builder
706 */
707 public Type inOut(String... uris) {
708 return to(ExchangePattern.InOut, uris);
709 }
710
711
712 /**
713 * Sends the message to the given endpoints using an
714 * <a href="http://camel.apache.org/request-reply.html">Request Reply</a> or
715 * <a href="http://camel.apache.org/exchange-pattern.html">InOut exchange pattern</a>
716 *
717 * @param endpoints list of endpoints to send to
718 * @return the builder
719 */
720 public Type inOut(Endpoint... endpoints) {
721 return to(ExchangePattern.InOut, endpoints);
722 }
723
724 /**
725 * Sends the message to the given endpoints using an
726 * <a href="http://camel.apache.org/request-reply.html">Request Reply</a> or
727 * <a href="http://camel.apache.org/exchange-pattern.html">InOut exchange pattern</a>
728 *
729 * @param endpoints list of endpoints to send to
730 * @return the builder
731 */
732 public Type inOut(Iterable<Endpoint> endpoints) {
733 return to(ExchangePattern.InOut, endpoints);
734 }
735
736 /**
737 * Sets the id of this node
738 *
739 * @param id the id
740 * @return the builder
741 */
742 @SuppressWarnings("unchecked")
743 public Type id(String id) {
744 if (getOutputs().isEmpty()) {
745 // set id on this
746 setId(id);
747 } else {
748 // set it on last output as this is what the user means to do
749 getOutputs().get(getOutputs().size() - 1).setId(id);
750 }
751
752 return (Type) this;
753 }
754
755 /**
756 * Set the route id for this route
757 *
758 * @param id the route id
759 * @return the builder
760 */
761 @SuppressWarnings("unchecked")
762 public Type routeId(String id) {
763 ProcessorDefinition def = this;
764
765 RouteDefinition route = ProcessorDefinitionHelper.getRoute(def);
766 if (route != null) {
767 route.setId(id);
768 }
769
770 return (Type) this;
771 }
772
773 /**
774 * <a href="http://camel.apache.org/multicast.html">Multicast EIP:</a>
775 * Multicasts messages to all its child outputs; so that each processor and
776 * destination gets a copy of the original message to avoid the processors
777 * interfering with each other.
778 *
779 * @return the builder
780 */
781 public MulticastDefinition multicast() {
782 MulticastDefinition answer = new MulticastDefinition();
783 addOutput(answer);
784 return answer;
785 }
786
787 /**
788 * <a href="http://camel.apache.org/multicast.html">Multicast EIP:</a>
789 * Multicasts messages to all its child outputs; so that each processor and
790 * destination gets a copy of the original message to avoid the processors
791 * interfering with each other.
792 *
793 * @param aggregationStrategy the strategy used to aggregate responses for
794 * every part
795 * @param parallelProcessing if is <tt>true</tt> camel will fork thread to call the endpoint producer
796 * @return the builder
797 */
798 public MulticastDefinition multicast(AggregationStrategy aggregationStrategy, boolean parallelProcessing) {
799 MulticastDefinition answer = new MulticastDefinition();
800 addOutput(answer);
801 answer.setAggregationStrategy(aggregationStrategy);
802 answer.setParallelProcessing(parallelProcessing);
803 return answer;
804 }
805
806 /**
807 * <a href="http://camel.apache.org/multicast.html">Multicast EIP:</a>
808 * Multicasts messages to all its child outputs; so that each processor and
809 * destination gets a copy of the original message to avoid the processors
810 * interfering with each other.
811 *
812 * @param aggregationStrategy the strategy used to aggregate responses for
813 * every part
814 * @return the builder
815 */
816 public MulticastDefinition multicast(AggregationStrategy aggregationStrategy) {
817 MulticastDefinition answer = new MulticastDefinition();
818 addOutput(answer);
819 answer.setAggregationStrategy(aggregationStrategy);
820 return answer;
821 }
822
823 /**
824 * <a href="http://camel.apache.org/pipes-nd-filters.html">Pipes and Filters EIP:</a>
825 * Creates a {@link Pipeline} so that the message
826 * will get processed by each endpoint in turn and for request/response the
827 * output of one endpoint will be the input of the next endpoint
828 *
829 * @return the builder
830 */
831 public PipelineDefinition pipeline() {
832 PipelineDefinition answer = new PipelineDefinition();
833 addOutput(answer);
834 return answer;
835 }
836
837 /**
838 * <a href="http://camel.apache.org/pipes-nd-filters.html">Pipes and Filters EIP:</a>
839 * Creates a {@link Pipeline} of the list of endpoints so that the message
840 * will get processed by each endpoint in turn and for request/response the
841 * output of one endpoint will be the input of the next endpoint
842 *
843 * @param uris list of endpoints
844 * @return the builder
845 */
846 public Type pipeline(String... uris) {
847 return to(uris);
848 }
849
850 /**
851 * <a href="http://camel.apache.org/pipes-nd-filters.html">Pipes and Filters EIP:</a>
852 * Creates a {@link Pipeline} of the list of endpoints so that the message
853 * will get processed by each endpoint in turn and for request/response the
854 * output of one endpoint will be the input of the next endpoint
855 *
856 * @param endpoints list of endpoints
857 * @return the builder
858 */
859 public Type pipeline(Endpoint... endpoints) {
860 return to(endpoints);
861 }
862
863 /**
864 * <a href="http://camel.apache.org/pipes-nd-filters.html">Pipes and Filters EIP:</a>
865 * Creates a {@link Pipeline} of the list of endpoints so that the message
866 * will get processed by each endpoint in turn and for request/response the
867 * output of one endpoint will be the input of the next endpoint
868 *
869 * @param endpoints list of endpoints
870 * @return the builder
871 */
872 public Type pipeline(Collection<Endpoint> endpoints) {
873 return to(endpoints);
874 }
875
876 /**
877 * Leverages a thread pool for multi threading processing exchanges.
878 * <p/>
879 * The caller thread will either wait for the async route
880 * to complete or imeddiately continue. If continue the OUT message will
881 * contain a {@link java.util.concurrent.Future} handle so you can get the real response
882 * later using this handle.
883 * <p/>
884 * Will default <tt>Always</tt> wait for the async route to complete, but this behavior can be overriden by:
885 * <ul>
886 * <li>Configuring the <tt>waitForTaskToComplete</tt> option</li>
887 * <li>Provide an IN header with the key {@link org.apache.camel.Exchange#ASYNC_WAIT} with the
888 * value containing a type {@link org.apache.camel.WaitForTaskToComplete}. The header will take precedence, if provided.</li>
889 * </ul>
890 *
891 * @return the builder
892 */
893 public ThreadsDefinition threads() {
894 ThreadsDefinition answer = new ThreadsDefinition();
895 addOutput(answer);
896 return answer;
897 }
898
899 /**
900 * Leverages a thread pool for multi threading processing exchanges.
901 * <p/>
902 * See {@link #threads()} for more details.
903 *
904 * @param poolSize the core pool size
905 * @return the builder
906 */
907 public ThreadsDefinition threads(int poolSize) {
908 ThreadsDefinition answer = threads();
909 answer.setPoolSize(poolSize);
910 return answer;
911 }
912
913 /**
914 * Wraps the sub route using AOP allowing you to do before and after work (AOP around).
915 *
916 * @return the builder
917 */
918 public AOPDefinition aop() {
919 AOPDefinition answer = new AOPDefinition();
920 addOutput(answer);
921 return answer;
922 }
923
924 /**
925 * Ends the current block
926 *
927 * @return the builder
928 */
929 @SuppressWarnings("unchecked")
930 public ProcessorDefinition end() {
931 // when using doTry .. doCatch .. doFinally we should always
932 // end the try definition to avoid having to use 2 x end() in the route
933 // this is counter intuitive for end users
934 ProcessorDefinition defn = (ProcessorDefinition) this;
935 if (defn instanceof TryDefinition) {
936 popBlock();
937 }
938
939 if (blocks.isEmpty()) {
940 if (parent == null) {
941 return this;
942 }
943 return parent;
944 }
945 popBlock();
946 return this;
947 }
948
949 /**
950 * <a href="http://camel.apache.org/idempotent-consumer.html">Idempotent consumer EIP:</a>
951 * Creates an {@link org.apache.camel.processor.idempotent.IdempotentConsumer IdempotentConsumer}
952 * to avoid duplicate messages
953 *
954 * @return the builder
955 */
956 public IdempotentConsumerDefinition idempotentConsumer() {
957 IdempotentConsumerDefinition answer = new IdempotentConsumerDefinition();
958 addOutput(answer);
959 return answer;
960 }
961
962 /**
963 * <a href="http://camel.apache.org/idempotent-consumer.html">Idempotent consumer EIP:</a>
964 * Creates an {@link org.apache.camel.processor.idempotent.IdempotentConsumer IdempotentConsumer}
965 * to avoid duplicate messages
966 *
967 * @param messageIdExpression expression to test of duplicate messages
968 * @param idempotentRepository the repository to use for duplicate chedck
969 * @return the builder
970 */
971 public IdempotentConsumerDefinition idempotentConsumer(Expression messageIdExpression, IdempotentRepository<?> idempotentRepository) {
972 IdempotentConsumerDefinition answer = new IdempotentConsumerDefinition(messageIdExpression, idempotentRepository);
973 addOutput(answer);
974 return answer;
975 }
976
977 /**
978 * <a href="http://camel.apache.org/idempotent-consumer.html">Idempotent consumer EIP:</a>
979 * Creates an {@link org.apache.camel.processor.idempotent.IdempotentConsumer IdempotentConsumer}
980 * to avoid duplicate messages
981 *
982 * @param idempotentRepository the repository to use for duplicate chedck
983 * @return the builder used to create the expression
984 */
985 public ExpressionClause<IdempotentConsumerDefinition> idempotentConsumer(IdempotentRepository<?> idempotentRepository) {
986 IdempotentConsumerDefinition answer = new IdempotentConsumerDefinition();
987 answer.setMessageIdRepository(idempotentRepository);
988 addOutput(answer);
989 return ExpressionClause.createAndSetExpression(answer);
990 }
991
992 /**
993 * <a href="http://camel.apache.org/message-filter.html">Message Filter EIP:</a>
994 * Creates a predicate expression which only if it is <tt>true</tt> then the
995 * exchange is forwarded to the destination
996 *
997 * @return the clause used to create the filter expression
998 */
999 public ExpressionClause<FilterDefinition> filter() {
1000 FilterDefinition filter = new FilterDefinition();
1001 addOutput(filter);
1002 return ExpressionClause.createAndSetExpression(filter);
1003 }
1004
1005 /**
1006 * <a href="http://camel.apache.org/message-filter.html">Message Filter EIP:</a>
1007 * Creates a predicate which is applied and only if it is <tt>true</tt> then the
1008 * exchange is forwarded to the destination
1009 *
1010 * @param predicate predicate to use
1011 * @return the builder
1012 */
1013 public FilterDefinition filter(Predicate predicate) {
1014 FilterDefinition filter = new FilterDefinition(predicate);
1015 addOutput(filter);
1016 return filter;
1017 }
1018
1019 /**
1020 * <a href="http://camel.apache.org/message-filter.html">Message Filter EIP:</a>
1021 * Creates a predicate expression which only if it is <tt>true</tt> then the
1022 * exchange is forwarded to the destination
1023 *
1024 * @param expression the predicate expression to use
1025 * @return the builder
1026 */
1027 public FilterDefinition filter(ExpressionDefinition expression) {
1028 FilterDefinition filter = getNodeFactory().createFilter();
1029 filter.setExpression(expression);
1030 addOutput(filter);
1031 return filter;
1032 }
1033
1034 /**
1035 * <a href="http://camel.apache.org/message-filter.html">Message Filter EIP:</a>
1036 * Creates a predicate language expression which only if it is <tt>true</tt> then the
1037 * exchange is forwarded to the destination
1038 *
1039 * @param language language for expression
1040 * @param expression the expression
1041 * @return the builder
1042 */
1043 public FilterDefinition filter(String language, String expression) {
1044 return filter(new LanguageExpression(language, expression));
1045 }
1046
1047 /**
1048 * <a href="http://camel.apache.org/load-balancer.html">Load Balancer EIP:</a>
1049 * Creates a loadbalance
1050 *
1051 * @return the builder
1052 */
1053 public LoadBalanceDefinition loadBalance() {
1054 LoadBalanceDefinition answer = new LoadBalanceDefinition();
1055 addOutput(answer);
1056 return answer;
1057 }
1058
1059 /**
1060 * <a href="http://camel.apache.org/load-balancer.html">Load Balancer EIP:</a>
1061 * Creates a loadbalance
1062 *
1063 * @param loadBalancer a custom load balancer to use
1064 * @return the builder
1065 */
1066 public LoadBalanceDefinition loadBalance(LoadBalancer loadBalancer) {
1067 LoadBalanceDefinition answer = new LoadBalanceDefinition();
1068 addOutput(answer);
1069 return answer.loadBalance(loadBalancer);
1070 }
1071
1072 /**
1073 * Creates a log message to be logged at INFO level.
1074 *
1075 * @param message the log message, (you can use {@link org.apache.camel.language.simple.SimpleLanguage} syntax)
1076 * @return the builder
1077 */
1078 @SuppressWarnings("unchecked")
1079 public Type log(String message) {
1080 LogDefinition answer = new LogDefinition(message);
1081 addOutput(answer);
1082 return (Type) this;
1083 }
1084
1085 /**
1086 * Creates a log message to be logged at the given level.
1087 *
1088 * @param loggingLevel the logging level to use
1089 * @param message the log message, (you can use {@link org.apache.camel.language.simple.SimpleLanguage} syntax)
1090 * @return the builder
1091 */
1092 @SuppressWarnings("unchecked")
1093 public Type log(LoggingLevel loggingLevel, String message) {
1094 LogDefinition answer = new LogDefinition(message);
1095 answer.setLoggingLevel(loggingLevel);
1096 addOutput(answer);
1097 return (Type) this;
1098 }
1099
1100 /**
1101 * Creates a log message to be logged at the given level and name.
1102 *
1103 * @param loggingLevel the logging level to use
1104 * @param logName the log name to use
1105 * @param message the log message, (you can use {@link org.apache.camel.language.simple.SimpleLanguage} syntax)
1106 * @return the builder
1107 */
1108 @SuppressWarnings("unchecked")
1109 public Type log(LoggingLevel loggingLevel, String logName, String message) {
1110 LogDefinition answer = new LogDefinition(message);
1111 answer.setLoggingLevel(loggingLevel);
1112 answer.setLogName(logName);
1113 addOutput(answer);
1114 return (Type) this;
1115 }
1116
1117 /**
1118 * <a href="http://camel.apache.org/content-based-router.html">Content Based Router EIP:</a>
1119 * Creates a choice of one or more predicates with an otherwise clause
1120 *
1121 * @return the builder for a choice expression
1122 */
1123 public ChoiceDefinition choice() {
1124 ChoiceDefinition answer = new ChoiceDefinition();
1125 addOutput(answer);
1126 return answer;
1127 }
1128
1129 /**
1130 * Creates a try/catch block
1131 *
1132 * @return the builder for a tryBlock expression
1133 */
1134 public TryDefinition doTry() {
1135 TryDefinition answer = new TryDefinition();
1136 addOutput(answer);
1137 return answer;
1138 }
1139
1140 /**
1141 * <a href="http://camel.apache.org/recipient-list.html">Recipient List EIP:</a>
1142 * Creates a dynamic recipient list allowing you to route messages to a number of dynamically specified recipients.
1143 * <p/>
1144 * Will use comma as default delimiter.
1145 *
1146 * @param recipients expression to decide the destinations
1147 * @return the builder
1148 */
1149 @SuppressWarnings("unchecked")
1150 public RecipientListDefinition recipientList(Expression recipients) {
1151 RecipientListDefinition answer = new RecipientListDefinition(recipients);
1152 addOutput(answer);
1153 return answer;
1154 }
1155
1156 /**
1157 * <a href="http://camel.apache.org/recipient-list.html">Recipient List EIP:</a>
1158 * Creates a dynamic recipient list allowing you to route messages to a number of dynamically specified recipients
1159 *
1160 * @param recipients expression to decide the destinations
1161 * @param delimiter a custom delimiter to use
1162 * @return the builder
1163 */
1164 @SuppressWarnings("unchecked")
1165 public RecipientListDefinition recipientList(Expression recipients, String delimiter) {
1166 RecipientListDefinition answer = new RecipientListDefinition(recipients);
1167 answer.setDelimiter(delimiter);
1168 addOutput(answer);
1169 return answer;
1170 }
1171
1172 /**
1173 * <a href="http://camel.apache.org/recipient-list.html">Recipient List EIP:</a>
1174 * Creates a dynamic recipient list allowing you to route messages to a number of dynamically specified recipients
1175 *
1176 * @return the expression clause to configure the expression to decide the destinations
1177 */
1178 public ExpressionClause<RecipientListDefinition> recipientList() {
1179 RecipientListDefinition answer = new RecipientListDefinition();
1180 addOutput(answer);
1181 return ExpressionClause.createAndSetExpression(answer);
1182 }
1183
1184 /**
1185 * <a href="http://camel.apache.org/routing-slip.html">Routing Slip EIP:</a>
1186 * Creates a routing slip allowing you to route a message consecutively through a series of processing
1187 * steps where the sequence of steps is not known at design time and can vary for each message.
1188 *
1189 * @param header is the header that the {@link org.apache.camel.processor.RoutingSlip RoutingSlip}
1190 * class will look in for the list of URIs to route the message to.
1191 * @param uriDelimiter is the delimiter that will be used to split up
1192 * the list of URIs in the routing slip.
1193 * @return the builder
1194 */
1195 @SuppressWarnings("unchecked")
1196 public Type routingSlip(String header, String uriDelimiter) {
1197 RoutingSlipDefinition answer = new RoutingSlipDefinition(header, uriDelimiter);
1198 addOutput(answer);
1199 return (Type) this;
1200 }
1201
1202 /**
1203 * <a href="http://camel.apache.org/routing-slip.html">Routing Slip EIP:</a>
1204 * Creates a routing slip allowing you to route a message consecutively through a series of processing
1205 * steps where the sequence of steps is not known at design time and can vary for each message.
1206 * <p>
1207 * The list of URIs will be split based on the default delimiter {@link RoutingSlipDefinition#DEFAULT_DELIMITER}
1208 *
1209 * @param header is the header that the {@link org.apache.camel.processor.RoutingSlip RoutingSlip}
1210 * class will look in for the list of URIs to route the message to.
1211 * @return the builder
1212 */
1213 @SuppressWarnings("unchecked")
1214 public Type routingSlip(String header) {
1215 RoutingSlipDefinition answer = new RoutingSlipDefinition(header);
1216 addOutput(answer);
1217 return (Type) this;
1218 }
1219
1220 /**
1221 * <a href="http://camel.apache.org/sampling.html">Sampling Throttler</a>
1222 * Creates a sampling throttler allowing you to extract a sample of
1223 * exchanges from the traffic on a route. It is configured with a sampling
1224 * period, during which only a single exchange is allowed to pass through.
1225 * All other exchanges will be stopped.
1226 * <p/>
1227 * Default period is one second.
1228 *
1229 * @return the builder
1230 */
1231 public SamplingDefinition sample() {
1232 return sample(1, TimeUnit.SECONDS);
1233 }
1234
1235 /**
1236 * <a href="http://camel.apache.org/sampling.html">Sampling Throttler</a>
1237 * Creates a sampling throttler allowing you to extract a sample of exchanges
1238 * from the traffic through a route. It is configured with a sampling period
1239 * during which only a single exchange is allowed to pass through.
1240 * All other exchanges will be stopped.
1241 *
1242 * @param samplePeriod this is the sample interval, only one exchange is
1243 * allowed through in this interval
1244 * @param unit this is the units for the samplePeriod e.g. Seconds
1245 * @return the builder
1246 */
1247 public SamplingDefinition sample(long samplePeriod, TimeUnit unit) {
1248 SamplingDefinition answer = new SamplingDefinition(samplePeriod, unit);
1249 addOutput(answer);
1250 return answer;
1251 }
1252
1253 /**
1254 * <a href="http://camel.apache.org/splitter.html">Splitter EIP:</a>
1255 * Creates a splitter allowing you split a message into a number of pieces and process them individually.
1256 * <p>
1257 * This splitter responds with the latest message returned from destination
1258 * endpoint.
1259 *
1260 * @return the expression clause builder for the expression on which to split
1261 */
1262 public ExpressionClause<SplitDefinition> split() {
1263 SplitDefinition answer = new SplitDefinition();
1264 addOutput(answer);
1265 return ExpressionClause.createAndSetExpression(answer);
1266 }
1267
1268 /**
1269 * <a href="http://camel.apache.org/splitter.html">Splitter EIP:</a>
1270 * Creates a splitter allowing you split a message into a number of pieces and process them individually.
1271 * <p>
1272 * This splitter responds with the latest message returned from destination
1273 * endpoint.
1274 *
1275 * @param expression the expression on which to split the message
1276 * @return the builder
1277 */
1278 public SplitDefinition split(Expression expression) {
1279 SplitDefinition answer = new SplitDefinition(expression);
1280 addOutput(answer);
1281 return answer;
1282 }
1283
1284 /**
1285 * <a href="http://camel.apache.org/splitter.html">Splitter EIP:</a>
1286 * Creates a splitter allowing you split a message into a number of pieces and process them individually.
1287 * <p>
1288 * The splitter responds with the answer produced by the given {@link AggregationStrategy}.
1289 *
1290 * @param expression the expression on which to split
1291 * @param aggregationStrategy the strategy used to aggregate responses for every part
1292 * @return the builder
1293 */
1294 public SplitDefinition split(Expression expression, AggregationStrategy aggregationStrategy) {
1295 SplitDefinition answer = new SplitDefinition(expression);
1296 addOutput(answer);
1297 answer.setAggregationStrategy(aggregationStrategy);
1298 return answer;
1299 }
1300
1301 /**
1302 * <a href="http://camel.apache.org/resequencer.html">Resequencer EIP:</a>
1303 * Creates a resequencer allowing you to reorganize messages based on some comparator.
1304 *
1305 * @return the expression clause for the expressions on which to compare messages in order
1306 */
1307 public ExpressionClause<ResequenceDefinition> resequence() {
1308 ResequenceDefinition answer = new ResequenceDefinition();
1309 addOutput(answer);
1310 ExpressionClause<ResequenceDefinition> clause = new ExpressionClause<ResequenceDefinition>(answer);
1311 answer.expression(clause);
1312 return clause;
1313 }
1314
1315 /**
1316 * <a href="http://camel.apache.org/resequencer.html">Resequencer EIP:</a>
1317 * Creates a resequencer allowing you to reorganize messages based on some comparator.
1318 *
1319 * @param expression the expression on which to compare messages in order
1320 * @return the builder
1321 */
1322 public ResequenceDefinition resequence(Expression expression) {
1323 return resequence(Collections.<Expression>singletonList(expression));
1324 }
1325
1326 /**
1327 * <a href="http://camel.apache.org/resequencer.html">Resequencer EIP:</a>
1328 * Creates a resequencer allowing you to reorganize messages based on some comparator.
1329 *
1330 * @param expressions the list of expressions on which to compare messages in order
1331 * @return the builder
1332 */
1333 public ResequenceDefinition resequence(List<Expression> expressions) {
1334 ResequenceDefinition answer = new ResequenceDefinition(expressions);
1335 addOutput(answer);
1336 return answer;
1337 }
1338
1339 /**
1340 * <a href="http://camel.apache.org/resequencer.html">Resequencer EIP:</a>
1341 * Creates a splitter allowing you to reorganise messages based on some comparator.
1342 *
1343 * @param expressions the list of expressions on which to compare messages in order
1344 * @return the builder
1345 */
1346 public ResequenceDefinition resequencer(Expression... expressions) {
1347 List<Expression> list = new ArrayList<Expression>();
1348 list.addAll(Arrays.asList(expressions));
1349 return resequence(list);
1350 }
1351
1352 /**
1353 * <a href="http://camel.apache.org/aggregator.html">Aggregator EIP:</a>
1354 * Creates an aggregator allowing you to combine a number of messages together into a single message.
1355 *
1356 * @return the expression clause to be used as builder to configure the correlation expression
1357 */
1358 public ExpressionClause<AggregateDefinition> aggregate() {
1359 AggregateDefinition answer = new AggregateDefinition();
1360 addOutput(answer);
1361 return answer.createAndSetExpression();
1362 }
1363
1364 /**
1365 * <a href="http://camel.apache.org/aggregator.html">Aggregator EIP:</a>
1366 * Creates an aggregator allowing you to combine a number of messages together into a single message.
1367 *
1368 * @param aggregationStrategy the strategy used for the aggregation
1369 * @return the expression clause to be used as builder to configure the correlation expression
1370 */
1371 public ExpressionClause<AggregateDefinition> aggregate(AggregationStrategy aggregationStrategy) {
1372 AggregateDefinition answer = new AggregateDefinition();
1373 answer.setAggregationStrategy(aggregationStrategy);
1374 addOutput(answer);
1375 return answer.createAndSetExpression();
1376 }
1377
1378 /**
1379 * <a href="http://camel.apache.org/aggregator.html">Aggregator EIP:</a>
1380 * Creates an aggregator allowing you to combine a number of messages together into a single message.
1381 *
1382 * @param aggregationCollection the collection used to perform the aggregation
1383 * @return the builder
1384 */
1385 public AggregateDefinition aggregate(AggregationCollection aggregationCollection) {
1386 AggregateDefinition answer = new AggregateDefinition();
1387 answer.setAggregationCollection(aggregationCollection);
1388 addOutput(answer);
1389 return answer;
1390 }
1391
1392 /**
1393 * <a href="http://camel.apache.org/aggregator.html">Aggregator EIP:</a>
1394 * Creates an aggregator allowing you to combine a number of messages together into a single message.
1395 *
1396 * @param correlationExpression the expression used to calculate the
1397 * correlation key. For a JMS message this could be the
1398 * expression <code>header("JMSDestination")</code> or
1399 * <code>header("JMSCorrelationID")</code>
1400 * @return the builder
1401 */
1402 public AggregateDefinition aggregate(Expression correlationExpression) {
1403 AggregateDefinition answer = new AggregateDefinition(correlationExpression);
1404 addOutput(answer);
1405 return answer;
1406 }
1407
1408 /**
1409 * <a href="http://camel.apache.org/aggregator.html">Aggregator EIP:</a>
1410 * Creates an aggregator allowing you to combine a number of messages together into a single message.
1411 *
1412 * @param correlationExpression the expression used to calculate the
1413 * correlation key. For a JMS message this could be the
1414 * expression <code>header("JMSDestination")</code> or
1415 * <code>header("JMSCorrelationID")</code>
1416 * @param aggregationStrategy the strategy used for the aggregation
1417 * @return the builder
1418 */
1419 public AggregateDefinition aggregate(Expression correlationExpression, AggregationStrategy aggregationStrategy) {
1420 AggregateDefinition answer = new AggregateDefinition(correlationExpression, aggregationStrategy);
1421 addOutput(answer);
1422 return answer;
1423 }
1424
1425 /**
1426 * <a href="http://camel.apache.org/delayer.html">Delayer EIP:</a>
1427 * Creates a delayer allowing you to delay the delivery of messages to some destination.
1428 *
1429 * @param delay an expression to calculate the delay time in millis
1430 * @return the builder
1431 */
1432 public DelayDefinition delay(Expression delay) {
1433 DelayDefinition answer = new DelayDefinition(delay);
1434 addOutput(answer);
1435 return answer;
1436 }
1437
1438 /**
1439 * <a href="http://camel.apache.org/delayer.html">Delayer EIP:</a>
1440 * Creates a delayer allowing you to delay the delivery of messages to some destination.
1441 *
1442 * @return the expression clause to create the expression
1443 */
1444 public ExpressionClause<DelayDefinition> delay() {
1445 DelayDefinition answer = new DelayDefinition();
1446 addOutput(answer);
1447 return ExpressionClause.createAndSetExpression(answer);
1448 }
1449
1450 /**
1451 * <a href="http://camel.apache.org/delayer.html">Delayer EIP:</a>
1452 * Creates a delayer allowing you to delay the delivery of messages to some destination.
1453 *
1454 * @param delay the delay in millis
1455 * @return the builder
1456 */
1457 public DelayDefinition delay(long delay) {
1458 return delay(ExpressionBuilder.constantExpression(delay));
1459 }
1460
1461 /**
1462 * <a href="http://camel.apache.org/throttler.html">Throttler EIP:</a>
1463 * Creates a throttler allowing you to ensure that a specific endpoint does not get overloaded,
1464 * or that we don't exceed an agreed SLA with some external service.
1465 * <p/>
1466 * Will default use a time period of 1 second, so setting the maximumRequestCount to eg 10
1467 * will default ensure at most 10 messages per second.
1468 *
1469 * @param maximumRequestCount the maximum messages
1470 * @return the builder
1471 */
1472 public ThrottleDefinition throttle(long maximumRequestCount) {
1473 ThrottleDefinition answer = new ThrottleDefinition(maximumRequestCount);
1474 addOutput(answer);
1475 return answer;
1476 }
1477
1478 /**
1479 * <a href="http://camel.apache.org/loop.html">Loop EIP:</a>
1480 * Creates a loop allowing to process the a message a number of times and possibly process them
1481 * in a different way. Useful mostly for testing.
1482 *
1483 * @return the clause used to create the loop expression
1484 */
1485 public ExpressionClause<LoopDefinition> loop() {
1486 LoopDefinition loop = new LoopDefinition();
1487 addOutput(loop);
1488 return ExpressionClause.createAndSetExpression(loop);
1489 }
1490
1491 /**
1492 * <a href="http://camel.apache.org/loop.html">Loop EIP:</a>
1493 * Creates a loop allowing to process the a message a number of times and possibly process them
1494 * in a different way. Useful mostly for testing.
1495 *
1496 * @param expression the loop expression
1497 * @return the builder
1498 */
1499 public LoopDefinition loop(Expression expression) {
1500 LoopDefinition loop = getNodeFactory().createLoop();
1501 loop.setExpression(expression);
1502 addOutput(loop);
1503 return loop;
1504 }
1505
1506 /**
1507 * <a href="http://camel.apache.org/loop.html">Loop EIP:</a>
1508 * Creates a loop allowing to process the a message a number of times and possibly process them
1509 * in a different way. Useful mostly for testing.
1510 *
1511 * @param count the number of times
1512 * @return the builder
1513 */
1514 public LoopDefinition loop(int count) {
1515 LoopDefinition loop = getNodeFactory().createLoop();
1516 loop.setExpression(new ConstantExpression(Integer.toString(count)));
1517 addOutput(loop);
1518 return loop;
1519 }
1520
1521 /**
1522 * Sets the exception on the {@link org.apache.camel.Exchange}
1523 *
1524 * @param exception the exception to throw
1525 * @return the builder
1526 */
1527 @SuppressWarnings("unchecked")
1528 public Type throwException(Exception exception) {
1529 ThrowExceptionDefinition answer = new ThrowExceptionDefinition();
1530 answer.setException(exception);
1531 addOutput(answer);
1532 return (Type) this;
1533 }
1534
1535 /**
1536 * Marks the exchange for rollback only.
1537 * <p/>
1538 * Does <b>not</b> set any exception as opposed to {@link #rollback()} methods.
1539 *
1540 * @return the builder
1541 * @see #rollback()
1542 * @see #rollback(String)
1543 * @see #markRollbackOnlyLast()
1544 */
1545 @SuppressWarnings("unchecked")
1546 public Type markRollbackOnly() {
1547 RollbackDefinition answer = new RollbackDefinition();
1548 answer.setMarkRollbackOnly(true);
1549 addOutput(answer);
1550 return (Type) this;
1551 }
1552
1553 /**
1554 * Marks the exchange for rollback only, but only for the last (current) transaction.
1555 * <p/>
1556 * A last rollback is used when you have nested transactions and only want the last local transaction to rollback,
1557 * where as the outer transaction can still be completed
1558 * <p/>
1559 * Does <b>not</b> set any exception as opposed to {@link #rollback()} methods.
1560 *
1561 * @return the builder
1562 * @see #rollback()
1563 * @see #rollback(String)
1564 * @see #markRollbackOnly()
1565 */
1566 @SuppressWarnings("unchecked")
1567 public Type markRollbackOnlyLast() {
1568 RollbackDefinition answer = new RollbackDefinition();
1569 answer.setMarkRollbackOnlyLast(true);
1570 addOutput(answer);
1571 return (Type) this;
1572 }
1573
1574 /**
1575 * Marks the exchange for rollback only and sets an exception with a default message.
1576 * <p/>
1577 * This is done by setting a {@link org.apache.camel.RollbackExchangeException} on the Exchange
1578 * and mark it for rollback.
1579 *
1580 * @return the builder
1581 * @see #markRollbackOnly()
1582 */
1583 @SuppressWarnings("unchecked")
1584 public Type rollback() {
1585 return rollback(null);
1586 }
1587
1588 /**
1589 * Marks the exchange for rollback and sets an exception with the provided message.
1590 * <p/>
1591 * This is done by setting a {@link org.apache.camel.RollbackExchangeException} on the Exchange
1592 * and mark it for rollback.
1593 *
1594 * @param message an optional message used for logging purpose why the rollback was triggered
1595 * @return the builder
1596 * @see #markRollbackOnly()
1597 */
1598 @SuppressWarnings("unchecked")
1599 public Type rollback(String message) {
1600 RollbackDefinition answer = new RollbackDefinition(message);
1601 addOutput(answer);
1602 return (Type) this;
1603 }
1604
1605 /**
1606 * <a href="http://camel.apache.org/wiretap.html">WireTap EIP:</a>
1607 * Sends messages to all its child outputs; so that each processor and
1608 * destination gets a copy of the original message to avoid the processors
1609 * interfering with each other using {@link ExchangePattern#InOnly}.
1610 *
1611 * @return the builder
1612 */
1613 @SuppressWarnings("unchecked")
1614 public Type wireTap(String uri) {
1615 WireTapDefinition answer = new WireTapDefinition();
1616 answer.setUri(uri);
1617 addOutput(answer);
1618 return (Type) this;
1619 }
1620
1621 /**
1622 * <a href="http://camel.apache.org/wiretap.html">WireTap EIP:</a>
1623 * Sends a new {@link org.apache.camel.Exchange} to the destination
1624 * using {@link ExchangePattern#InOnly}.
1625 *
1626 * @param uri the destination
1627 * @param body expression that creates the body to send
1628 * @return the builder
1629 */
1630 @SuppressWarnings("unchecked")
1631 public Type wireTap(String uri, Expression body) {
1632 WireTapDefinition answer = new WireTapDefinition();
1633 answer.setUri(uri);
1634 answer.setNewExchangeExpression(body);
1635 addOutput(answer);
1636 return (Type) this;
1637 }
1638
1639 /**
1640 * <a href="http://camel.apache.org/wiretap.html">WireTap EIP:</a>
1641 * Sends a new {@link org.apache.camel.Exchange} to the destination
1642 * using {@link ExchangePattern#InOnly}.
1643 *
1644 * @param uri the destination
1645 * @param processor processor preparing the new exchange to send
1646 * @return the builder
1647 */
1648 @SuppressWarnings("unchecked")
1649 public Type wireTap(String uri, Processor processor) {
1650 WireTapDefinition answer = new WireTapDefinition();
1651 answer.setUri(uri);
1652 answer.setNewExchangeProcessor(processor);
1653 addOutput(answer);
1654 return (Type) this;
1655 }
1656
1657 /**
1658 * Pushes the given block on the stack as current block
1659 * @param block the block
1660 */
1661 void pushBlock(Block block) {
1662 blocks.add(block);
1663 }
1664
1665 /**
1666 * Pops the block off the stack as current block
1667 * @return the block
1668 */
1669 Block popBlock() {
1670 return blocks.isEmpty() ? null : blocks.removeLast();
1671 }
1672
1673 /**
1674 * Stops continue routing the current {@link org.apache.camel.Exchange} and marks it as completed.
1675 *
1676 * @return the builder
1677 */
1678 @SuppressWarnings("unchecked")
1679 public Type stop() {
1680 StopDefinition stop = new StopDefinition();
1681 addOutput(stop);
1682 return (Type) this;
1683 }
1684
1685 /**
1686 * <a href="http://camel.apache.org/exception-clause.html">Exception clause</a>
1687 * for cathing certain exceptions and handling them.
1688 *
1689 * @param exceptionType the exception to catch
1690 * @return the exception builder to configure
1691 */
1692 public OnExceptionDefinition onException(Class exceptionType) {
1693 OnExceptionDefinition answer = new OnExceptionDefinition(exceptionType);
1694 addOutput(answer);
1695 return answer;
1696 }
1697
1698 /**
1699 * Apply a {@link Policy}.
1700 * <p/>
1701 * Policy can be used for transactional policies.
1702 *
1703 * @param policy the policy to apply
1704 * @return the policy builder to configure
1705 */
1706 public PolicyDefinition policy(Policy policy) {
1707 PolicyDefinition answer = new PolicyDefinition(policy);
1708 addOutput(answer);
1709 return answer;
1710 }
1711
1712 /**
1713 * Apply a {@link Policy}.
1714 * <p/>
1715 * Policy can be used for transactional policies.
1716 *
1717 * @param ref reference to lookup a policy in the registry
1718 * @return the policy builder to configure
1719 */
1720 public PolicyDefinition policy(String ref) {
1721 PolicyDefinition answer = new PolicyDefinition();
1722 answer.setRef(ref);
1723 addOutput(answer);
1724 return answer;
1725 }
1726
1727 /**
1728 * Marks this route as transacted and uses the default transacted policy found in the registry.
1729 *
1730 * @return the policy builder to configure
1731 */
1732 public PolicyDefinition transacted() {
1733 PolicyDefinition answer = new PolicyDefinition();
1734 answer.setType(TransactedPolicy.class);
1735 addOutput(answer);
1736 return answer;
1737 }
1738
1739 /**
1740 * Marks this route as transacted.
1741 *
1742 * @param ref reference to lookup a transacted policy in the registry
1743 * @return the policy builder to configure
1744 */
1745 public PolicyDefinition transacted(String ref) {
1746 PolicyDefinition answer = new PolicyDefinition();
1747 answer.setType(TransactedPolicy.class);
1748 answer.setRef(ref);
1749 addOutput(answer);
1750 return answer;
1751 }
1752
1753 // Transformers
1754 // -------------------------------------------------------------------------
1755
1756 /**
1757 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
1758 * Adds the custom processor to this destination which could be a final
1759 * destination, or could be a transformation in a pipeline
1760 *
1761 * @param processor the custom {@link Processor}
1762 * @return the builder
1763 */
1764 @SuppressWarnings("unchecked")
1765 public Type process(Processor processor) {
1766 ProcessDefinition answer = new ProcessDefinition(processor);
1767 addOutput(answer);
1768 return (Type) this;
1769 }
1770
1771 /**
1772 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
1773 * Adds the custom processor reference to this destination which could be a final
1774 * destination, or could be a transformation in a pipeline
1775 *
1776 * @param ref reference to a {@link Processor} to lookup in the registry
1777 * @return the builder
1778 */
1779 @SuppressWarnings("unchecked")
1780 public Type processRef(String ref) {
1781 ProcessDefinition answer = new ProcessDefinition();
1782 answer.setRef(ref);
1783 addOutput(answer);
1784 return (Type) this;
1785 }
1786
1787 /**
1788 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
1789 * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
1790 *
1791 * @param bean the bean to invoke
1792 * @return the builder
1793 */
1794 @SuppressWarnings("unchecked")
1795 public Type bean(Object bean) {
1796 BeanDefinition answer = new BeanDefinition();
1797 answer.setBean(bean);
1798 addOutput(answer);
1799 return (Type) this;
1800 }
1801
1802 /**
1803 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
1804 * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
1805 *
1806 * @param bean the bean to invoke
1807 * @param method the method name to invoke on the bean (can be used to avoid ambiguty)
1808 * @return the builder
1809 */
1810 @SuppressWarnings("unchecked")
1811 public Type bean(Object bean, String method) {
1812 BeanDefinition answer = new BeanDefinition();
1813 answer.setBean(bean);
1814 answer.setMethod(method);
1815 addOutput(answer);
1816 return (Type) this;
1817 }
1818
1819 /**
1820 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
1821 * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
1822 *
1823 * @param beanType the bean class, Camel will instantiate an object at runtime
1824 * @return the builder
1825 */
1826 @SuppressWarnings("unchecked")
1827 public Type bean(Class beanType) {
1828 BeanDefinition answer = new BeanDefinition();
1829 answer.setBeanType(beanType);
1830 addOutput(answer);
1831 return (Type) this;
1832 }
1833
1834 /**
1835 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
1836 * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
1837 *
1838 * @param beanType the bean class, Camel will instantiate an object at runtime
1839 * @param method the method name to invoke on the bean (can be used to avoid ambiguty)
1840 * @return the builder
1841 */
1842 @SuppressWarnings("unchecked")
1843 public Type bean(Class beanType, String method) {
1844 BeanDefinition answer = new BeanDefinition();
1845 answer.setBeanType(beanType);
1846 answer.setMethod(method);
1847 addOutput(answer);
1848 return (Type) this;
1849 }
1850
1851 /**
1852 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
1853 * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
1854 *
1855 * @param ref reference to a bean to lookup in the registry
1856 * @return the builder
1857 */
1858 @SuppressWarnings("unchecked")
1859 public Type beanRef(String ref) {
1860 BeanDefinition answer = new BeanDefinition(ref);
1861 addOutput(answer);
1862 return (Type) this;
1863 }
1864
1865 /**
1866 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
1867 * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
1868 *
1869 * @param ref reference to a bean to lookup in the registry
1870 * @param method the method name to invoke on the bean (can be used to avoid ambiguty)
1871 * @return the builder
1872 */
1873 @SuppressWarnings("unchecked")
1874 public Type beanRef(String ref, String method) {
1875 BeanDefinition answer = new BeanDefinition(ref, method);
1876 addOutput(answer);
1877 return (Type) this;
1878 }
1879
1880 /**
1881 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
1882 * Adds a processor which sets the body on the IN message
1883 *
1884 * @return a expression builder clause to set the body
1885 */
1886 public ExpressionClause<ProcessorDefinition<Type>> setBody() {
1887 ExpressionClause<ProcessorDefinition<Type>> clause = new ExpressionClause<ProcessorDefinition<Type>>(this);
1888 SetBodyDefinition answer = new SetBodyDefinition(clause);
1889 addOutput(answer);
1890 return clause;
1891 }
1892
1893 /**
1894 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
1895 * Adds a processor which sets the body on the IN message
1896 *
1897 * @param expression the expression used to set the body
1898 * @return the builder
1899 */
1900 @SuppressWarnings("unchecked")
1901 public Type setBody(Expression expression) {
1902 SetBodyDefinition answer = new SetBodyDefinition(expression);
1903 addOutput(answer);
1904 return (Type) this;
1905 }
1906
1907 /**
1908 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
1909 * Adds a processor which sets the body on the OUT message
1910 *
1911 * @param expression the expression used to set the body
1912 * @return the builder
1913 */
1914 @SuppressWarnings("unchecked")
1915 public Type transform(Expression expression) {
1916 TransformDefinition answer = new TransformDefinition(expression);
1917 addOutput(answer);
1918 return (Type) this;
1919 }
1920
1921 /**
1922 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
1923 * Adds a processor which sets the body on the OUT message
1924 *
1925 * @return a expression builder clause to set the body
1926 */
1927 public ExpressionClause<ProcessorDefinition<Type>> transform() {
1928 ExpressionClause<ProcessorDefinition<Type>> clause =
1929 new ExpressionClause<ProcessorDefinition<Type>>((ProcessorDefinition<Type>) this);
1930 TransformDefinition answer = new TransformDefinition(clause);
1931 addOutput(answer);
1932 return clause;
1933 }
1934
1935 /**
1936 * Adds a processor which sets the body on the FAULT message
1937 *
1938 * @param expression the expression used to set the body
1939 * @return the builder
1940 */
1941 public Type setFaultBody(Expression expression) {
1942 return process(ProcessorBuilder.setFaultBody(expression));
1943 }
1944
1945 /**
1946 * Adds a processor which sets the header on the IN message
1947 *
1948 * @param name the header name
1949 * @return a expression builder clause to set the header
1950 */
1951 public ExpressionClause<ProcessorDefinition<Type>> setHeader(String name) {
1952 ExpressionClause<ProcessorDefinition<Type>> clause = new ExpressionClause<ProcessorDefinition<Type>>(this);
1953 SetHeaderDefinition answer = new SetHeaderDefinition(name, clause);
1954 addOutput(answer);
1955 return clause;
1956 }
1957
1958 /**
1959 * Adds a processor which sets the header on the IN message
1960 *
1961 * @param name the header name
1962 * @param expression the expression used to set the header
1963 * @return the builder
1964 */
1965 @SuppressWarnings("unchecked")
1966 public Type setHeader(String name, Expression expression) {
1967 SetHeaderDefinition answer = new SetHeaderDefinition(name, expression);
1968 addOutput(answer);
1969 return (Type) this;
1970 }
1971
1972 /**
1973 * Adds a processor which sets the header on the OUT message
1974 *
1975 * @param name the header name
1976 * @return a expression builder clause to set the header
1977 */
1978 public ExpressionClause<ProcessorDefinition<Type>> setOutHeader(String name) {
1979 ExpressionClause<ProcessorDefinition<Type>> clause = new ExpressionClause<ProcessorDefinition<Type>>(this);
1980 SetOutHeaderDefinition answer = new SetOutHeaderDefinition(name, clause);
1981 addOutput(answer);
1982 return clause;
1983 }
1984
1985 /**
1986 * Adds a processor which sets the header on the OUT message
1987 *
1988 * @param name the header name
1989 * @param expression the expression used to set the header
1990 * @return the builder
1991 */
1992 @SuppressWarnings("unchecked")
1993 public Type setOutHeader(String name, Expression expression) {
1994 SetOutHeaderDefinition answer = new SetOutHeaderDefinition(name, expression);
1995 addOutput(answer);
1996 return (Type) this;
1997 }
1998
1999 /**
2000 * Adds a processor which sets the header on the FAULT message
2001 *
2002 * @param name the header name
2003 * @param expression the expression used to set the header
2004 * @return the builder
2005 */
2006 public Type setFaultHeader(String name, Expression expression) {
2007 return process(ProcessorBuilder.setFaultHeader(name, expression));
2008 }
2009
2010 /**
2011 * Adds a processor which sets the exchange property
2012 *
2013 * @param name the property name
2014 * @param expression the expression used to set the property
2015 * @return the builder
2016 */
2017 @SuppressWarnings("unchecked")
2018 public Type setProperty(String name, Expression expression) {
2019 SetPropertyDefinition answer = new SetPropertyDefinition(name, expression);
2020 addOutput(answer);
2021 return (Type) this;
2022 }
2023
2024
2025 /**
2026 * Adds a processor which sets the exchange property
2027 *
2028 * @param name the property name
2029 * @return a expression builder clause to set the property
2030 */
2031 public ExpressionClause<ProcessorDefinition<Type>> setProperty(String name) {
2032 ExpressionClause<ProcessorDefinition<Type>> clause = new ExpressionClause<ProcessorDefinition<Type>>(this);
2033 SetPropertyDefinition answer = new SetPropertyDefinition(name, clause);
2034 addOutput(answer);
2035 return clause;
2036 }
2037
2038 /**
2039 * Adds a processor which removes the header on the IN message
2040 *
2041 * @param name the header name
2042 * @return the builder
2043 */
2044 @SuppressWarnings("unchecked")
2045 public Type removeHeader(String name) {
2046 RemoveHeaderDefinition answer = new RemoveHeaderDefinition(name);
2047 addOutput(answer);
2048 return (Type) this;
2049 }
2050
2051 /**
2052 * Adds a processor which removes the header on the FAULT message
2053 *
2054 * @param name the header name
2055 * @return the builder
2056 */
2057 public Type removeFaultHeader(String name) {
2058 return process(ProcessorBuilder.removeFaultHeader(name));
2059 }
2060
2061 /**
2062 * Adds a processor which removes the exchange property
2063 *
2064 * @param name the property name
2065 * @return the builder
2066 */
2067 @SuppressWarnings("unchecked")
2068 public Type removeProperty(String name) {
2069 RemovePropertyDefinition answer = new RemovePropertyDefinition(name);
2070 addOutput(answer);
2071 return (Type) this;
2072 }
2073
2074 /**
2075 * Converts the IN message body to the specified type
2076 *
2077 * @param type the type to convert to
2078 * @return the builder
2079 */
2080 @SuppressWarnings("unchecked")
2081 public Type convertBodyTo(Class type) {
2082 addOutput(new ConvertBodyDefinition(type));
2083 return (Type) this;
2084 }
2085
2086 /**
2087 * Converts the IN message body to the specified type
2088 *
2089 * @param type the type to convert to
2090 * @param charset the charset to use by type converters (not all converters support specifc charset)
2091 * @return the builder
2092 */
2093 @SuppressWarnings("unchecked")
2094 public Type convertBodyTo(Class type, String charset) {
2095 addOutput(new ConvertBodyDefinition(type, charset));
2096 return (Type) this;
2097 }
2098
2099 /**
2100 * Sorts the IN message body using the given comparator.
2101 * The IN body mut be convertable to {@link List}.
2102 *
2103 * @param comparator the comparator to use for sorting
2104 * @return the builder
2105 */
2106 @SuppressWarnings("unchecked")
2107 public Type sortBody(Comparator comparator) {
2108 addOutput(new SortDefinition(body(), comparator));
2109 return (Type) this;
2110 }
2111
2112 /**
2113 * Sorts the IN message body using a default sorting based on toString representation.
2114 * The IN body mut be convertable to {@link List}.
2115 *
2116 * @return the builder
2117 */
2118 public Type sortBody() {
2119 return sortBody(null);
2120 }
2121
2122 /**
2123 * Sorts the expression using the given comparator
2124 *
2125 * @param expression the expression, must be convertable to {@link List}
2126 * @param comparator the comparator to use for sorting
2127 * @return the builder
2128 */
2129 @SuppressWarnings("unchecked")
2130 public Type sort(Expression expression, Comparator comparator) {
2131 addOutput(new SortDefinition(expression, comparator));
2132 return (Type) this;
2133 }
2134
2135 /**
2136 * Sorts the expression using a default sorting based on toString representation.
2137 *
2138 * @param expression the expression, must be convertable to {@link List}
2139 * @return the builder
2140 */
2141 public Type sort(Expression expression) {
2142 return sort(expression, null);
2143 }
2144
2145 /**
2146 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
2147 * enriches an exchange with additional data obtained from a <code>resourceUri</code>.
2148 *
2149 * @param resourceUri URI of resource endpoint for obtaining additional data.
2150 * @param aggregationStrategy aggregation strategy to aggregate input data and additional data.
2151 * @return the builder
2152 * @see org.apache.camel.processor.Enricher
2153 */
2154 @SuppressWarnings("unchecked")
2155 public Type enrich(String resourceUri, AggregationStrategy aggregationStrategy) {
2156 addOutput(new EnrichDefinition(aggregationStrategy, resourceUri));
2157 return (Type) this;
2158 }
2159
2160 /**
2161 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
2162 * enriches an exchange with additional data obtained from a <code>resourceUri</code>.
2163 * <p/>
2164 * The difference between this and {@link #pollEnrich(String)} is that this uses a producer
2165 * to obatin the additional data, where as pollEnrich uses a polling consumer.
2166 *
2167 * @param resourceUri URI of resource endpoint for obtaining additional data.
2168 * @return the builder
2169 * @see org.apache.camel.processor.Enricher
2170 */
2171 @SuppressWarnings("unchecked")
2172 public Type enrich(String resourceUri) {
2173 addOutput(new EnrichDefinition(resourceUri));
2174 return (Type) this;
2175 }
2176
2177 /**
2178 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
2179 * enriches an exchange with additional data obtained from a <code>resourceUri</code>.
2180 * <p/>
2181 * The difference between this and {@link #pollEnrich(String)} is that this uses a producer
2182 * to obatin the additional data, where as pollEnrich uses a polling consumer.
2183 *
2184 * @param resourceRef Reference of resource endpoint for obtaining additional data.
2185 * @param aggregationStrategyRef Reference of aggregation strategy to aggregate input data and additional data.
2186 * @return the builder
2187 * @see org.apache.camel.processor.Enricher
2188 */
2189 @SuppressWarnings("unchecked")
2190 public Type enrichRef(String resourceRef, String aggregationStrategyRef) {
2191 EnrichDefinition enrich = new EnrichDefinition();
2192 enrich.setResourceRef(resourceRef);
2193 enrich.setAggregationStrategyRef(aggregationStrategyRef);
2194 addOutput(enrich);
2195 return (Type) this;
2196 }
2197
2198 /**
2199 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
2200 * enriches an exchange with additional data obtained from a <code>resourceUri</code>
2201 * using a {@link org.apache.camel.PollingConsumer} to poll the endpoint.
2202 * <p/>
2203 * The difference between this and {@link #enrich(String)} is that this uses a consumer
2204 * to obatin the additional data, where as enrich uses a producer.
2205 * <p/>
2206 * This method will block until data is avialable, use the method with timeout if you do not
2207 * want to risk waiting a long time before data is available from the resourceUri.
2208 *
2209 * @param resourceUri URI of resource endpoint for obtaining additional data.
2210 * @return the builder
2211 * @see org.apache.camel.processor.PollEnricher
2212 */
2213 @SuppressWarnings("unchecked")
2214 public Type pollEnrich(String resourceUri) {
2215 addOutput(new PollEnrichDefinition(null, resourceUri, 0));
2216 return (Type) this;
2217 }
2218
2219 /**
2220 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
2221 * enriches an exchange with additional data obtained from a <code>resourceUri</code>
2222 * using a {@link org.apache.camel.PollingConsumer} to poll the endpoint.
2223 * <p/>
2224 * The difference between this and {@link #enrich(String)} is that this uses a consumer
2225 * to obatin the additional data, where as enrich uses a producer.
2226 * <p/>
2227 * This method will block until data is avialable, use the method with timeout if you do not
2228 * want to risk waiting a long time before data is available from the resourceUri.
2229 *
2230 * @param resourceUri URI of resource endpoint for obtaining additional data.
2231 * @param aggregationStrategy aggregation strategy to aggregate input data and additional data.
2232 * @return the builder
2233 * @see org.apache.camel.processor.PollEnricher
2234 */
2235 @SuppressWarnings("unchecked")
2236 public Type pollEnrich(String resourceUri, AggregationStrategy aggregationStrategy) {
2237 addOutput(new PollEnrichDefinition(aggregationStrategy, resourceUri, 0));
2238 return (Type) this;
2239 }
2240
2241 /**
2242 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
2243 * enriches an exchange with additional data obtained from a <code>resourceUri</code>
2244 * using a {@link org.apache.camel.PollingConsumer} to poll the endpoint.
2245 * <p/>
2246 * The difference between this and {@link #enrich(String)} is that this uses a consumer
2247 * to obatin the additional data, where as enrich uses a producer.
2248 * <p/>
2249 * The timeout controls which operation to use on {@link org.apache.camel.PollingConsumer}.
2250 * If timeout is negative, we use <tt>receive</tt>. If timeout is 0 then we use <tt>receiveNoWait</tt>
2251 * otherwise we use <tt>receive(timeout)</tt>.
2252 *
2253 * @param resourceUri URI of resource endpoint for obtaining additional data.
2254 * @param timeout timeout in millis to wait at most for data to be available.
2255 * @param aggregationStrategy aggregation strategy to aggregate input data and additional data.
2256 * @return the builder
2257 * @see org.apache.camel.processor.PollEnricher
2258 */
2259 @SuppressWarnings("unchecked")
2260 public Type pollEnrich(String resourceUri, long timeout, AggregationStrategy aggregationStrategy) {
2261 addOutput(new PollEnrichDefinition(aggregationStrategy, resourceUri, timeout));
2262 return (Type) this;
2263 }
2264
2265 /**
2266 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
2267 * enriches an exchange with additional data obtained from a <code>resourceUri</code>
2268 * using a {@link org.apache.camel.PollingConsumer} to poll the endpoint.
2269 * <p/>
2270 * The difference between this and {@link #enrich(String)} is that this uses a consumer
2271 * to obatin the additional data, where as enrich uses a producer.
2272 * <p/>
2273 * The timeout controls which operation to use on {@link org.apache.camel.PollingConsumer}.
2274 * If timeout is negative, we use <tt>receive</tt>. If timeout is 0 then we use <tt>receiveNoWait</tt>
2275 * otherwise we use <tt>receive(timeout)</tt>.
2276 *
2277 * @param resourceUri URI of resource endpoint for obtaining additional data.
2278 * @param timeout timeout in millis to wait at most for data to be available.
2279 * @return the builder
2280 * @see org.apache.camel.processor.PollEnricher
2281 */
2282 @SuppressWarnings("unchecked")
2283 public Type pollEnrich(String resourceUri, long timeout) {
2284 addOutput(new PollEnrichDefinition(null, resourceUri, timeout));
2285 return (Type) this;
2286 }
2287
2288 /**
2289 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
2290 * enriches an exchange with additional data obtained from a <code>resourceUri</code>
2291 * using a {@link org.apache.camel.PollingConsumer} to poll the endpoint.
2292 * <p/>
2293 * The difference between this and {@link #enrich(String)} is that this uses a consumer
2294 * to obatin the additional data, where as enrich uses a producer.
2295 * <p/>
2296 * The timeout controls which operation to use on {@link org.apache.camel.PollingConsumer}.
2297 * If timeout is negative, we use <tt>receive</tt>. If timeout is 0 then we use <tt>receiveNoWait</tt>
2298 * otherwise we use <tt>receive(timeout)</tt>.
2299 *
2300 * @param resourceRef Reference of resource endpoint for obtaining additional data.
2301 * @param timeout timeout in millis to wait at most for data to be available.
2302 * @param aggregationStrategyRef Reference of aggregation strategy to aggregate input data and additional data.
2303 * @return the builder
2304 * @see org.apache.camel.processor.PollEnricher
2305 */
2306 @SuppressWarnings("unchecked")
2307 public Type pollEnrichRef(String resourceRef, long timeout, String aggregationStrategyRef) {
2308 PollEnrichDefinition pollEnrich = new PollEnrichDefinition();
2309 pollEnrich.setResourceRef(resourceRef);
2310 pollEnrich.setTimeout(timeout);
2311 pollEnrich.setAggregationStrategyRef(aggregationStrategyRef);
2312 addOutput(pollEnrich);
2313 return (Type) this;
2314 }
2315
2316 /**
2317 * Adds a onComplection {@link org.apache.camel.spi.Synchronization} hook that invoke this route as
2318 * a callback when the {@link org.apache.camel.Exchange} has finished being processed.
2319 * The hook invoke callbacks for either onComplete or onFailure.
2320 * <p/>
2321 * Will by default always trigger when the {@link org.apache.camel.Exchange} is complete
2322 * (either with success or failed).
2323 * <br/>
2324 * You can limit the callback to either onComplete or onFailure but invoking the nested
2325 * builder method.
2326 * <p/>
2327 * For onFailure the caused exception is stored as a property on the {@link org.apache.camel.Exchange}
2328 * with the key {@link org.apache.camel.Exchange#EXCEPTION_CAUGHT}.
2329 *
2330 * @return the builder
2331 */
2332 @SuppressWarnings("unchecked")
2333 public OnCompletionDefinition onCompletion() {
2334 OnCompletionDefinition answer = new OnCompletionDefinition();
2335 // we must remove all existing on completion definition (as they are global)
2336 // and thus we are the only one as route scoped should override any global scoped
2337 answer.removeAllOnCompletionDefinition(this);
2338 popBlock();
2339 addOutput(answer);
2340 pushBlock(answer);
2341 return answer;
2342 }
2343
2344 // DataFormat support
2345 // -------------------------------------------------------------------------
2346
2347 /**
2348 * <a href="http://camel.apache.org/data-format.html">DataFormat:</a>
2349 * Unmarshals the in body using a {@link DataFormat} expression to define
2350 * the format of the input message and the output will be set on the out message body.
2351 *
2352 * @return the expression to create the {@link DataFormat}
2353 */
2354 public DataFormatClause<ProcessorDefinition<Type>> unmarshal() {
2355 return new DataFormatClause<ProcessorDefinition<Type>>(this, DataFormatClause.Operation.Unmarshal);
2356 }
2357
2358 /**
2359 * <a href="http://camel.apache.org/data-format.html">DataFormat:</a>
2360 * Unmarshals the in body using the specified {@link DataFormat}
2361 * and sets the output on the out message body.
2362 *
2363 * @param dataFormatType the dataformat
2364 * @return the builder
2365 */
2366 @SuppressWarnings("unchecked")
2367 public Type unmarshal(DataFormatDefinition dataFormatType) {
2368 addOutput(new UnmarshalDefinition(dataFormatType));
2369 return (Type) this;
2370 }
2371
2372 /**
2373 * <a href="http://camel.apache.org/data-format.html">DataFormat:</a>
2374 * Unmarshals the in body using the specified {@link DataFormat}
2375 * and sets the output on the out message body.
2376 *
2377 * @param dataFormat the dataformat
2378 * @return the builder
2379 */
2380 public Type unmarshal(DataFormat dataFormat) {
2381 return unmarshal(new DataFormatDefinition(dataFormat));
2382 }
2383
2384 /**
2385 * <a href="http://camel.apache.org/data-format.html">DataFormat:</a>
2386 * Unmarshals the in body using the specified {@link DataFormat}
2387 * reference in the {@link org.apache.camel.spi.Registry} and sets
2388 * the output on the out message body.
2389 *
2390 * @param dataTypeRef reference to a {@link DataFormat} to lookup in the registry
2391 * @return the builder
2392 */
2393 @SuppressWarnings("unchecked")
2394 public Type unmarshal(String dataTypeRef) {
2395 addOutput(new UnmarshalDefinition(dataTypeRef));
2396 return (Type) this;
2397 }
2398
2399 /**
2400 * <a href="http://camel.apache.org/data-format.html">DataFormat:</a>
2401 * Marshals the in body using a {@link DataFormat} expression to define
2402 * the format of the output which will be added to the out body.
2403 *
2404 * @return the expression to create the {@link DataFormat}
2405 */
2406 public DataFormatClause<ProcessorDefinition<Type>> marshal() {
2407 return new DataFormatClause<ProcessorDefinition<Type>>(this, DataFormatClause.Operation.Marshal);
2408 }
2409
2410 /**
2411 * <a href="http://camel.apache.org/data-format.html">DataFormat:</a>
2412 * Marshals the in body using the specified {@link DataFormat}
2413 * and sets the output on the out message body.
2414 *
2415 * @param dataFormatType the dataformat
2416 * @return the builder
2417 */
2418 @SuppressWarnings("unchecked")
2419 public Type marshal(DataFormatDefinition dataFormatType) {
2420 addOutput(new MarshalDefinition(dataFormatType));
2421 return (Type) this;
2422 }
2423
2424 /**
2425 * <a href="http://camel.apache.org/data-format.html">DataFormat:</a>
2426 * Marshals the in body using the specified {@link DataFormat}
2427 * and sets the output on the out message body.
2428 *
2429 * @param dataFormat the dataformat
2430 * @return the builder
2431 */
2432 public Type marshal(DataFormat dataFormat) {
2433 return marshal(new DataFormatDefinition(dataFormat));
2434 }
2435
2436 /**
2437 * <a href="http://camel.apache.org/data-format.html">DataFormat:</a>
2438 * Marshals the in body the specified {@link DataFormat}
2439 * reference in the {@link org.apache.camel.spi.Registry} and sets
2440 * the output on the out message body.
2441 *
2442 * @param dataTypeRef reference to a {@link DataFormat} to lookup in the registry
2443 * @return the builder
2444 */
2445 @SuppressWarnings("unchecked")
2446 public Type marshal(String dataTypeRef) {
2447 addOutput(new MarshalDefinition(dataTypeRef));
2448 return (Type) this;
2449 }
2450
2451 // Properties
2452 // -------------------------------------------------------------------------
2453 @XmlTransient
2454 public ProcessorDefinition getParent() {
2455 return parent;
2456 }
2457
2458 public void setParent(ProcessorDefinition parent) {
2459 this.parent = parent;
2460 }
2461
2462 @XmlTransient
2463 public ErrorHandlerBuilder getErrorHandlerBuilder() {
2464 if (errorHandlerBuilder == null) {
2465 errorHandlerBuilder = createErrorHandlerBuilder();
2466 }
2467 return errorHandlerBuilder;
2468 }
2469
2470 /**
2471 * Sets the error handler to use with processors created by this builder
2472 */
2473 public void setErrorHandlerBuilder(ErrorHandlerBuilder errorHandlerBuilder) {
2474 this.errorHandlerBuilder = errorHandlerBuilder;
2475 }
2476
2477 @XmlTransient
2478 public NodeFactory getNodeFactory() {
2479 if (nodeFactory == null) {
2480 nodeFactory = new NodeFactory();
2481 }
2482 return nodeFactory;
2483 }
2484
2485 public void setNodeFactory(NodeFactory nodeFactory) {
2486 this.nodeFactory = nodeFactory;
2487 }
2488
2489 @XmlTransient
2490 public List<InterceptStrategy> getInterceptStrategies() {
2491 return interceptStrategies;
2492 }
2493
2494 public void addInterceptStrategy(InterceptStrategy strategy) {
2495 this.interceptStrategies.add(strategy);
2496 }
2497
2498 /**
2499 * Returns a label to describe this node such as the expression if some kind of expression node
2500 */
2501 public String getLabel() {
2502 return "";
2503 }
2504
2505 }