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