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 */
017package org.apache.camel.model;
018
019import java.util.ArrayList;
020import java.util.Arrays;
021import java.util.Collection;
022import java.util.Comparator;
023import java.util.HashMap;
024import java.util.Iterator;
025import java.util.LinkedList;
026import java.util.List;
027import java.util.Map;
028import java.util.concurrent.ExecutorService;
029import java.util.concurrent.TimeUnit;
030import java.util.concurrent.atomic.AtomicInteger;
031import javax.xml.bind.annotation.XmlAccessType;
032import javax.xml.bind.annotation.XmlAccessorType;
033import javax.xml.bind.annotation.XmlAnyAttribute;
034import javax.xml.bind.annotation.XmlAttribute;
035import javax.xml.bind.annotation.XmlTransient;
036import javax.xml.namespace.QName;
037
038import org.apache.camel.Channel;
039import org.apache.camel.Endpoint;
040import org.apache.camel.ErrorHandlerFactory;
041import org.apache.camel.Exchange;
042import org.apache.camel.ExchangePattern;
043import org.apache.camel.Expression;
044import org.apache.camel.LoggingLevel;
045import org.apache.camel.Predicate;
046import org.apache.camel.Processor;
047import org.apache.camel.Route;
048import org.apache.camel.builder.DataFormatClause;
049import org.apache.camel.builder.ExpressionBuilder;
050import org.apache.camel.builder.ExpressionClause;
051import org.apache.camel.builder.ProcessorBuilder;
052import org.apache.camel.model.language.ConstantExpression;
053import org.apache.camel.model.language.ExpressionDefinition;
054import org.apache.camel.model.language.LanguageExpression;
055import org.apache.camel.model.language.SimpleExpression;
056import org.apache.camel.model.rest.RestDefinition;
057import org.apache.camel.processor.CamelInternalProcessor;
058import org.apache.camel.processor.InterceptEndpointProcessor;
059import org.apache.camel.processor.Pipeline;
060import org.apache.camel.processor.aggregate.AggregationStrategy;
061import org.apache.camel.processor.interceptor.DefaultChannel;
062import org.apache.camel.processor.interceptor.Delayer;
063import org.apache.camel.processor.interceptor.HandleFault;
064import org.apache.camel.processor.interceptor.StreamCaching;
065import org.apache.camel.processor.loadbalancer.LoadBalancer;
066import org.apache.camel.spi.DataFormat;
067import org.apache.camel.spi.IdAware;
068import org.apache.camel.spi.IdempotentRepository;
069import org.apache.camel.spi.InterceptStrategy;
070import org.apache.camel.spi.LifecycleStrategy;
071import org.apache.camel.spi.Policy;
072import org.apache.camel.spi.RouteContext;
073import org.slf4j.Logger;
074import org.slf4j.LoggerFactory;
075
076/**
077 * Base class for processor types that most XML types extend.
078 *
079 * @version 
080 */
081@XmlAccessorType(XmlAccessType.FIELD)
082public abstract class ProcessorDefinition<Type extends ProcessorDefinition<Type>> extends OptionalIdentifiedDefinition<Type> implements Block, OtherAttributesAware {
083    @XmlTransient
084    private static final AtomicInteger COUNTER = new AtomicInteger();
085    @XmlTransient
086    protected final Logger log = LoggerFactory.getLogger(getClass());
087    @XmlAttribute
088    protected Boolean inheritErrorHandler;
089    @XmlTransient
090    private final LinkedList<Block> blocks = new LinkedList<Block>();
091    @XmlTransient
092    private ProcessorDefinition<?> parent;
093    @XmlTransient
094    private final List<InterceptStrategy> interceptStrategies = new ArrayList<InterceptStrategy>();
095    // use xs:any to support optional property placeholders
096    @XmlAnyAttribute
097    private Map<QName, Object> otherAttributes;
098    @XmlTransient
099    private final int index;
100
101    protected ProcessorDefinition() {
102        // every time we create a definition we should inc the COUNTER counter
103        index = COUNTER.getAndIncrement();
104    }
105
106    /**
107     * Gets the unique index number for when this {@link ProcessorDefinition} was created by its constructor.
108     * <p/>
109     * This can be used to know the order in which the definition was created when assembled as a route.
110     *
111     * @return the index number
112     */
113    public int getIndex() {
114        return index;
115    }
116
117    // else to use an optional attribute in JAXB2
118    public abstract List<ProcessorDefinition<?>> getOutputs();
119
120    public abstract boolean isOutputSupported();
121
122    /**
123     * Whether this definition can only be added as top-level directly on the route itself (such as onException,onCompletion,intercept, etc.)
124     * <p/>
125     * If trying to add a top-level only definition to a nested output would fail in the {@link #addOutput(ProcessorDefinition)}
126     * method.
127     */
128    public boolean isTopLevelOnly() {
129        return false;
130    }
131
132    /**
133     * Whether this model is abstract or not.
134     * <p/>
135     * An abstract model is something that is used for configuring cross cutting concerns such as
136     * error handling, transaction policies, interceptors etc.
137     * <p/>
138     * Regular definitions is what is part of the route, such as ToDefinition, WireTapDefinition and the likes.
139     * <p/>
140     * Will by default return <tt>false</tt> to indicate regular definition, so all the abstract definitions
141     * must override this method and return <tt>true</tt> instead.
142     * <p/>
143     * This information is used in camel-spring to let Camel work a bit on the model provided by JAXB from the
144     * Spring XML file. This is needed to handle those cross cutting concerns properly. The Java DSL does not
145     * have this issue as it can work this out directly using the fluent builder methods.
146     *
147     * @return <tt>true</tt> for abstract, otherwise <tt>false</tt> for regular.
148     */
149    public boolean isAbstract() {
150        return false;
151    }
152
153    /**
154     * Override this in definition class and implement logic to create the processor
155     * based on the definition model.
156     */
157    public Processor createProcessor(RouteContext routeContext) throws Exception {
158        throw new UnsupportedOperationException("Not implemented yet for class: " + getClass().getName());
159    }
160
161    /**
162     * Prefer to use {#link #createChildProcessor}.
163     */
164    public Processor createOutputsProcessor(RouteContext routeContext) throws Exception {
165        Collection<ProcessorDefinition<?>> outputs = getOutputs();
166        return createOutputsProcessor(routeContext, outputs);
167    }
168
169    /**
170     * Creates the child processor (outputs) from the current definition
171     *
172     * @param routeContext   the route context
173     * @param mandatory      whether or not children is mandatory (ie the definition should have outputs)
174     * @return the created children, or <tt>null</tt> if definition had no output
175     * @throws Exception is thrown if error creating the child or if it was mandatory and there was no output defined on definition
176     */
177    public Processor createChildProcessor(RouteContext routeContext, boolean mandatory) throws Exception {
178        Processor children = null;
179        // at first use custom factory
180        if (routeContext.getCamelContext().getProcessorFactory() != null) {
181            children = routeContext.getCamelContext().getProcessorFactory().createChildProcessor(routeContext, this, mandatory);
182        }
183        // fallback to default implementation if factory did not create the child
184        if (children == null) {
185            children = createOutputsProcessor(routeContext);
186        }
187
188        if (children == null && mandatory) {
189            throw new IllegalArgumentException("Definition has no children on " + this);
190        }
191        return children;
192    }
193
194    @Override
195    public void addOutput(ProcessorDefinition<?> output) {
196        if (!blocks.isEmpty()) {
197            // let the Block deal with the output
198            Block block = blocks.getLast();
199            block.addOutput(output);
200            return;
201        }
202
203        // validate that top-level is only added on the route (eg top level)
204        boolean parentIsRoute = this.getClass().isAssignableFrom(RouteDefinition.class);
205        if (output.isTopLevelOnly() && !parentIsRoute) {
206            throw new IllegalArgumentException("The output must be added as top-level on the route. Try moving " + output + " to the top of route.");
207        }
208
209        output.setParent(this);
210        configureChild(output);
211        getOutputs().add(output);
212    }
213
214    public void clearOutput() {
215        getOutputs().clear();
216        blocks.clear();
217    }
218
219    public void addRoutes(RouteContext routeContext, Collection<Route> routes) throws Exception {
220        Processor processor = makeProcessor(routeContext);
221        if (processor == null) {
222            // no processor to add
223            return;
224        }
225
226        if (!routeContext.isRouteAdded()) {
227            boolean endpointInterceptor = false;
228
229            // are we routing to an endpoint interceptor, if so we should not add it as an event driven
230            // processor as we use the producer to trigger the interceptor
231            if (processor instanceof Channel) {
232                Channel channel = (Channel) processor;
233                Processor next = channel.getNextProcessor();
234                if (next instanceof InterceptEndpointProcessor) {
235                    endpointInterceptor = true;
236                }
237            }
238
239            // only add regular processors as event driven
240            if (endpointInterceptor) {
241                log.debug("Endpoint interceptor should not be added as an event driven consumer route: {}", processor);
242            } else {
243                log.trace("Adding event driven processor: {}", processor);
244                routeContext.addEventDrivenProcessor(processor);
245            }
246
247        }
248    }
249
250    /**
251     * Wraps the child processor in whatever necessary interceptors and error handlers
252     */
253    public Processor wrapProcessor(RouteContext routeContext, Processor processor) throws Exception {
254        // dont double wrap
255        if (processor instanceof Channel) {
256            return processor;
257        }
258        return wrapChannel(routeContext, processor, null);
259    }
260
261    protected Processor wrapChannel(RouteContext routeContext, Processor processor, ProcessorDefinition<?> child) throws Exception {
262        // put a channel in between this and each output to control the route flow logic
263        ModelChannel channel = createChannel(routeContext);
264        channel.setNextProcessor(processor);
265
266        // add interceptor strategies to the channel must be in this order: camel context, route context, local
267        addInterceptStrategies(routeContext, channel, routeContext.getCamelContext().getInterceptStrategies());
268        addInterceptStrategies(routeContext, channel, routeContext.getInterceptStrategies());
269        addInterceptStrategies(routeContext, channel, this.getInterceptStrategies());
270
271        // must do this ugly cast to avoid compiler error on AIX/HP-UX
272        ProcessorDefinition<?> defn = (ProcessorDefinition<?>) this;
273
274        // set the child before init the channel
275        channel.setChildDefinition(child);
276        channel.initChannel(defn, routeContext);
277
278        // set the error handler, must be done after init as we can set the error handler as first in the chain
279        if (defn instanceof TryDefinition || defn instanceof CatchDefinition || defn instanceof FinallyDefinition) {
280            // do not use error handler for try .. catch .. finally blocks as it will handle errors itself
281            log.trace("{} is part of doTry .. doCatch .. doFinally so no error handler is applied", defn);
282        } else if (ProcessorDefinitionHelper.isParentOfType(TryDefinition.class, defn, true)
283                || ProcessorDefinitionHelper.isParentOfType(CatchDefinition.class, defn, true)
284                || ProcessorDefinitionHelper.isParentOfType(FinallyDefinition.class, defn, true)) {
285            // do not use error handler for try .. catch .. finally blocks as it will handle errors itself
286            // by checking that any of our parent(s) is not a try .. catch or finally type
287            log.trace("{} is part of doTry .. doCatch .. doFinally so no error handler is applied", defn);
288        } else if (defn instanceof OnExceptionDefinition || ProcessorDefinitionHelper.isParentOfType(OnExceptionDefinition.class, defn, true)) {
289            log.trace("{} is part of OnException so no error handler is applied", defn);
290            // do not use error handler for onExceptions blocks as it will handle errors itself
291        } else if (defn instanceof MulticastDefinition) {
292            // do not use error handler for multicast as it offers fine grained error handlers for its outputs
293            // however if share unit of work is enabled, we need to wrap an error handler on the multicast parent
294            MulticastDefinition def = (MulticastDefinition) defn;
295            boolean isShareUnitOfWork = def.getShareUnitOfWork() != null && def.getShareUnitOfWork();
296            if (isShareUnitOfWork && child == null) {
297                // only wrap the parent (not the children of the multicast)
298                wrapChannelInErrorHandler(channel, routeContext);
299            } else {
300                log.trace("{} is part of multicast which have special error handling so no error handler is applied", defn);
301            }
302        } else {
303            // use error handler by default or if configured to do so
304            wrapChannelInErrorHandler(channel, routeContext);
305        }
306
307        // do post init at the end
308        channel.postInitChannel(defn, routeContext);
309        log.trace("{} wrapped in Channel: {}", defn, channel);
310
311        return channel;
312    }
313
314    /**
315     * Wraps the given channel in error handler (if error handler is inherited)
316     *
317     * @param channel       the channel
318     * @param routeContext  the route context
319     * @throws Exception can be thrown if failed to create error handler builder
320     */
321    private void wrapChannelInErrorHandler(Channel channel, RouteContext routeContext) throws Exception {
322        if (isInheritErrorHandler() == null || isInheritErrorHandler()) {
323            log.trace("{} is configured to inheritErrorHandler", this);
324            Processor output = channel.getOutput();
325            Processor errorHandler = wrapInErrorHandler(routeContext, output);
326            // set error handler on channel
327            channel.setErrorHandler(errorHandler);
328        } else {
329            log.debug("{} is configured to not inheritErrorHandler.", this);
330        }
331    }
332
333    /**
334     * Wraps the given output in an error handler
335     *
336     * @param routeContext the route context
337     * @param output the output
338     * @return the output wrapped with the error handler
339     * @throws Exception can be thrown if failed to create error handler builder
340     */
341    protected Processor wrapInErrorHandler(RouteContext routeContext, Processor output) throws Exception {
342        ErrorHandlerFactory builder = routeContext.getRoute().getErrorHandlerBuilder();
343        // create error handler
344        Processor errorHandler = builder.createErrorHandler(routeContext, output);
345
346        // invoke lifecycles so we can manage this error handler builder
347        for (LifecycleStrategy strategy : routeContext.getCamelContext().getLifecycleStrategies()) {
348            strategy.onErrorHandlerAdd(routeContext, errorHandler, builder);
349        }
350
351        return errorHandler;
352    }
353
354    /**
355     * Adds the given list of interceptors to the channel.
356     *
357     * @param routeContext  the route context
358     * @param channel       the channel to add strategies
359     * @param strategies    list of strategies to add.
360     */
361    protected void addInterceptStrategies(RouteContext routeContext, Channel channel, List<InterceptStrategy> strategies) {
362        for (InterceptStrategy strategy : strategies) {
363            if (!routeContext.isStreamCaching() && strategy instanceof StreamCaching) {
364                // stream cache is disabled so we should not add it
365                continue;
366            }
367            if (!routeContext.isHandleFault() && strategy instanceof HandleFault) {
368                // handle fault is disabled so we should not add it
369                continue;
370            }
371            if (strategy instanceof Delayer) {
372                if (routeContext.getDelayer() == null || routeContext.getDelayer() <= 0) {
373                    // delayer is disabled so we should not add it
374                    continue;
375                } else {
376                    // replace existing delayer as delayer have individual configuration
377                    Iterator<InterceptStrategy> it = channel.getInterceptStrategies().iterator();
378                    while (it.hasNext()) {
379                        InterceptStrategy existing = it.next();
380                        if (existing instanceof Delayer) {
381                            it.remove();
382                        }
383                    }
384                    // add the new correct delayer
385                    channel.addInterceptStrategy(strategy);
386                    continue;
387                }
388            }
389
390            // add strategy
391            channel.addInterceptStrategy(strategy);
392        }
393    }
394
395    /**
396     * Creates a new instance of some kind of composite processor which defaults
397     * to using a {@link Pipeline} but derived classes could change the behaviour
398     */
399    protected Processor createCompositeProcessor(RouteContext routeContext, List<Processor> list) throws Exception {
400        return new Pipeline(routeContext.getCamelContext(), list);
401    }
402
403    /**
404     * Creates a new instance of the {@link Channel}.
405     */
406    protected ModelChannel createChannel(RouteContext routeContext) throws Exception {
407        return new DefaultChannel();
408    }
409
410    protected Processor createOutputsProcessor(RouteContext routeContext, Collection<ProcessorDefinition<?>> outputs) throws Exception {
411        // We will save list of actions to restore the outputs back to the original state.
412        Runnable propertyPlaceholdersChangeReverter = ProcessorDefinitionHelper.createPropertyPlaceholdersChangeReverter();
413        try {
414            return createOutputsProcessorImpl(routeContext, outputs);
415        } finally {
416            propertyPlaceholdersChangeReverter.run();
417        }
418    }
419
420    protected Processor createOutputsProcessorImpl(RouteContext routeContext, Collection<ProcessorDefinition<?>> outputs) throws Exception {
421        List<Processor> list = new ArrayList<Processor>();
422        for (ProcessorDefinition<?> output : outputs) {
423
424            // allow any custom logic before we create the processor
425            output.preCreateProcessor();
426
427            // resolve properties before we create the processor
428            ProcessorDefinitionHelper.resolvePropertyPlaceholders(routeContext.getCamelContext(), output);
429
430            // resolve constant fields (eg Exchange.FILE_NAME)
431            ProcessorDefinitionHelper.resolveKnownConstantFields(output);
432
433            // also resolve properties and constant fields on embedded expressions
434            ProcessorDefinition<?> me = (ProcessorDefinition<?>) output;
435            if (me instanceof ExpressionNode) {
436                ExpressionNode exp = (ExpressionNode) me;
437                ExpressionDefinition expressionDefinition = exp.getExpression();
438                if (expressionDefinition != null) {
439                    // resolve properties before we create the processor
440                    ProcessorDefinitionHelper.resolvePropertyPlaceholders(routeContext.getCamelContext(), expressionDefinition);
441
442                    // resolve constant fields (eg Exchange.FILE_NAME)
443                    ProcessorDefinitionHelper.resolveKnownConstantFields(expressionDefinition);
444                }
445            }
446
447            Processor processor = createProcessor(routeContext, output);
448
449            // inject id
450            if (processor instanceof IdAware) {
451                String id = output.idOrCreate(routeContext.getCamelContext().getNodeIdFactory());
452                ((IdAware) processor).setId(id);
453            }
454
455            if (output instanceof Channel && processor == null) {
456                continue;
457            }
458
459            Processor channel = wrapChannel(routeContext, processor, output);
460            list.add(channel);
461        }
462
463        // if more than one output wrap than in a composite processor else just keep it as is
464        Processor processor = null;
465        if (!list.isEmpty()) {
466            if (list.size() == 1) {
467                processor = list.get(0);
468            } else {
469                processor = createCompositeProcessor(routeContext, list);
470            }
471        }
472
473        return processor;
474    }
475
476    protected Processor createProcessor(RouteContext routeContext, ProcessorDefinition<?> output) throws Exception {
477        Processor processor = null;
478        // at first use custom factory
479        if (routeContext.getCamelContext().getProcessorFactory() != null) {
480            processor = routeContext.getCamelContext().getProcessorFactory().createProcessor(routeContext, output);
481        }
482        // fallback to default implementation if factory did not create the processor
483        if (processor == null) {
484            processor = output.createProcessor(routeContext);
485        }
486        return processor;
487    }
488
489    /**
490     * Creates the processor and wraps it in any necessary interceptors and error handlers
491     */
492    protected Processor makeProcessor(RouteContext routeContext) throws Exception {
493        // We will save list of actions to restore the definition back to the original state.
494        Runnable propertyPlaceholdersChangeReverter = ProcessorDefinitionHelper.createPropertyPlaceholdersChangeReverter();
495        try {
496            return makeProcessorImpl(routeContext);
497        } finally {
498            // Lets restore
499            propertyPlaceholdersChangeReverter.run();
500        }
501    }
502
503    private Processor makeProcessorImpl(RouteContext routeContext) throws Exception {
504        Processor processor = null;
505
506        // allow any custom logic before we create the processor
507        preCreateProcessor();
508
509        // resolve properties before we create the processor
510        ProcessorDefinitionHelper.resolvePropertyPlaceholders(routeContext.getCamelContext(), this);
511
512        // resolve constant fields (eg Exchange.FILE_NAME)
513        ProcessorDefinitionHelper.resolveKnownConstantFields(this);
514
515        // also resolve properties and constant fields on embedded expressions
516        ProcessorDefinition<?> me = (ProcessorDefinition<?>) this;
517        if (me instanceof ExpressionNode) {
518            ExpressionNode exp = (ExpressionNode) me;
519            ExpressionDefinition expressionDefinition = exp.getExpression();
520            if (expressionDefinition != null) {
521                // resolve properties before we create the processor
522                ProcessorDefinitionHelper.resolvePropertyPlaceholders(routeContext.getCamelContext(), expressionDefinition);
523
524                // resolve constant fields (eg Exchange.FILE_NAME)
525                ProcessorDefinitionHelper.resolveKnownConstantFields(expressionDefinition);
526            }
527        }
528
529        // at first use custom factory
530        if (routeContext.getCamelContext().getProcessorFactory() != null) {
531            processor = routeContext.getCamelContext().getProcessorFactory().createProcessor(routeContext, this);
532        }
533        // fallback to default implementation if factory did not create the processor
534        if (processor == null) {
535            processor = createProcessor(routeContext);
536        }
537
538        // unwrap internal processor so we can set id on the actual processor
539        Processor idProcessor = processor;
540        if (processor instanceof CamelInternalProcessor) {
541            idProcessor = ((CamelInternalProcessor) processor).getProcessor();
542        }
543
544        // inject id
545        if (idProcessor instanceof IdAware) {
546            String id = this.idOrCreate(routeContext.getCamelContext().getNodeIdFactory());
547            ((IdAware) idProcessor).setId(id);
548        }
549
550        if (processor == null) {
551            // no processor to make
552            return null;
553        }
554        return wrapProcessor(routeContext, processor);
555    }
556
557    /**
558     * Strategy to execute any custom logic before the {@link Processor} is created.
559     */
560    protected void preCreateProcessor() {
561        // noop
562    }
563
564    /**
565     * Strategy for children to do any custom configuration
566     *
567     * @param output the child to be added as output to this
568     */
569    public void configureChild(ProcessorDefinition<?> output) {
570        // noop
571    }
572
573    // Fluent API
574    // -------------------------------------------------------------------------
575
576    /**
577     * Adds a placeholder for the given option
578     * <p/>
579     * Requires using the {@link org.apache.camel.component.properties.PropertiesComponent}
580     *
581     * @param option  the name of the option
582     * @param key     the placeholder key
583     * @return the builder
584     */
585    public Type placeholder(String option, String key) {
586        QName name = new QName(Constants.PLACEHOLDER_QNAME, option);
587        return attribute(name, key);
588    }
589
590    /**
591     * Adds an optional attribute
592     *
593     * @param name    the name of the attribute
594     * @param value   the value
595     * @return the builder
596     */
597    @SuppressWarnings("unchecked")
598    public Type attribute(QName name, Object value) {
599        if (otherAttributes == null) {
600            otherAttributes = new HashMap<QName, Object>();
601        }
602        otherAttributes.put(name, value);
603        return (Type) this;
604    }
605
606    /**
607     * Sends the exchange to the given endpoint
608     *
609     * @param uri  the endpoint to send to
610     * @return the builder
611     */
612    @SuppressWarnings("unchecked")
613    public Type to(String uri) {
614        addOutput(new ToDefinition(uri));
615        return (Type) this;
616    }
617
618    /**
619     * Sends the exchange to the given dynamic endpoint
620     *
621     * @param uri  the dynamic endpoint to send to (resolved using simple language by default)
622     * @return the builder
623     */
624    @SuppressWarnings("unchecked")
625    public Type toD(String uri) {
626        ToDynamicDefinition answer = new ToDynamicDefinition();
627        answer.setUri(uri);
628        addOutput(answer);
629        return (Type) this;
630    }
631
632    /**
633     * Sends the exchange to the given dynamic endpoint
634     *
635     * @param uri  the dynamic endpoint to send to (resolved using simple language by default)
636     * @return the builder
637     */
638    @SuppressWarnings("unchecked")
639    public Type toD(String uri, boolean ignoreInvalidEndpoint) {
640        ToDynamicDefinition answer = new ToDynamicDefinition();
641        answer.setUri(uri);
642        answer.setIgnoreInvalidEndpoint(ignoreInvalidEndpoint);
643        addOutput(answer);
644        return (Type) this;
645    }
646
647    /**
648     * Sends the exchange to the given endpoint
649     *
650     * @param uri  the String formatted endpoint uri to send to
651     * @param args arguments for the string formatting of the uri
652     * @return the builder
653     */
654    @SuppressWarnings("unchecked")
655    public Type toF(String uri, Object... args) {
656        addOutput(new ToDefinition(String.format(uri, args)));
657        return (Type) this;
658    }
659
660    /**
661     * Sends the exchange to the given endpoint
662     *
663     * @param endpoint  the endpoint to send to
664     * @return the builder
665     */
666    @SuppressWarnings("unchecked")
667    public Type to(Endpoint endpoint) {
668        addOutput(new ToDefinition(endpoint));
669        return (Type) this;
670    }
671    
672    /**
673     * Sends the exchange with certain exchange pattern to the given endpoint
674     * <p/>
675     * Notice the existing MEP is preserved
676     *
677     * @param pattern the pattern to use for the message exchange
678     * @param uri  the endpoint to send to
679     * @return the builder
680     */
681    @SuppressWarnings("unchecked")
682    public Type to(ExchangePattern pattern, String uri) {
683        addOutput(new ToDefinition(uri, pattern));
684        return (Type) this;
685    }   
686
687    /**
688     * Sends the exchange with certain exchange pattern to the given endpoint
689     * <p/>
690     * Notice the existing MEP is preserved
691     *
692     * @param pattern the pattern to use for the message exchange
693     * @param endpoint  the endpoint to send to
694     * @return the builder
695     */
696    @SuppressWarnings("unchecked")
697    public Type to(ExchangePattern pattern, Endpoint endpoint) {
698        addOutput(new ToDefinition(endpoint, pattern));
699        return (Type) this;
700    }
701
702    /**
703     * Sends the exchange to a list of endpoints
704     *
705     * @param uris  list of endpoints to send to
706     * @return the builder
707     */
708    @SuppressWarnings("unchecked")
709    public Type to(String... uris) {
710        for (String uri : uris) {
711            addOutput(new ToDefinition(uri));
712        }
713        return (Type) this;
714    }
715
716    /**
717     * Sends the exchange to a list of endpoints
718     *
719     * @param endpoints  list of endpoints to send to
720     * @return the builder
721     */
722    @SuppressWarnings("unchecked")
723    public Type to(Endpoint... endpoints) {
724        for (Endpoint endpoint : endpoints) {
725            addOutput(new ToDefinition(endpoint));
726        }
727        return (Type) this;
728    }
729
730    /**
731     * Sends the exchange to a list of endpoints
732     *
733     * @param endpoints  list of endpoints to send to
734     * @return the builder
735     */
736    @SuppressWarnings("unchecked")
737    public Type to(Iterable<Endpoint> endpoints) {
738        for (Endpoint endpoint : endpoints) {
739            addOutput(new ToDefinition(endpoint));
740        }
741        return (Type) this;
742    }
743
744    /**
745     * Sends the exchange to a list of endpoints
746     * <p/>
747     * Notice the existing MEP is preserved
748     *
749     * @param pattern the pattern to use for the message exchanges
750     * @param uris  list of endpoints to send to
751     * @return the builder
752     */
753    @SuppressWarnings("unchecked")
754    public Type to(ExchangePattern pattern, String... uris) {
755        for (String uri : uris) {
756            addOutput(new ToDefinition(uri, pattern));
757        }
758        return (Type) this;
759    }
760
761    /**
762     * Sends the exchange to a list of endpoints
763     * <p/>
764     * Notice the existing MEP is preserved
765     *
766     * @param pattern the pattern to use for the message exchanges
767     * @param endpoints  list of endpoints to send to
768     * @return the builder
769     */
770    @SuppressWarnings("unchecked")
771    public Type to(ExchangePattern pattern, Endpoint... endpoints) {
772        for (Endpoint endpoint : endpoints) {
773            addOutput(new ToDefinition(endpoint, pattern));
774        }
775        return (Type) this;
776    }
777
778    /**
779     * Sends the exchange to a list of endpoints
780     *
781     * @param pattern the pattern to use for the message exchanges
782     * @param endpoints  list of endpoints to send to
783     * @return the builder
784     */
785    @SuppressWarnings("unchecked")
786    public Type to(ExchangePattern pattern, Iterable<Endpoint> endpoints) {
787        for (Endpoint endpoint : endpoints) {
788            addOutput(new ToDefinition(endpoint, pattern));
789        }
790        return (Type) this;
791    }
792
793    /**
794     * <a href="http://camel.apache.org/exchange-pattern.html">ExchangePattern:</a>
795     * set the {@link ExchangePattern} into the {@link Exchange}.
796     * <p/>
797     * The pattern set on the {@link Exchange} will
798     *
799     * @param exchangePattern  instance of {@link ExchangePattern}
800     * @return the builder
801     */
802    @SuppressWarnings("unchecked")
803    public Type setExchangePattern(ExchangePattern exchangePattern) {
804        addOutput(new SetExchangePatternDefinition(exchangePattern));
805        return (Type) this;
806    }
807
808    /**
809     * <a href="http://camel.apache.org/exchange-pattern.html">ExchangePattern:</a>
810     * set the exchange's ExchangePattern {@link ExchangePattern} to be InOnly
811     *
812     * @return the builder
813     * @deprecated use {@link #setExchangePattern(org.apache.camel.ExchangePattern)} instead
814     */
815    @Deprecated
816    public Type inOnly() {
817        return setExchangePattern(ExchangePattern.InOnly);
818    }
819
820    /**
821     * Sends the message to the given endpoint using an
822     * <a href="http://camel.apache.org/event-message.html">Event Message</a> or
823     * <a href="http://camel.apache.org/exchange-pattern.html">InOnly exchange pattern</a>
824     * <p/>
825     * Notice the existing MEP is restored after the message has been sent to the given endpoint.
826     *
827     * @param uri The endpoint uri which is used for sending the exchange
828     * @return the builder
829     */
830    public Type inOnly(String uri) {
831        return to(ExchangePattern.InOnly, uri);
832    }
833
834    /**
835     * Sends the message to the given endpoint using an
836     * <a href="http://camel.apache.org/event-message.html">Event Message</a> or 
837     * <a href="http://camel.apache.org/exchange-pattern.html">InOnly exchange pattern</a>
838     * <p/>
839     * Notice the existing MEP is restored after the message has been sent to the given endpoint.
840     *
841     * @param endpoint The endpoint which is used for sending the exchange
842     * @return the builder
843     */
844    public Type inOnly(Endpoint endpoint) {
845        return to(ExchangePattern.InOnly, endpoint);
846    }
847
848    /**
849     * Sends the message to the given endpoints using an
850     * <a href="http://camel.apache.org/event-message.html">Event Message</a> or
851     * <a href="http://camel.apache.org/exchange-pattern.html">InOnly exchange pattern</a>
852     * <p/>
853     * Notice the existing MEP is restored after the message has been sent to the given endpoint.
854     *
855     * @param uris  list of endpoints to send to
856     * @return the builder
857     */
858    public Type inOnly(String... uris) {
859        return to(ExchangePattern.InOnly, uris);
860    }
861
862    /**
863     * Sends the message to the given endpoints using an
864     * <a href="http://camel.apache.org/event-message.html">Event Message</a> or
865     * <a href="http://camel.apache.org/exchange-pattern.html">InOnly exchange pattern</a>
866     * <p/>
867     * Notice the existing MEP is restored after the message has been sent to the given endpoint.
868     *
869     * @param endpoints  list of endpoints to send to
870     * @return the builder
871     */
872    public Type inOnly(Endpoint... endpoints) {
873        return to(ExchangePattern.InOnly, endpoints);
874    }
875
876    /**
877     * Sends the message to the given endpoints using an
878     * <a href="http://camel.apache.org/event-message.html">Event Message</a> or
879     * <a href="http://camel.apache.org/exchange-pattern.html">InOnly exchange pattern</a>
880     * <p/>
881     * Notice the existing MEP is restored after the message has been sent to the given endpoint.
882     *
883     * @param endpoints  list of endpoints to send to
884     * @return the builder
885     */
886    public Type inOnly(Iterable<Endpoint> endpoints) {
887        return to(ExchangePattern.InOnly, endpoints);
888    }
889
890    /**
891     * <a href="http://camel.apache.org/exchange-pattern.html">ExchangePattern:</a>
892     * set the exchange's ExchangePattern {@link ExchangePattern} to be InOut
893     *
894     * @return the builder
895     * @deprecated use {@link #setExchangePattern(org.apache.camel.ExchangePattern)} instead
896     */
897    @Deprecated
898    public Type inOut() {
899        return setExchangePattern(ExchangePattern.InOut);
900    }
901
902    /**
903     * Sends the message to the given endpoint using an
904     * <a href="http://camel.apache.org/request-reply.html">Request Reply</a> or
905     * <a href="http://camel.apache.org/exchange-pattern.html">InOut exchange pattern</a>
906     * <p/>
907     * Notice the existing MEP is restored after the message has been sent to the given endpoint.
908     *
909     * @param uri The endpoint uri which is used for sending the exchange
910     * @return the builder
911     */
912    public Type inOut(String uri) {
913        return to(ExchangePattern.InOut, uri);
914    }
915
916    /**
917     * Sends the message to the given endpoint using an
918     * <a href="http://camel.apache.org/request-reply.html">Request Reply</a> or
919     * <a href="http://camel.apache.org/exchange-pattern.html">InOut exchange pattern</a>
920     * <p/>
921     * Notice the existing MEP is restored after the message has been sent to the given endpoint.
922     *
923     * @param endpoint The endpoint which is used for sending the exchange
924     * @return the builder
925     */
926    public Type inOut(Endpoint endpoint) {
927        return to(ExchangePattern.InOut, endpoint);
928    }
929
930    /**
931     * Sends the message to the given endpoints using an
932     * <a href="http://camel.apache.org/request-reply.html">Request Reply</a> or
933     * <a href="http://camel.apache.org/exchange-pattern.html">InOut exchange pattern</a>
934     * <p/>
935     * Notice the existing MEP is restored after the message has been sent to the given endpoint.
936     *
937     * @param uris  list of endpoints to send to
938     * @return the builder
939     */
940    public Type inOut(String... uris) {
941        return to(ExchangePattern.InOut, uris);
942    }
943
944    /**
945     * Sends the message to the given endpoints using an
946     * <a href="http://camel.apache.org/request-reply.html">Request Reply</a> or
947     * <a href="http://camel.apache.org/exchange-pattern.html">InOut exchange pattern</a>
948     * <p/>
949     * Notice the existing MEP is restored after the message has been sent to the given endpoint.
950     *
951     * @param endpoints  list of endpoints to send to
952     * @return the builder
953     */
954    public Type inOut(Endpoint... endpoints) {
955        return to(ExchangePattern.InOut, endpoints);
956    }
957
958    /**
959     * Sends the message to the given endpoints using an
960     * <a href="http://camel.apache.org/request-reply.html">Request Reply</a> or
961     * <a href="http://camel.apache.org/exchange-pattern.html">InOut exchange pattern</a>
962     * <p/>
963     * Notice the existing MEP is restored after the message has been sent to the given endpoint.
964     *
965     * @param endpoints  list of endpoints to send to
966     * @return the builder
967     */
968    public Type inOut(Iterable<Endpoint> endpoints) {
969        return to(ExchangePattern.InOut, endpoints);
970    }
971
972    /**
973     * Sets the id of this node.
974     * <p/>
975     * <b>Important:</b> If you want to set the id of the route,
976     * then you <b>must</b> use {@link #routeId(String)} instead.
977     *
978     * @param id  the id
979     * @return the builder
980     */
981    @SuppressWarnings("unchecked")
982    public Type id(String id) {
983        if (isOutputSupported() && getOutputs().isEmpty()) {
984            // set id on this
985            setId(id);
986        } else {
987            
988            // set it on last output as this is what the user means to do
989            // for Block(s) with non empty getOutputs() the id probably refers
990            //  to the last definition in the current Block
991            List<ProcessorDefinition<?>> outputs = getOutputs();
992            if (!blocks.isEmpty()) {
993                if (blocks.getLast() instanceof ProcessorDefinition) {
994                    ProcessorDefinition<?> block = (ProcessorDefinition<?>)blocks.getLast();
995                    if (!block.getOutputs().isEmpty()) {
996                        outputs = block.getOutputs();
997                    }
998                }
999            }
1000            if (!getOutputs().isEmpty()) {
1001                outputs.get(outputs.size() - 1).setId(id);
1002            } else {
1003                // the output could be empty
1004                setId(id);
1005            }
1006        }
1007
1008        return (Type) this;
1009    }
1010
1011    /**
1012     * Set the route id for this route.
1013     * <p/>
1014     * <b>Important: </b> Each route in the same {@link org.apache.camel.CamelContext} must have an <b>unique</b> route id.
1015     * If you use the API from {@link org.apache.camel.CamelContext} or {@link ModelCamelContext} to add routes, then any
1016     * new routes which has a route id that matches an old route, then the old route is replaced by the new route.
1017     *
1018     * @param id  the route id, should be unique
1019     * @return the builder
1020     */
1021    @SuppressWarnings("unchecked")
1022    public Type routeId(String id) {
1023        ProcessorDefinition<?> def = this;
1024
1025        RouteDefinition route = ProcessorDefinitionHelper.getRoute(def);
1026        if (route != null) {
1027            route.setId(id);
1028        }
1029
1030        return (Type) this;
1031    }
1032
1033    /**
1034     * Set the route description for this route
1035     *
1036     * @param description the route description
1037     * @return the builder
1038     */
1039    @SuppressWarnings("unchecked")
1040    public Type routeDescription(String description) {
1041        ProcessorDefinition<?> def = this;
1042
1043        RouteDefinition route = ProcessorDefinitionHelper.getRoute(def);
1044        if (route != null) {
1045            DescriptionDefinition desc = new DescriptionDefinition();
1046            desc.setText(description);
1047            route.setDescription(desc);
1048        }
1049
1050        return (Type) this;
1051    }
1052
1053    /**
1054     * <a href="http://camel.apache.org/multicast.html">Multicast EIP:</a>
1055     * Multicasts messages to all its child outputs; so that each processor and
1056     * destination gets a copy of the original message to avoid the processors
1057     * interfering with each other.
1058     *
1059     * @return the builder
1060     */
1061    public MulticastDefinition multicast() {
1062        MulticastDefinition answer = new MulticastDefinition();
1063        addOutput(answer);
1064        return answer;
1065    }
1066
1067    /**
1068     * <a href="http://camel.apache.org/multicast.html">Multicast EIP:</a>
1069     * Multicasts messages to all its child outputs; so that each processor and
1070     * destination gets a copy of the original message to avoid the processors
1071     * interfering with each other.
1072     *
1073     * @param aggregationStrategy the strategy used to aggregate responses for
1074     *          every part
1075     * @param parallelProcessing if is <tt>true</tt> camel will fork thread to call the endpoint producer
1076     * @return the builder
1077     */
1078    public MulticastDefinition multicast(AggregationStrategy aggregationStrategy, boolean parallelProcessing) {
1079        MulticastDefinition answer = new MulticastDefinition();
1080        addOutput(answer);
1081        answer.setAggregationStrategy(aggregationStrategy);
1082        answer.setParallelProcessing(parallelProcessing);
1083        return answer;
1084    }
1085
1086    /**
1087     * <a href="http://camel.apache.org/multicast.html">Multicast EIP:</a>
1088     * Multicasts messages to all its child outputs; so that each processor and
1089     * destination gets a copy of the original message to avoid the processors
1090     * interfering with each other.
1091     *
1092     * @param aggregationStrategy the strategy used to aggregate responses for every part
1093     * @return the builder
1094     */
1095    public MulticastDefinition multicast(AggregationStrategy aggregationStrategy) {
1096        MulticastDefinition answer = new MulticastDefinition();
1097        addOutput(answer);
1098        answer.setAggregationStrategy(aggregationStrategy);
1099        return answer;
1100    }
1101
1102    /**
1103     * <a href="http://camel.apache.org/pipes-nd-filters.html">Pipes and Filters EIP:</a>
1104     * Creates a {@link Pipeline} so that the message
1105     * will get processed by each endpoint in turn and for request/response the
1106     * output of one endpoint will be the input of the next endpoint
1107     *
1108     * @return the builder
1109     */
1110    public PipelineDefinition pipeline() {
1111        PipelineDefinition answer = new PipelineDefinition();
1112        addOutput(answer);
1113        return answer;
1114    }
1115
1116    /**
1117     * <a href="http://camel.apache.org/pipes-nd-filters.html">Pipes and Filters EIP:</a>
1118     * Creates a {@link Pipeline} of the list of endpoints so that the message
1119     * will get processed by each endpoint in turn and for request/response the
1120     * output of one endpoint will be the input of the next endpoint
1121     *
1122     * @param uris  list of endpoints
1123     * @return the builder
1124     */
1125    public Type pipeline(String... uris) {
1126        return to(uris);
1127    }
1128
1129    /**
1130     * <a href="http://camel.apache.org/pipes-nd-filters.html">Pipes and Filters EIP:</a>
1131     * Creates a {@link Pipeline} of the list of endpoints so that the message
1132     * will get processed by each endpoint in turn and for request/response the
1133     * output of one endpoint will be the input of the next endpoint
1134     *
1135     * @param endpoints  list of endpoints
1136     * @return the builder
1137     */
1138    public Type pipeline(Endpoint... endpoints) {
1139        return to(endpoints);
1140    }
1141
1142    /**
1143     * <a href="http://camel.apache.org/pipes-nd-filters.html">Pipes and Filters EIP:</a>
1144     * Creates a {@link Pipeline} of the list of endpoints so that the message
1145     * will get processed by each endpoint in turn and for request/response the
1146     * output of one endpoint will be the input of the next endpoint
1147     *
1148     * @param endpoints  list of endpoints
1149     * @return the builder
1150     */
1151    public Type pipeline(Collection<Endpoint> endpoints) {
1152        return to(endpoints);
1153    }
1154
1155    /**
1156     * Continues processing the {@link org.apache.camel.Exchange} using asynchronous routing engine.
1157     *
1158     * @return the builder
1159     */
1160    public ThreadsDefinition threads() {
1161        ThreadsDefinition answer = new ThreadsDefinition();
1162        addOutput(answer);
1163        return answer;
1164    }
1165
1166    /**
1167     * Continues processing the {@link org.apache.camel.Exchange} using asynchronous routing engine.
1168     *
1169     * @param poolSize the core pool size
1170     * @return the builder
1171     */
1172    public ThreadsDefinition threads(int poolSize) {
1173        ThreadsDefinition answer = new ThreadsDefinition();
1174        answer.setPoolSize(poolSize);
1175        addOutput(answer);
1176        return answer;
1177    }
1178
1179    /**
1180     * Continues processing the {@link org.apache.camel.Exchange} using asynchronous routing engine.
1181     *
1182     * @param poolSize    the core pool size
1183     * @param maxPoolSize the maximum pool size
1184     * @return the builder
1185     */
1186    public ThreadsDefinition threads(int poolSize, int maxPoolSize) {
1187        ThreadsDefinition answer = new ThreadsDefinition();
1188        answer.setPoolSize(poolSize);
1189        answer.setMaxPoolSize(maxPoolSize);
1190        addOutput(answer);
1191        return answer;
1192    }
1193    
1194    /**
1195     * Continues processing the {@link org.apache.camel.Exchange} using asynchronous routing engine.
1196     *
1197     * @param poolSize    the core pool size
1198     * @param maxPoolSize the maximum pool size
1199     * @param threadName the thread pool name
1200     * @return the builder
1201     */
1202    public ThreadsDefinition threads(int poolSize, int maxPoolSize, String threadName) {
1203        ThreadsDefinition answer = new ThreadsDefinition();
1204        answer.setPoolSize(poolSize);
1205        answer.setMaxPoolSize(maxPoolSize);
1206        answer.setThreadName(threadName);
1207        addOutput(answer);
1208        return answer;
1209    }
1210
1211    /**
1212     * Wraps the sub route using AOP allowing you to do before and after work (AOP around).
1213     *
1214     * @return the builder
1215     * @deprecated to be removed in the near future. Instead you can use interceptors or processors to do AOP with Camel.
1216     */
1217    @Deprecated
1218    public AOPDefinition aop() {
1219        AOPDefinition answer = new AOPDefinition();
1220        addOutput(answer);
1221        return answer;
1222    }
1223
1224    /**
1225     * Ends the current block
1226     *
1227     * @return the builder
1228     */
1229    public ProcessorDefinition<?> end() {
1230        // must do this ugly cast to avoid compiler error on AIX/HP-UX
1231        ProcessorDefinition<?> defn = (ProcessorDefinition<?>) this;
1232        
1233        // when using choice .. when .. otherwise - doTry .. doCatch .. doFinally we should always
1234        // end the choice/try definition to avoid having to use 2 x end() in the route
1235        // this is counter intuitive for end users
1236        // TODO (camel-3.0): this should be done inside of TryDefinition or even better
1237        //  in Block(s) in general, but the api needs to be revisited for that.
1238        if (defn instanceof TryDefinition || defn instanceof ChoiceDefinition) {
1239            popBlock();
1240        }
1241
1242        if (blocks.isEmpty()) {
1243            if (parent == null) {
1244                return this.endParent();
1245            }
1246            return parent.endParent();
1247        }
1248        popBlock();
1249        return this.endParent();
1250    }
1251
1252    /**
1253     * Strategy to allow {@link ProcessorDefinition}s to have special logic when using end() in the DSL
1254     * to return back to the intended parent.
1255     * <p/>
1256     * For example a content based router we return back to the {@link ChoiceDefinition} when we end()
1257     * from a {@link WhenDefinition}.
1258     *
1259     * @return the end
1260     */
1261    public ProcessorDefinition<?> endParent() {
1262        return this;
1263    }
1264
1265    /**
1266     * Ends the current block and returns back to the {@link ChoiceDefinition choice()} DSL.
1267     * <p/>
1268     * <b>Important:</b> If you want to end the entire choice block, then use {@link #end()} instead.
1269     * The purpose of {@link #endChoice()} is to return <i>control</i> back to the {@link ChoiceDefinition choice()} DSL,
1270     * so you can add subsequent <tt>when</tt> and <tt>otherwise</tt> to the choice. There can be situations where
1271     * you would need to use {@link #endChoice()} often when you add additional EIPs inside the <tt>when</tt>'s, and
1272     * the DSL <t>looses</t> scope when using a regular {@link #end()}, and you would need to use this {@link #endChoice()}
1273     * to return back the scope to the {@link ChoiceDefinition choice()} DSL.
1274     * <p/>
1275     * For more details and examples see also this FAQ:
1276     * <a href="http://camel.apache.org/why-can-i-not-use-when-or-otherwise-in-a-java-camel-route.html">Why can I not use when or otherwise in a Java Camel route </a>.
1277     *
1278     * @return the choice builder
1279     */
1280    public ChoiceDefinition endChoice() {
1281        // are we nested choice?
1282        ProcessorDefinition<?> def = this;
1283        if (def.getParent() instanceof WhenDefinition) {
1284            return (ChoiceDefinition) def.getParent().getParent();
1285        }
1286
1287        // are we already a choice?
1288        if (def instanceof ChoiceDefinition) {
1289            return (ChoiceDefinition) def;
1290        }
1291
1292        // okay end this and get back to the choice
1293        def = end();
1294        if (def instanceof WhenDefinition) {
1295            return (ChoiceDefinition) def.getParent();
1296        } else if (def instanceof OtherwiseDefinition) {
1297            return (ChoiceDefinition) def.getParent();
1298        } else {
1299            return (ChoiceDefinition) def;
1300        }
1301    }
1302
1303    /**
1304     * Ends the current block and returns back to the {@link org.apache.camel.model.rest.RestDefinition rest()} DSL.
1305     *
1306     * @return the builder
1307     */
1308    public RestDefinition endRest() {
1309        ProcessorDefinition<?> def = this;
1310
1311        RouteDefinition route = ProcessorDefinitionHelper.getRoute(def);
1312        if (route != null) {
1313            return route.getRestDefinition();
1314        }
1315
1316        throw new IllegalArgumentException("Cannot find RouteDefinition to allow endRest");
1317    }
1318
1319    /**
1320     * Ends the current block and returns back to the {@link TryDefinition doTry()} DSL.
1321     *
1322     * @return the builder
1323     */
1324    public TryDefinition endDoTry() {
1325        ProcessorDefinition<?> def = this;
1326
1327        // are we already a try?
1328        if (def instanceof TryDefinition) {
1329            return (TryDefinition) def;
1330        }
1331
1332        // okay end this and get back to the try
1333        def = end();
1334        return (TryDefinition) def;
1335    }
1336
1337    /**
1338     * <a href="http://camel.apache.org/idempotent-consumer.html">Idempotent consumer EIP:</a>
1339     * Creates an {@link org.apache.camel.processor.idempotent.IdempotentConsumer IdempotentConsumer}
1340     * to avoid duplicate messages
1341     *
1342     * @param messageIdExpression  expression to test of duplicate messages
1343     * @return the builder
1344     */
1345    public IdempotentConsumerDefinition idempotentConsumer(Expression messageIdExpression) {
1346        IdempotentConsumerDefinition answer = new IdempotentConsumerDefinition();
1347        answer.setExpression(ExpressionNodeHelper.toExpressionDefinition(messageIdExpression));
1348        addOutput(answer);
1349        return answer;
1350    }
1351
1352    /**
1353     * <a href="http://camel.apache.org/idempotent-consumer.html">Idempotent consumer EIP:</a>
1354     * Creates an {@link org.apache.camel.processor.idempotent.IdempotentConsumer IdempotentConsumer}
1355     * to avoid duplicate messages
1356     *
1357     * @param messageIdExpression  expression to test of duplicate messages
1358     * @param idempotentRepository  the repository to use for duplicate check
1359     * @return the builder
1360     */
1361    public IdempotentConsumerDefinition idempotentConsumer(Expression messageIdExpression, IdempotentRepository<?> idempotentRepository) {
1362        IdempotentConsumerDefinition answer = new IdempotentConsumerDefinition(messageIdExpression, idempotentRepository);
1363        addOutput(answer);
1364        return answer;
1365    }
1366
1367    /**
1368     * <a href="http://camel.apache.org/idempotent-consumer.html">Idempotent consumer EIP:</a>
1369     * Creates an {@link org.apache.camel.processor.idempotent.IdempotentConsumer IdempotentConsumer}
1370     * to avoid duplicate messages
1371     *
1372     * @param idempotentRepository the repository to use for duplicate check
1373     * @return the builder used to create the expression
1374     * @deprecated will be removed in Camel 3.0. Instead use any of the other methods
1375     */
1376    @Deprecated
1377    public ExpressionClause<IdempotentConsumerDefinition> idempotentConsumer(IdempotentRepository<?> idempotentRepository) {
1378        IdempotentConsumerDefinition answer = new IdempotentConsumerDefinition();
1379        answer.setMessageIdRepository(idempotentRepository);
1380        addOutput(answer);
1381        return ExpressionClause.createAndSetExpression(answer);
1382    }
1383
1384    /**
1385     * <a href="http://camel.apache.org/message-filter.html">Message Filter EIP:</a>
1386     * Creates a predicate expression which only if it is <tt>true</tt> then the
1387     * exchange is forwarded to the destination
1388     *
1389     * @return the clause used to create the filter expression
1390     */
1391    public ExpressionClause<? extends FilterDefinition> filter() {
1392        FilterDefinition filter = new FilterDefinition();
1393        addOutput(filter);
1394        return ExpressionClause.createAndSetExpression(filter);
1395    }
1396
1397    /**
1398     * <a href="http://camel.apache.org/message-filter.html">Message Filter EIP:</a>
1399     * Creates a predicate which is applied and only if it is <tt>true</tt> then the
1400     * exchange is forwarded to the destination
1401     *
1402     * @param predicate  predicate to use
1403     * @return the builder 
1404     */
1405    public FilterDefinition filter(Predicate predicate) {
1406        FilterDefinition filter = new FilterDefinition(predicate);
1407        addOutput(filter);
1408        return filter;
1409    }
1410
1411    /**
1412     * <a href="http://camel.apache.org/message-filter.html">Message Filter EIP:</a>
1413     * Creates a predicate expression which only if it is <tt>true</tt> then the
1414     * exchange is forwarded to the destination
1415     *
1416     * @param expression  the predicate expression to use
1417     * @return the builder
1418     */
1419    public FilterDefinition filter(ExpressionDefinition expression) {
1420        FilterDefinition filter = new FilterDefinition(expression);
1421        addOutput(filter);
1422        return filter;
1423    }
1424
1425    /**
1426     * <a href="http://camel.apache.org/message-filter.html">Message Filter EIP:</a>
1427     * Creates a predicate language expression which only if it is <tt>true</tt> then the
1428     * exchange is forwarded to the destination
1429     *
1430     * @param language     language for expression
1431     * @param expression   the expression
1432     * @return the builder
1433     */
1434    public FilterDefinition filter(String language, String expression) {
1435        return filter(new LanguageExpression(language, expression));
1436    }
1437    
1438    /**
1439     * Creates a validation expression which only if it is <tt>true</tt> then the
1440     * exchange is forwarded to the destination.
1441     * Otherwise a {@link org.apache.camel.processor.validation.PredicateValidationException} is thrown.
1442     *
1443     * @param expression  the expression
1444     * @return the builder
1445     */
1446    public ValidateDefinition validate(Expression expression) {
1447        ValidateDefinition answer = new ValidateDefinition(expression);
1448        addOutput(answer);
1449        return answer;
1450    }
1451
1452    /**
1453     * Creates a validation expression which only if it is <tt>true</tt> then the
1454     * exchange is forwarded to the destination.
1455     * Otherwise a {@link org.apache.camel.processor.validation.PredicateValidationException} is thrown.
1456     *
1457     * @param predicate  the predicate
1458     * @return the builder
1459     */
1460    public ValidateDefinition validate(Predicate predicate) {
1461        ValidateDefinition answer = new ValidateDefinition(predicate);
1462        addOutput(answer);
1463        return answer;
1464    }
1465
1466    /**
1467     * Creates a validation expression which only if it is <tt>true</tt> then the
1468     * exchange is forwarded to the destination.
1469     * Otherwise a {@link org.apache.camel.processor.validation.PredicateValidationException} is thrown.
1470     *
1471     * @return the builder
1472     */
1473    public ExpressionClause<ValidateDefinition> validate() {
1474        ValidateDefinition answer = new ValidateDefinition();
1475        addOutput(answer);
1476        return ExpressionClause.createAndSetExpression(answer);
1477    }
1478
1479    /**
1480     * <a href="http://camel.apache.org/load-balancer.html">Load Balancer EIP:</a>
1481     * Creates a loadbalance
1482     *
1483     * @return  the builder
1484     */
1485    public LoadBalanceDefinition loadBalance() {
1486        LoadBalanceDefinition answer = new LoadBalanceDefinition();
1487        addOutput(answer);
1488        return answer;
1489    }
1490
1491    /**
1492     * <a href="http://camel.apache.org/load-balancer.html">Load Balancer EIP:</a>
1493     * Creates a loadbalance
1494     *
1495     * @param loadBalancer a custom load balancer to use
1496     * @return  the builder
1497     */
1498    public LoadBalanceDefinition loadBalance(LoadBalancer loadBalancer) {
1499        LoadBalanceDefinition answer = new LoadBalanceDefinition();
1500        addOutput(answer);
1501        return answer.loadBalance(loadBalancer);
1502    }
1503
1504    /**
1505     * Creates a log message to be logged at INFO level.
1506     *
1507     * @param message the log message, (you can use {@link org.apache.camel.language.simple.SimpleLanguage} syntax)
1508     * @return the builder
1509     */
1510    @SuppressWarnings("unchecked")
1511    public Type log(String message) {
1512        LogDefinition answer = new LogDefinition(message);
1513        addOutput(answer);
1514        return (Type) this;
1515    }
1516
1517    /**
1518     * Creates a log message to be logged at the given level.
1519     *
1520     * @param loggingLevel the logging level to use
1521     * @param message the log message, (you can use {@link org.apache.camel.language.simple.SimpleLanguage} syntax)
1522     * @return the builder
1523     */
1524    @SuppressWarnings("unchecked")
1525    public Type log(LoggingLevel loggingLevel, String message) {
1526        LogDefinition answer = new LogDefinition(message);
1527        answer.setLoggingLevel(loggingLevel);
1528        addOutput(answer);
1529        return (Type) this;
1530    }
1531
1532    /**
1533     * Creates a log message to be logged at the given level and name.
1534     *
1535     * @param loggingLevel the logging level to use
1536     * @param logName the log name to use
1537     * @param message the log message, (you can use {@link org.apache.camel.language.simple.SimpleLanguage} syntax)
1538     * @return the builder
1539     */
1540    @SuppressWarnings("unchecked")
1541    public Type log(LoggingLevel loggingLevel, String logName, String message) {
1542        LogDefinition answer = new LogDefinition(message);
1543        answer.setLoggingLevel(loggingLevel);
1544        answer.setLogName(logName);
1545        addOutput(answer);
1546        return (Type) this;
1547    }
1548
1549    /**
1550     * Creates a log message to be logged at the given level using provided logger.
1551     *
1552     * @param loggingLevel the logging level to use
1553     * @param logger the logger to use
1554     * @param message the log message, (you can use {@link org.apache.camel.language.simple.SimpleLanguage} syntax)
1555     * @return the builder
1556     */
1557    @SuppressWarnings("unchecked")
1558    public Type log(LoggingLevel loggingLevel, Logger logger, String message) {
1559        LogDefinition answer = new LogDefinition(message);
1560        answer.setLoggingLevel(loggingLevel);
1561        answer.setLogger(logger);
1562        addOutput(answer);
1563        return (Type) this;
1564    }
1565
1566    /**
1567     * Creates a log message to be logged at the given level and name.
1568     *
1569     *
1570     * @param loggingLevel the logging level to use
1571     * @param logName the log name to use
1572     * @param marker  log marker name
1573     * @param message the log message, (you can use {@link org.apache.camel.language.simple.SimpleLanguage} syntax)
1574     * @return the builder
1575     */
1576    @SuppressWarnings("unchecked")
1577    public Type log(LoggingLevel loggingLevel, String logName, String marker, String message) {
1578        LogDefinition answer = new LogDefinition(message);
1579        answer.setLoggingLevel(loggingLevel);
1580        answer.setLogName(logName);
1581        answer.setMarker(marker);
1582        addOutput(answer);
1583        return (Type) this;
1584    }
1585
1586    /**
1587     * Creates a log message to be logged at the given level using provided logger.
1588     *
1589     *
1590     * @param loggingLevel the logging level to use
1591     * @param logger the logger to use
1592     * @param marker  log marker name
1593     * @param message the log message, (you can use {@link org.apache.camel.language.simple.SimpleLanguage} syntax)
1594     * @return the builder
1595     */
1596    @SuppressWarnings("unchecked")
1597    public Type log(LoggingLevel loggingLevel, Logger logger, String marker, String message) {
1598        LogDefinition answer = new LogDefinition(message);
1599        answer.setLoggingLevel(loggingLevel);
1600        answer.setLogger(logger);
1601        answer.setMarker(marker);
1602        addOutput(answer);
1603        return (Type) this;
1604    }
1605
1606    /**
1607     * <a href="http://camel.apache.org/content-based-router.html">Content Based Router EIP:</a>
1608     * Creates a choice of one or more predicates with an otherwise clause
1609     *
1610     * @return the builder for a choice expression
1611     */
1612    public ChoiceDefinition choice() {
1613        ChoiceDefinition answer = new ChoiceDefinition();
1614        addOutput(answer);
1615        return answer;
1616    }
1617
1618    /**
1619     * Creates a try/catch block
1620     *
1621     * @return the builder for a tryBlock expression
1622     */
1623    public TryDefinition doTry() {
1624        TryDefinition answer = new TryDefinition();
1625        addOutput(answer);
1626        return answer;
1627    }
1628
1629    /**
1630     * <a href="http://camel.apache.org/recipient-list.html">Recipient List EIP:</a>
1631     * Creates a dynamic recipient list allowing you to route messages to a number of dynamically specified recipients.
1632     * <p/>
1633     * Will use comma as default delimiter.
1634     *
1635     * @param recipients expression to decide the destinations
1636     * @return the builder
1637     */
1638    public RecipientListDefinition<Type> recipientList(Expression recipients) {
1639        RecipientListDefinition<Type> answer = new RecipientListDefinition<Type>(recipients);
1640        addOutput(answer);
1641        return answer;
1642    }
1643
1644    /**
1645     * <a href="http://camel.apache.org/recipient-list.html">Recipient List EIP:</a>
1646     * Creates a dynamic recipient list allowing you to route messages to a number of dynamically specified recipients
1647     *
1648     * @param recipients expression to decide the destinations
1649     * @param delimiter  a custom delimiter to use
1650     * @return the builder
1651     */
1652    public RecipientListDefinition<Type> recipientList(Expression recipients, String delimiter) {
1653        RecipientListDefinition<Type> answer = new RecipientListDefinition<Type>(recipients);
1654        answer.setDelimiter(delimiter);
1655        addOutput(answer);
1656        return answer;
1657    }
1658
1659    /**
1660     * <a href="http://camel.apache.org/recipient-list.html">Recipient List EIP:</a>
1661     * Creates a dynamic recipient list allowing you to route messages to a number of dynamically specified recipients
1662     *
1663     * @param delimiter  a custom delimiter to use
1664     * @return the builder
1665     */
1666    public ExpressionClause<RecipientListDefinition<Type>> recipientList(String delimiter) {
1667        RecipientListDefinition<Type> answer = new RecipientListDefinition<Type>();
1668        answer.setDelimiter(delimiter);
1669        addOutput(answer);
1670        return ExpressionClause.createAndSetExpression(answer);
1671    }
1672
1673    /**
1674     * <a href="http://camel.apache.org/recipient-list.html">Recipient List EIP:</a>
1675     * Creates a dynamic recipient list allowing you to route messages to a number of dynamically specified recipients
1676     *
1677     * @return the expression clause to configure the expression to decide the destinations
1678     */
1679    public ExpressionClause<RecipientListDefinition<Type>> recipientList() {
1680        RecipientListDefinition<Type> answer = new RecipientListDefinition<Type>();
1681        addOutput(answer);
1682        return ExpressionClause.createAndSetExpression(answer);
1683    }
1684
1685    /**
1686     * <a href="http://camel.apache.org/routing-slip.html">Routing Slip EIP:</a>
1687     * Creates a routing slip allowing you to route a message consecutively through a series of processing
1688     * steps where the sequence of steps is not known at design time and can vary for each message.
1689     * <p/>
1690     * The route slip will be evaluated <i>once</i>, use {@link #dynamicRouter()} if you need even more dynamic routing.
1691     *
1692     * @param header  is the header that the {@link org.apache.camel.processor.RoutingSlip RoutingSlip}
1693     *                class will look in for the list of URIs to route the message to.
1694     * @param uriDelimiter  is the delimiter that will be used to split up
1695     *                      the list of URIs in the routing slip.
1696     * @return the builder
1697     * @deprecated prefer to use {@link #routingSlip(org.apache.camel.Expression, String)} instead
1698     */
1699    @Deprecated
1700    public Type routingSlip(String header, String uriDelimiter) {
1701        RoutingSlipDefinition<Type> answer = new RoutingSlipDefinition<Type>(header, uriDelimiter);
1702        addOutput(answer);
1703        return (Type) this;
1704    }
1705
1706    /**
1707     * <a href="http://camel.apache.org/routing-slip.html">Routing Slip EIP:</a>
1708     * Creates a routing slip allowing you to route a message consecutively through a series of processing
1709     * steps where the sequence of steps is not known at design time and can vary for each message.
1710     * <p/>
1711     * The list of URIs will be split based on the default delimiter {@link RoutingSlipDefinition#DEFAULT_DELIMITER}
1712     * <p/>
1713     * The route slip will be evaluated <i>once</i>, use {@link #dynamicRouter()} if you need even more dynamic routing.
1714     *
1715     * @param header  is the header that the {@link org.apache.camel.processor.RoutingSlip RoutingSlip}
1716     *                class will look in for the list of URIs to route the message to.
1717     * @return the builder
1718     * @deprecated prefer to use {@link #routingSlip(org.apache.camel.Expression)} instead
1719     */
1720    @Deprecated
1721    public Type routingSlip(String header) {
1722        RoutingSlipDefinition<Type> answer = new RoutingSlipDefinition<Type>(header);
1723        addOutput(answer);
1724        return (Type) this;
1725    }
1726    
1727    /**
1728     * <a href="http://camel.apache.org/routing-slip.html">Routing Slip EIP:</a>
1729     * Creates a routing slip allowing you to route a message consecutively through a series of processing
1730     * steps where the sequence of steps is not known at design time and can vary for each message.
1731     * <p/>
1732     * The route slip will be evaluated <i>once</i>, use {@link #dynamicRouter()} if you need even more dynamic routing.
1733     *
1734     * @param header  is the header that the {@link org.apache.camel.processor.RoutingSlip RoutingSlip}
1735     *                class will look in for the list of URIs to route the message to.
1736     * @param uriDelimiter  is the delimiter that will be used to split up
1737     *                      the list of URIs in the routing slip.
1738     * @param ignoreInvalidEndpoints if this parameter is true, routingSlip will ignore the endpoints which
1739     *                               cannot be resolved or a producer cannot be created or started 
1740     * @return the builder
1741     * @deprecated prefer to use {@link #routingSlip()} instead
1742     */
1743    @Deprecated
1744    public Type routingSlip(String header, String uriDelimiter, boolean ignoreInvalidEndpoints) {
1745        RoutingSlipDefinition<Type> answer = new RoutingSlipDefinition<Type>(header, uriDelimiter);
1746        answer.setIgnoreInvalidEndpoints(ignoreInvalidEndpoints);
1747        addOutput(answer);
1748        return (Type) this;
1749    }
1750
1751    /**
1752     * <a href="http://camel.apache.org/routing-slip.html">Routing Slip EIP:</a>
1753     * Creates a routing slip allowing you to route a message consecutively through a series of processing
1754     * steps where the sequence of steps is not known at design time and can vary for each message.
1755     * <p/>
1756     * The list of URIs will be split based on the default delimiter {@link RoutingSlipDefinition#DEFAULT_DELIMITER}
1757     * <p/>
1758     * The route slip will be evaluated <i>once</i>, use {@link #dynamicRouter()} if you need even more dynamic routing.
1759     *
1760     * @param header  is the header that the {@link org.apache.camel.processor.RoutingSlip RoutingSlip}
1761     *                class will look in for the list of URIs to route the message to.
1762     * @param ignoreInvalidEndpoints if this parameter is true, routingSlip will ignore the endpoints which
1763     *                               cannot be resolved or a producer cannot be created or started 
1764     * @return the builder
1765     * @deprecated prefer to use {@link #routingSlip()} instead
1766     */
1767    @Deprecated
1768    public Type routingSlip(String header, boolean ignoreInvalidEndpoints) {
1769        RoutingSlipDefinition<Type> answer = new RoutingSlipDefinition<Type>(header);
1770        answer.setIgnoreInvalidEndpoints(ignoreInvalidEndpoints);
1771        addOutput(answer);
1772        return (Type) this;
1773    }
1774    
1775    /**
1776     * <a href="http://camel.apache.org/routing-slip.html">Routing Slip EIP:</a>
1777     * Creates a routing slip allowing you to route a message consecutively through a series of processing
1778     * steps where the sequence of steps is not known at design time and can vary for each message.
1779     * <p/>
1780     * The route slip will be evaluated <i>once</i>, use {@link #dynamicRouter()} if you need even more dynamic routing.
1781     *
1782     * @param expression  to decide the destinations
1783     * @param uriDelimiter  is the delimiter that will be used to split up
1784     *                      the list of URIs in the routing slip.
1785     * @return the builder
1786     */
1787    public RoutingSlipDefinition<Type> routingSlip(Expression expression, String uriDelimiter) {
1788        RoutingSlipDefinition<Type> answer = new RoutingSlipDefinition<Type>(expression, uriDelimiter);
1789        addOutput(answer);
1790        return answer;
1791    }
1792
1793    /**
1794     * <a href="http://camel.apache.org/routing-slip.html">Routing Slip EIP:</a>
1795     * Creates a routing slip allowing you to route a message consecutively through a series of processing
1796     * steps where the sequence of steps is not known at design time and can vary for each message.
1797     * <p/>
1798     * The list of URIs will be split based on the default delimiter {@link RoutingSlipDefinition#DEFAULT_DELIMITER}
1799     * <p/>
1800     * The route slip will be evaluated <i>once</i>, use {@link #dynamicRouter()} if you need even more dynamic routing.
1801     *
1802     * @param expression  to decide the destinations
1803     * @return the builder
1804     */
1805    public RoutingSlipDefinition<Type> routingSlip(Expression expression) {
1806        RoutingSlipDefinition<Type> answer = new RoutingSlipDefinition<Type>(expression);
1807        addOutput(answer);
1808        return answer;
1809    }
1810    
1811    /**
1812     * <a href="http://camel.apache.org/routing-slip.html">Routing Slip EIP:</a>
1813     * Creates a routing slip allowing you to route a message consecutively through a series of processing
1814     * steps where the sequence of steps is not known at design time and can vary for each message.
1815     * <p/>
1816     * The list of URIs will be split based on the default delimiter {@link RoutingSlipDefinition#DEFAULT_DELIMITER}
1817     * <p/>
1818     * The route slip will be evaluated <i>once</i>, use {@link #dynamicRouter()} if you need even more dynamic routing.
1819     *
1820     * @return the expression clause to configure the expression to decide the destinations
1821     */
1822    public ExpressionClause<RoutingSlipDefinition<Type>> routingSlip() {
1823        RoutingSlipDefinition<Type> answer = new RoutingSlipDefinition<Type>();
1824        addOutput(answer);
1825        return ExpressionClause.createAndSetExpression(answer);
1826    }
1827
1828    /**
1829     * <a href="http://camel.apache.org/dynamic-router.html">Dynamic Router EIP:</a>
1830     * Creates a dynamic router allowing you to route a message consecutively through a series of processing
1831     * steps where the sequence of steps is not known at design time and can vary for each message.
1832     * <p/>
1833     * <br/><b>Important:</b> The expression will be invoked repeatedly until it returns <tt>null</tt>, so be sure it does that,
1834     * otherwise it will be invoked endlessly.
1835     *
1836     * @param expression  to decide the destinations, which will be invoked repeatedly
1837     *                    until it evaluates <tt>null</tt> to indicate no more destinations.
1838     * @return the builder
1839     */
1840    public DynamicRouterDefinition<Type> dynamicRouter(Expression expression) {
1841        DynamicRouterDefinition<Type> answer = new DynamicRouterDefinition<Type>(expression);
1842        addOutput(answer);
1843        return answer;
1844    }
1845
1846    /**
1847     * <a href="http://camel.apache.org/dynamic-router.html">Dynamic Router EIP:</a>
1848     * Creates a dynamic router allowing you to route a message consecutively through a series of processing
1849     * steps where the sequence of steps is not known at design time and can vary for each message.
1850     * <p/>
1851     * <br/><b>Important:</b> The expression will be invoked repeatedly until it returns <tt>null</tt>, so be sure it does that,
1852     * otherwise it will be invoked endlessly.
1853     *
1854     * @return the expression clause to configure the expression to decide the destinations,
1855     * which will be invoked repeatedly until it evaluates <tt>null</tt> to indicate no more destinations.
1856     */
1857    public ExpressionClause<DynamicRouterDefinition<Type>> dynamicRouter() {
1858        DynamicRouterDefinition<Type> answer = new DynamicRouterDefinition<Type>();
1859        addOutput(answer);
1860        return ExpressionClause.createAndSetExpression(answer);
1861    }
1862
1863    /**
1864     * <a href="http://camel.apache.org/sampling.html">Sampling Throttler</a>
1865     * Creates a sampling throttler allowing you to extract a sample of
1866     * exchanges from the traffic on a route. It is configured with a sampling
1867     * period, during which only a single exchange is allowed to pass through.
1868     * All other exchanges will be stopped.
1869     * <p/>
1870     * Default period is one second.
1871     *
1872     * @return the builder
1873     */
1874    public SamplingDefinition sample() {
1875        return sample(1, TimeUnit.SECONDS);
1876    }
1877
1878    /**
1879     * <a href="http://camel.apache.org/sampling.html">Sampling Throttler</a>
1880     * Creates a sampling throttler allowing you to extract a sample of exchanges
1881     * from the traffic through a route. It is configured with a sampling period
1882     * during which only a single exchange is allowed to pass through.
1883     * All other exchanges will be stopped.
1884     *
1885     * @param samplePeriod this is the sample interval, only one exchange is
1886     *            allowed through in this interval
1887     * @param unit this is the units for the samplePeriod e.g. Seconds
1888     * @return the builder
1889     */
1890    public SamplingDefinition sample(long samplePeriod, TimeUnit unit) {
1891        SamplingDefinition answer = new SamplingDefinition(samplePeriod, unit);
1892        addOutput(answer);
1893        return answer;
1894    }
1895
1896    /**
1897     * <a href="http://camel.apache.org/sampling.html">Sampling Throttler</a>
1898     * Creates a sampling throttler allowing you to extract a sample of exchanges
1899     * from the traffic through a route. It is configured with a sampling message frequency
1900     * during which only a single exchange is allowed to pass through.
1901     * All other exchanges will be stopped.
1902     *
1903     * @param messageFrequency this is the sample message frequency, only one exchange is 
1904     *              allowed through for this many messages received
1905     * @return the builder
1906     */
1907    public SamplingDefinition sample(long messageFrequency) {
1908        SamplingDefinition answer = new SamplingDefinition(messageFrequency);
1909        addOutput(answer);
1910        return answer;
1911    }
1912
1913    /**
1914     * <a href="http://camel.apache.org/splitter.html">Splitter EIP:</a>
1915     * Creates a splitter allowing you split a message into a number of pieces and process them individually.
1916     * <p>
1917     * This splitter responds with the original input message. You can use a custom {@link AggregationStrategy} to
1918     * control what to respond from the splitter.
1919     *
1920     * @return the expression clause builder for the expression on which to split
1921     */
1922    public ExpressionClause<SplitDefinition> split() {
1923        SplitDefinition answer = new SplitDefinition();
1924        addOutput(answer);
1925        return ExpressionClause.createAndSetExpression(answer);
1926    }
1927
1928    /**
1929     * <a href="http://camel.apache.org/splitter.html">Splitter EIP:</a>
1930     * Creates a splitter allowing you split a message into a number of pieces and process them individually.
1931     * <p>
1932     * This splitter responds with the original input message. You can use a custom {@link AggregationStrategy} to
1933     * control what to respond from the splitter.
1934     *
1935     * @param expression  the expression on which to split the message
1936     * @return the builder
1937     */
1938    public SplitDefinition split(Expression expression) {
1939        SplitDefinition answer = new SplitDefinition(expression);
1940        addOutput(answer);
1941        return answer;
1942    }
1943
1944    /**
1945     * <a href="http://camel.apache.org/splitter.html">Splitter EIP:</a>
1946     * Creates a splitter allowing you split a message into a number of pieces and process them individually.
1947     * <p>
1948     * The splitter responds with the answer produced by the given {@link AggregationStrategy}.
1949     *
1950     * @param expression  the expression on which to split
1951     * @param aggregationStrategy  the strategy used to aggregate responses for every part
1952     * @return the builder
1953     */
1954    public SplitDefinition split(Expression expression, AggregationStrategy aggregationStrategy) {
1955        SplitDefinition answer = new SplitDefinition(expression);
1956        addOutput(answer);
1957        answer.setAggregationStrategy(aggregationStrategy);
1958        return answer;
1959    }
1960
1961    /**
1962     * <a href="http://camel.apache.org/resequencer.html">Resequencer EIP:</a>
1963     * Creates a resequencer allowing you to reorganize messages based on some comparator.
1964     *
1965     * @return the expression clause for the expressions on which to compare messages in order
1966     */
1967    public ExpressionClause<ResequenceDefinition> resequence() {
1968        ResequenceDefinition answer = new ResequenceDefinition();
1969        ExpressionClause<ResequenceDefinition> clause = new ExpressionClause<ResequenceDefinition>(answer);
1970        answer.setExpression(clause);
1971        addOutput(answer);
1972        return clause;
1973    }
1974
1975    /**
1976     * <a href="http://camel.apache.org/resequencer.html">Resequencer EIP:</a>
1977     * Creates a resequencer allowing you to reorganize messages based on some comparator.
1978     *
1979     * @param expression the expression on which to compare messages in order
1980     * @return the builder
1981     */
1982    public ResequenceDefinition resequence(Expression expression) {
1983        ResequenceDefinition answer = new ResequenceDefinition(expression);
1984        addOutput(answer);
1985        return answer;
1986    }
1987
1988    /**
1989     * <a href="http://camel.apache.org/aggregator.html">Aggregator EIP:</a>
1990     * Creates an aggregator allowing you to combine a number of messages together into a single message.
1991     *
1992     * @return the expression clause to be used as builder to configure the correlation expression
1993     */
1994    public ExpressionClause<AggregateDefinition> aggregate() {
1995        AggregateDefinition answer = new AggregateDefinition();
1996        ExpressionClause<AggregateDefinition> clause = new ExpressionClause<AggregateDefinition>(answer);
1997        answer.setExpression(clause);
1998        addOutput(answer);
1999        return clause;
2000    }
2001
2002    /**
2003     * <a href="http://camel.apache.org/aggregator.html">Aggregator EIP:</a>
2004     * Creates an aggregator allowing you to combine a number of messages together into a single message.
2005     *
2006     * @param aggregationStrategy the strategy used for the aggregation
2007     * @return the expression clause to be used as builder to configure the correlation expression
2008     */
2009    public ExpressionClause<AggregateDefinition> aggregate(AggregationStrategy aggregationStrategy) {
2010        AggregateDefinition answer = new AggregateDefinition();
2011        ExpressionClause<AggregateDefinition> clause = new ExpressionClause<AggregateDefinition>(answer);
2012        answer.setExpression(clause);
2013        answer.setAggregationStrategy(aggregationStrategy);
2014        addOutput(answer);
2015        return clause;
2016    }
2017
2018    /**
2019     * <a href="http://camel.apache.org/aggregator.html">Aggregator EIP:</a>
2020     * Creates an aggregator allowing you to combine a number of messages together into a single message.
2021     *
2022     * @param correlationExpression the expression used to calculate the
2023     *                              correlation key. For a JMS message this could be the
2024     *                              expression <code>header("JMSDestination")</code> or
2025     *                              <code>header("JMSCorrelationID")</code>
2026     * @return the builder
2027     */
2028    public AggregateDefinition aggregate(Expression correlationExpression) {
2029        AggregateDefinition answer = new AggregateDefinition(correlationExpression);
2030        addOutput(answer);
2031        return answer;
2032    }
2033
2034    /**
2035     * <a href="http://camel.apache.org/aggregator.html">Aggregator EIP:</a>
2036     * Creates an aggregator allowing you to combine a number of messages together into a single message.
2037     *
2038     * @param correlationExpression the expression used to calculate the
2039     *                              correlation key. For a JMS message this could be the
2040     *                              expression <code>header("JMSDestination")</code> or
2041     *                              <code>header("JMSCorrelationID")</code>
2042     * @param aggregationStrategy the strategy used for the aggregation
2043     * @return the builder
2044     */
2045    public AggregateDefinition aggregate(Expression correlationExpression, AggregationStrategy aggregationStrategy) {
2046        AggregateDefinition answer = new AggregateDefinition(correlationExpression, aggregationStrategy);
2047        addOutput(answer);
2048        return answer;
2049    }
2050
2051    /**
2052     * <a href="http://camel.apache.org/delayer.html">Delayer EIP:</a>
2053     * Creates a delayer allowing you to delay the delivery of messages to some destination.
2054     *
2055     * @param delay  an expression to calculate the delay time in millis
2056     * @return the builder
2057     */
2058    public DelayDefinition delay(Expression delay) {
2059        DelayDefinition answer = new DelayDefinition(delay);
2060        addOutput(answer);
2061        return answer;
2062    }
2063
2064    /**
2065     * <a href="http://camel.apache.org/delayer.html">Delayer EIP:</a>
2066     * Creates a delayer allowing you to delay the delivery of messages to some destination.
2067     *
2068     * @return the expression clause to create the expression
2069     */
2070    public ExpressionClause<DelayDefinition> delay() {
2071        DelayDefinition answer = new DelayDefinition();
2072        addOutput(answer);
2073        return ExpressionClause.createAndSetExpression(answer);
2074    }
2075
2076    /**
2077     * <a href="http://camel.apache.org/delayer.html">Delayer EIP:</a>
2078     * Creates a delayer allowing you to delay the delivery of messages to some destination.
2079     *
2080     * @param delay  the delay in millis
2081     * @return the builder
2082     */
2083    public DelayDefinition delay(long delay) {
2084        return delay(ExpressionBuilder.constantExpression(delay));
2085    }
2086
2087    /**
2088     * <a href="http://camel.apache.org/throttler.html">Throttler EIP:</a>
2089     * Creates a throttler allowing you to ensure that a specific endpoint does not get overloaded,
2090     * or that we don't exceed an agreed SLA with some external service.
2091     * <p/>
2092     * Will default use a time period of 1 second, so setting the maximumRequestCount to eg 10
2093     * will default ensure at most 10 messages per second. 
2094     *
2095     * @param maximumRequestCount  the maximum messages 
2096     * @return the builder
2097     */
2098    public ThrottleDefinition throttle(long maximumRequestCount) {
2099        return throttle(ExpressionBuilder.constantExpression(maximumRequestCount));
2100    }
2101
2102    /**
2103     * <a href="http://camel.apache.org/throttler.html">Throttler EIP:</a>
2104     * Creates a throttler allowing you to ensure that a specific endpoint does not get overloaded,
2105     * or that we don't exceed an agreed SLA with some external service.
2106     * <p/>
2107     * Will default use a time period of 1 second, so setting the maximumRequestCount to eg 10
2108     * will default ensure at most 10 messages per second. 
2109     *
2110     * @param maximumRequestCount  an expression to calculate the maximum request count 
2111     * @return the builder
2112     */
2113    public ThrottleDefinition throttle(Expression maximumRequestCount) {
2114        ThrottleDefinition answer = new ThrottleDefinition(maximumRequestCount);
2115        addOutput(answer);
2116        return answer;
2117    }
2118    
2119    /**
2120     * <a href="http://camel.apache.org/loop.html">Loop EIP:</a>
2121     * Creates a loop allowing to process the a message a number of times and possibly process them
2122     * in a different way. Useful mostly for testing.
2123     *
2124     * @return the clause used to create the loop expression
2125     */
2126    public ExpressionClause<LoopDefinition> loop() {
2127        LoopDefinition loop = new LoopDefinition();
2128        addOutput(loop);
2129        return ExpressionClause.createAndSetExpression(loop);
2130    }
2131
2132    /**
2133     * <a href="http://camel.apache.org/loop.html">Loop EIP:</a>
2134     * Creates a loop allowing to process the a message a number of times and possibly process them
2135     * in a different way. Useful mostly for testing.
2136     *
2137     * @param expression the loop expression
2138     * @return the builder
2139     */
2140    public LoopDefinition loop(Expression expression) {
2141        LoopDefinition loop = new LoopDefinition(expression);
2142        addOutput(loop);
2143        return loop;
2144    }
2145
2146    /**
2147     * <a href="http://camel.apache.org/loop.html">Loop EIP:</a>
2148     * Creates a loop allowing to process the a message a number of times and possibly process them
2149     * in a different way. Useful mostly for testing.
2150     *
2151     * @param count  the number of times
2152     * @return the builder
2153     */
2154    public LoopDefinition loop(int count) {
2155        LoopDefinition loop = new LoopDefinition(new ConstantExpression(Integer.toString(count)));
2156        addOutput(loop);
2157        return loop;
2158    }
2159
2160    /**
2161     * Sets the exception on the {@link org.apache.camel.Exchange}
2162     *
2163     * @param exception the exception to throw
2164     * @return the builder
2165     */
2166    public Type throwException(Exception exception) {
2167        ThrowExceptionDefinition answer = new ThrowExceptionDefinition();
2168        answer.setException(exception);
2169        addOutput(answer);
2170        return (Type) this;
2171    }
2172
2173    /**
2174     * Sets the exception on the {@link org.apache.camel.Exchange}
2175     *
2176     * @param type the exception class to use
2177     * @param message the given message as caused message (supports simple language)
2178     * @return the builder
2179     */
2180    public Type throwException(Class<? extends Exception> type, String message) {
2181        ThrowExceptionDefinition answer = new ThrowExceptionDefinition();
2182        answer.setExceptionClass(type);
2183        answer.setMessage(message);
2184        addOutput(answer);
2185        return (Type) this;
2186    }
2187
2188    /**
2189     * Marks the exchange for rollback only.
2190     * <p/>
2191     * Does <b>not</b> set any exception as opposed to {@link #rollback()} methods.
2192     *
2193     * @return the builder
2194     * @see #rollback()
2195     * @see #rollback(String)
2196     * @see #markRollbackOnlyLast()
2197     */
2198    public Type markRollbackOnly() {
2199        RollbackDefinition answer = new RollbackDefinition();
2200        answer.setMarkRollbackOnly(true);
2201        addOutput(answer);
2202        return (Type) this;
2203    }
2204
2205    /**
2206     * Marks the exchange for rollback only, but only for the last (current) transaction.
2207     * <p/>
2208     * A last rollback is used when you have nested transactions and only want the last local transaction to rollback,
2209     * where as the outer transaction can still be completed
2210     * <p/>
2211     * Does <b>not</b> set any exception as opposed to {@link #rollback()} methods.
2212     *
2213     * @return the builder
2214     * @see #rollback()
2215     * @see #rollback(String)
2216     * @see #markRollbackOnly()
2217     */
2218    public Type markRollbackOnlyLast() {
2219        RollbackDefinition answer = new RollbackDefinition();
2220        answer.setMarkRollbackOnlyLast(true);
2221        addOutput(answer);
2222        return (Type) this;
2223    }
2224
2225    /**
2226     * Marks the exchange for rollback only and sets an exception with a default message.
2227     * <p/>
2228     * This is done by setting a {@link org.apache.camel.RollbackExchangeException} on the Exchange
2229     * and mark it for rollback.
2230     *
2231     * @return the builder
2232     * @see #markRollbackOnly()
2233     */
2234    public Type rollback() {
2235        return rollback(null);
2236    }
2237
2238    /**
2239     * Marks the exchange for rollback and sets an exception with the provided message.
2240     * <p/>
2241     * This is done by setting a {@link org.apache.camel.RollbackExchangeException} on the Exchange
2242     * and mark it for rollback.
2243     *
2244     * @param message an optional message used for logging purpose why the rollback was triggered
2245     * @return the builder
2246     * @see #markRollbackOnly()
2247     */
2248    public Type rollback(String message) {
2249        RollbackDefinition answer = new RollbackDefinition(message);
2250        addOutput(answer);
2251        return (Type) this;
2252    }
2253
2254    /**
2255     * <a href="http://camel.apache.org/wiretap.html">WireTap EIP:</a>
2256     * Sends messages to all its child outputs; so that each processor and
2257     * destination gets a copy of the original message to avoid the processors
2258     * interfering with each other using {@link ExchangePattern#InOnly}.
2259     *
2260     * @param endpoint  the endpoint to wiretap to
2261     * @return the builder
2262     */
2263    public WireTapDefinition<Type> wireTap(Endpoint endpoint) {
2264        WireTapDefinition answer = new WireTapDefinition();
2265        answer.setUri(endpoint.getEndpointUri());
2266        addOutput(answer);
2267        return answer;
2268    }
2269
2270    /**
2271     * <a href="http://camel.apache.org/wiretap.html">WireTap EIP:</a>
2272     * Sends messages to all its child outputs; so that each processor and
2273     * destination gets a copy of the original message to avoid the processors
2274     * interfering with each other using {@link ExchangePattern#InOnly}.
2275     *
2276     * @param uri  the dynamic endpoint to wiretap to (resolved using simple language by default)
2277     * @return the builder
2278     */
2279    public WireTapDefinition<Type> wireTap(String uri) {
2280        WireTapDefinition answer = new WireTapDefinition();
2281        answer.setUri(uri);
2282        addOutput(answer);
2283        return answer;
2284    }
2285
2286    /**
2287     * <a href="http://camel.apache.org/wiretap.html">WireTap EIP:</a>
2288     * Sends messages to all its child outputs; so that each processor and
2289     * destination gets a copy of the original message to avoid the processors
2290     * interfering with each other using {@link ExchangePattern#InOnly}.
2291     *
2292     * @param uri  the dynamic endpoint to wiretap to (resolved using simple language by default)
2293     * @param      executorService a custom {@link ExecutorService} to use as thread pool
2294     *             for sending tapped exchanges
2295     * @return the builder
2296     * @deprecated use the fluent builder from {@link WireTapDefinition}, will be removed in Camel 3.0
2297     */
2298    @Deprecated
2299    public WireTapDefinition<Type> wireTap(String uri, ExecutorService executorService) {
2300        WireTapDefinition answer = new WireTapDefinition();
2301        answer.setUri(uri);
2302        answer.setExecutorService(executorService);
2303        addOutput(answer);
2304        return answer;
2305    }
2306
2307    /**
2308     * <a href="http://camel.apache.org/wiretap.html">WireTap EIP:</a>
2309     * Sends messages to all its child outputs; so that each processor and
2310     * destination gets a copy of the original message to avoid the processors
2311     * interfering with each other using {@link ExchangePattern#InOnly}.
2312     *
2313     * @param uri  the dynamic endpoint to wiretap to (resolved using simple language by default)
2314     * @param      executorServiceRef reference to lookup a custom {@link ExecutorService}
2315     *             to use as thread pool for sending tapped exchanges
2316     * @return the builder
2317     * @deprecated use the fluent builder from {@link WireTapDefinition}, will be removed in Camel 3.0
2318     */
2319    @Deprecated
2320    public WireTapDefinition<Type> wireTap(String uri, String executorServiceRef) {
2321        WireTapDefinition answer = new WireTapDefinition();
2322        answer.setUri(uri);
2323        answer.setExecutorServiceRef(executorServiceRef);
2324        addOutput(answer);
2325        return answer;
2326    }
2327
2328    /**
2329     * <a href="http://camel.apache.org/wiretap.html">WireTap EIP:</a>
2330     * Sends a new {@link org.apache.camel.Exchange} to the destination
2331     * using {@link ExchangePattern#InOnly}.
2332     * <p/>
2333     * Will use a copy of the original Exchange which is passed in as argument
2334     * to the given expression
2335     *
2336     * @param uri  the dynamic endpoint to wiretap to (resolved using simple language by default)
2337     * @param body expression that creates the body to send
2338     * @return the builder
2339     * @deprecated use the fluent builder from {@link WireTapDefinition}, will be removed in Camel 3.0
2340     */
2341    @Deprecated
2342    public WireTapDefinition<Type> wireTap(String uri, Expression body) {
2343        return wireTap(uri, true, body);
2344    }
2345
2346    /**
2347     * <a href="http://camel.apache.org/wiretap.html">WireTap EIP:</a>
2348     * Sends a new {@link org.apache.camel.Exchange} to the destination
2349     * using {@link ExchangePattern#InOnly}.
2350     *
2351     * @param uri  the dynamic endpoint to wiretap to (resolved using simple language by default)
2352     * @param copy whether or not use a copy of the original exchange or a new empty exchange
2353     * @return the builder
2354     * @deprecated use the fluent builder from {@link WireTapDefinition}, will be removed in Camel 3.0
2355     */
2356    @Deprecated
2357    public WireTapDefinition<Type> wireTap(String uri, boolean copy) {
2358        WireTapDefinition answer = new WireTapDefinition();
2359        answer.setUri(uri);
2360        answer.setCopy(copy);
2361        addOutput(answer);
2362        return answer;
2363    }
2364
2365    /**
2366     * <a href="http://camel.apache.org/wiretap.html">WireTap EIP:</a>
2367     * Sends a new {@link org.apache.camel.Exchange} to the destination
2368     * using {@link ExchangePattern#InOnly}.
2369     *
2370     * @param uri  the dynamic endpoint to wiretap to (resolved using simple language by default)
2371     * @param copy whether or not use a copy of the original exchange or a new empty exchange
2372     * @param body expression that creates the body to send
2373     * @return the builder
2374     * @deprecated use the fluent builder from {@link WireTapDefinition}, will be removed in Camel 3.0
2375     */
2376    @Deprecated
2377    public WireTapDefinition<Type> wireTap(String uri, boolean copy, Expression body) {
2378        WireTapDefinition answer = new WireTapDefinition();
2379        answer.setUri(uri);
2380        answer.setCopy(copy);
2381        answer.setNewExchangeExpression(new ExpressionSubElementDefinition(body));
2382        addOutput(answer);
2383        return answer;
2384    }
2385
2386    /**
2387     * <a href="http://camel.apache.org/wiretap.html">WireTap EIP:</a>
2388     * Sends a new {@link org.apache.camel.Exchange} to the destination
2389     * using {@link ExchangePattern#InOnly}.
2390     * <p/>
2391     * Will use a copy of the original Exchange which is passed in as argument
2392     * to the given processor
2393     *
2394     * @param uri  the dynamic endpoint to wiretap to (resolved using simple language by default)
2395     * @param processor  processor preparing the new exchange to send
2396     * @return the builder
2397     * @deprecated use the fluent builder from {@link WireTapDefinition}, will be removed in Camel 3.0
2398     */
2399    @Deprecated
2400    public WireTapDefinition<Type> wireTap(String uri, Processor processor) {
2401        return wireTap(uri, true, processor);
2402    }
2403
2404    /**
2405     * <a href="http://camel.apache.org/wiretap.html">WireTap EIP:</a>
2406     * Sends a new {@link org.apache.camel.Exchange} to the destination
2407     * using {@link ExchangePattern#InOnly}.
2408     *
2409     * @param uri  the dynamic endpoint to wiretap to (resolved using simple language by default)
2410     * @param copy whether or not use a copy of the original exchange or a new empty exchange
2411     * @param processor  processor preparing the new exchange to send
2412     * @return the builder
2413     * @deprecated use the fluent builder from {@link WireTapDefinition}, will be removed in Camel 3.0
2414     */
2415    @Deprecated
2416    public WireTapDefinition<Type> wireTap(String uri, boolean copy, Processor processor) {
2417        WireTapDefinition answer = new WireTapDefinition();
2418        answer.setUri(uri);
2419        answer.setCopy(copy);
2420        answer.setNewExchangeProcessor(processor);
2421        addOutput(answer);
2422        return answer;
2423    }
2424
2425    /**
2426     * Pushes the given block on the stack as current block
2427     *
2428     * @param block  the block
2429     */
2430    void pushBlock(Block block) {
2431        blocks.add(block);
2432    }
2433
2434    /**
2435     * Pops the block off the stack as current block
2436     *
2437     * @return the block
2438     */
2439    Block popBlock() {
2440        return blocks.isEmpty() ? null : blocks.removeLast();
2441    }
2442
2443    @SuppressWarnings("unchecked")
2444    public Type startupOrder(int startupOrder) {
2445        ProcessorDefinition<?> def = this;
2446
2447        RouteDefinition route = ProcessorDefinitionHelper.getRoute(def);
2448        if (route != null) {
2449            route.startupOrder(startupOrder);
2450        }
2451
2452        return (Type) this;
2453    }
2454
2455    /**
2456     * Stops continue routing the current {@link org.apache.camel.Exchange} and marks it as completed.
2457     *
2458     * @return the builder
2459     */
2460    @SuppressWarnings("unchecked")
2461    public Type stop() {
2462        StopDefinition stop = new StopDefinition();
2463        addOutput(stop);
2464        return (Type) this;
2465    }
2466
2467    /**
2468     * <a href="http://camel.apache.org/exception-clause.html">Exception clause</a>
2469     * for catching certain exceptions and handling them.
2470     *
2471     * @param exceptionType  the exception to catch
2472     * @return the exception builder to configure
2473     */
2474    public OnExceptionDefinition onException(Class<? extends Throwable> exceptionType) {
2475        OnExceptionDefinition answer = new OnExceptionDefinition(exceptionType);
2476        answer.setRouteScoped(true);
2477        addOutput(answer);
2478        return answer;
2479    }
2480
2481    /**
2482     * <a href="http://camel.apache.org/exception-clause.html">Exception clause</a>
2483     * for catching certain exceptions and handling them.
2484     *
2485     * @param exceptions list of exceptions to catch
2486     * @return the exception builder to configure
2487     */
2488    public OnExceptionDefinition onException(Class<? extends Throwable>... exceptions) {
2489        OnExceptionDefinition answer = new OnExceptionDefinition(Arrays.asList(exceptions));
2490        answer.setRouteScoped(true);
2491        addOutput(answer);
2492        return answer;
2493    }
2494
2495    /**
2496     * Apply a {@link Policy}.
2497     * <p/>
2498     * Policy can be used for transactional policies.
2499     *
2500     * @param policy  the policy to apply
2501     * @return the policy builder to configure
2502     */
2503    public PolicyDefinition policy(Policy policy) {
2504        PolicyDefinition answer = new PolicyDefinition(policy);
2505        addOutput(answer);
2506        return answer;
2507    }
2508
2509    /**
2510     * Apply a {@link Policy}.
2511     * <p/>
2512     * Policy can be used for transactional policies.
2513     *
2514     * @param ref  reference to lookup a policy in the registry
2515     * @return the policy builder to configure
2516     */
2517    public PolicyDefinition policy(String ref) {
2518        PolicyDefinition answer = new PolicyDefinition();
2519        answer.setRef(ref);
2520        addOutput(answer);
2521        return answer;
2522    }
2523
2524    /**
2525     * Marks this route as transacted and uses the default transacted policy found in the registry.
2526     *
2527     * @return the policy builder to configure
2528     */
2529    public TransactedDefinition transacted() {
2530        TransactedDefinition answer = new TransactedDefinition();
2531        addOutput(answer);
2532        return answer;
2533    }
2534
2535    /**
2536     * Marks this route as transacted.
2537     *
2538     * @param ref  reference to lookup a transacted policy in the registry
2539     * @return the policy builder to configure
2540     */
2541    public TransactedDefinition transacted(String ref) {
2542        TransactedDefinition answer = new TransactedDefinition();
2543        answer.setRef(ref);
2544        addOutput(answer);
2545        return answer;
2546    }
2547
2548    // Transformers
2549    // -------------------------------------------------------------------------
2550
2551    /**
2552     * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
2553     * Adds the custom processor to this destination which could be a final
2554     * destination, or could be a transformation in a pipeline
2555     *
2556     * @param processor  the custom {@link Processor}
2557     * @return the builder
2558     */
2559    @SuppressWarnings("unchecked")
2560    public Type process(Processor processor) {
2561        ProcessDefinition answer = new ProcessDefinition(processor);
2562        addOutput(answer);
2563        return (Type) this;
2564    }
2565
2566    /**
2567     * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
2568     * Adds the custom processor reference to this destination which could be a final
2569     * destination, or could be a transformation in a pipeline
2570     *
2571     * @param ref   reference to a {@link Processor} to lookup in the registry
2572     * @return the builder
2573     */
2574    @SuppressWarnings("unchecked")
2575    public Type process(String ref) {
2576        ProcessDefinition answer = new ProcessDefinition();
2577        answer.setRef(ref);
2578        addOutput(answer);
2579        return (Type) this;
2580    }
2581
2582    /**
2583     * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
2584     * Adds the custom processor reference to this destination which could be a final
2585     * destination, or could be a transformation in a pipeline
2586     *
2587     * @param ref   reference to a {@link Processor} to lookup in the registry
2588     * @return the builder
2589     * @deprecated use {@link #process(String)}
2590     */
2591    @SuppressWarnings("unchecked")
2592    @Deprecated
2593    public Type processRef(String ref) {
2594        ProcessDefinition answer = new ProcessDefinition();
2595        answer.setRef(ref);
2596        addOutput(answer);
2597        return (Type) this;
2598    }
2599
2600    /**
2601     * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
2602     * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
2603     *
2604     * @param bean  the bean to invoke, or a reference to a bean if the type is a String
2605     * @return the builder
2606     */
2607    @SuppressWarnings("unchecked")
2608    public Type bean(Object bean) {
2609        BeanDefinition answer = new BeanDefinition();
2610        if (bean instanceof String) {
2611            answer.setRef((String) bean);
2612        } else {
2613            answer.setBean(bean);
2614        }
2615        addOutput(answer);
2616        return (Type) this;
2617    }
2618
2619    /**
2620     * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
2621     * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
2622     *
2623     * @param bean  the bean to invoke, or a reference to a bean if the type is a String
2624     * @param method  the method name to invoke on the bean (can be used to avoid ambiguity)
2625     * @return the builder
2626     */
2627    @SuppressWarnings("unchecked")
2628    public Type bean(Object bean, String method) {
2629        BeanDefinition answer = new BeanDefinition();
2630        if (bean instanceof String) {
2631            answer.setRef((String) bean);
2632        } else {
2633            answer.setBean(bean);
2634        }
2635        answer.setMethod(method);
2636        addOutput(answer);
2637        return (Type) this;
2638    }
2639    
2640    /**
2641     * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
2642     * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
2643     *
2644     * @param bean  the bean to invoke, or a reference to a bean if the type is a String
2645     * @param cache  if enabled, Camel will cache the result of the first Registry look-up.
2646     *               Cache can be enabled if the bean in the Registry is defined as a singleton scope.
2647     *  the multi parameter
2648     * @return the builder
2649     */
2650    @SuppressWarnings("unchecked")
2651    public Type bean(Object bean, boolean cache) {
2652        BeanDefinition answer = new BeanDefinition();
2653        if (bean instanceof String) {
2654            answer.setRef((String) bean);
2655        } else {
2656            answer.setBean(bean);
2657        }
2658        answer.setCache(cache);
2659        addOutput(answer);
2660        return (Type) this;
2661    }
2662
2663    /**
2664     * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
2665     * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
2666     *
2667     * @param bean  the bean to invoke, or a reference to a bean if the type is a String
2668     * @param method  the method name to invoke on the bean (can be used to avoid ambiguity)
2669     * @param cache  if enabled, Camel will cache the result of the first Registry look-up.
2670     *               Cache can be enabled if the bean in the Registry is defined as a singleton scope.
2671     *  the multi parameter
2672     * @return the builder
2673     */
2674    @SuppressWarnings("unchecked")
2675    public Type bean(Object bean, String method, boolean cache) {
2676        BeanDefinition answer = new BeanDefinition();
2677        if (bean instanceof String) {
2678            answer.setRef((String) bean);
2679        } else {
2680            answer.setBean(bean);
2681        }
2682        answer.setMethod(method);
2683        answer.setCache(cache);
2684        addOutput(answer);
2685        return (Type) this;
2686    }
2687
2688    /**
2689     * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
2690     * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
2691     *
2692     * @param  beanType  the bean class, Camel will instantiate an object at runtime
2693     * @return the builder
2694     */
2695    @SuppressWarnings("unchecked")
2696    public Type bean(Class<?> beanType) {
2697        BeanDefinition answer = new BeanDefinition();
2698        answer.setBeanType(beanType);
2699        addOutput(answer);
2700        return (Type) this;
2701    }
2702
2703    /**
2704     * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
2705     * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
2706     *
2707     * @param  beanType  the bean class, Camel will instantiate an object at runtime
2708     * @param method  the method name to invoke on the bean (can be used to avoid ambiguity)
2709     * @return the builder
2710     */
2711    @SuppressWarnings("unchecked")
2712    public Type bean(Class<?> beanType, String method) {
2713        BeanDefinition answer = new BeanDefinition();
2714        answer.setBeanType(beanType);
2715        answer.setMethod(method);
2716        addOutput(answer);
2717        return (Type) this;
2718    }
2719    
2720    /**
2721     * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
2722     * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
2723     *
2724     * @param beanType  the bean class, Camel will instantiate an object at runtime
2725     * @param method  the method name to invoke on the bean (can be used to avoid ambiguity)
2726     * @param multiParameterArray if it is true, camel will treat the message body as an object array which holds
2727     *  the multi parameter 
2728     * @return the builder
2729     * @deprecated the option multiParameterArray is deprecated
2730     */
2731    @SuppressWarnings("unchecked")
2732    @Deprecated
2733    public Type bean(Class<?> beanType, String method, boolean multiParameterArray) {
2734        BeanDefinition answer = new BeanDefinition();
2735        answer.setBeanType(beanType);
2736        answer.setMethod(method);
2737        answer.setMultiParameterArray(multiParameterArray);
2738        addOutput(answer);
2739        return (Type) this;
2740    }
2741
2742    /**
2743     * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
2744     * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
2745     *
2746     * @param beanType  the bean class, Camel will instantiate an object at runtime
2747     * @param method  the method name to invoke on the bean (can be used to avoid ambiguity)
2748     * @param multiParameterArray if it is true, camel will treat the message body as an object array which holds
2749     *  the multi parameter
2750     * @param cache  if enabled, Camel will cache the result of the first Registry look-up.
2751     *               Cache can be enabled if the bean in the Registry is defined as a singleton scope.
2752     * @return the builder
2753     * @deprecated the option multiParameterArray is deprecated
2754     */
2755    @SuppressWarnings("unchecked")
2756    @Deprecated
2757    public Type bean(Class<?> beanType, String method, boolean multiParameterArray, boolean cache) {
2758        BeanDefinition answer = new BeanDefinition();
2759        answer.setBeanType(beanType);
2760        answer.setMethod(method);
2761        answer.setMultiParameterArray(multiParameterArray);
2762        answer.setCache(cache);
2763        addOutput(answer);
2764        return (Type) this;
2765    }
2766
2767    /**
2768     * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
2769     * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
2770     *
2771     * @param ref  reference to a bean to lookup in the registry
2772     * @return the builder
2773     * @deprecated use {@link #bean(Object)}
2774     */
2775    @SuppressWarnings("unchecked")
2776    @Deprecated
2777    public Type beanRef(String ref) {
2778        BeanDefinition answer = new BeanDefinition(ref);
2779        addOutput(answer);
2780        return (Type) this;
2781    }
2782    
2783    /**
2784     * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
2785     * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
2786     *
2787     * @param ref  reference to a bean to lookup in the registry
2788     * @param method  the method name to invoke on the bean (can be used to avoid ambiguity)
2789     * @return the builder
2790     * @deprecated use {@link #bean(Object, String)}
2791     */
2792    @SuppressWarnings("unchecked")
2793    @Deprecated
2794    public Type beanRef(String ref, String method) {
2795        BeanDefinition answer = new BeanDefinition(ref, method);
2796        addOutput(answer);
2797        return (Type) this;
2798    }
2799
2800    /**
2801     * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
2802     * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
2803     *
2804     * @param ref  reference to a bean to lookup in the registry
2805     * @param cache  if enabled, Camel will cache the result of the first Registry look-up.
2806     *               Cache can be enabled if the bean in the Registry is defined as a singleton scope.
2807     * @return the builder
2808     * @deprecated use {@link #bean(Object, String, boolean)}
2809     */
2810    @SuppressWarnings("unchecked")
2811    @Deprecated
2812    public Type beanRef(String ref, boolean cache) {
2813        BeanDefinition answer = new BeanDefinition(ref);
2814        answer.setCache(cache);
2815        addOutput(answer);
2816        return (Type) this;
2817    }
2818    
2819    /**
2820     * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
2821     * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
2822     *
2823     * @param ref  reference to a bean to lookup in the registry
2824     * @param method  the method name to invoke on the bean (can be used to avoid ambiguity)
2825     * @param cache  if enabled, Camel will cache the result of the first Registry look-up.
2826     *               Cache can be enabled if the bean in the Registry is defined as a singleton scope.
2827     * @return the builder
2828     * @deprecated use {@link #bean(Object, String, boolean)}
2829     */
2830    @SuppressWarnings("unchecked")
2831    @Deprecated
2832    public Type beanRef(String ref, String method, boolean cache) {
2833        BeanDefinition answer = new BeanDefinition(ref, method);
2834        answer.setCache(cache);
2835        addOutput(answer);
2836        return (Type) this;
2837    }
2838
2839    /**
2840     * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
2841     * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
2842     *
2843     * @param ref  reference to a bean to lookup in the registry
2844     * @param method  the method name to invoke on the bean (can be used to avoid ambiguity)
2845     * @param cache  if enabled, Camel will cache the result of the first Registry look-up.
2846     *               Cache can be enabled if the bean in the Registry is defined as a singleton scope.
2847     * @param multiParameterArray if it is true, camel will treat the message body as an object array which holds
2848     *               the multi parameter 
2849     * @return the builder
2850     * @deprecated the option multiParameterArray is deprecated
2851     */
2852    @SuppressWarnings("unchecked")
2853    @Deprecated
2854    public Type beanRef(String ref, String method, boolean cache, boolean multiParameterArray) {
2855        BeanDefinition answer = new BeanDefinition(ref, method);
2856        answer.setCache(cache);
2857        answer.setMultiParameterArray(multiParameterArray);
2858        addOutput(answer);
2859        return (Type) this;
2860    }
2861
2862    /**
2863     * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
2864     * Adds a processor which sets the body on the IN message
2865     *
2866     * @return a expression builder clause to set the body
2867     */
2868    public ExpressionClause<ProcessorDefinition<Type>> setBody() {
2869        ExpressionClause<ProcessorDefinition<Type>> clause = new ExpressionClause<ProcessorDefinition<Type>>(this);
2870        SetBodyDefinition answer = new SetBodyDefinition(clause);
2871        addOutput(answer);
2872        return clause;
2873    }
2874
2875    /**
2876     * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
2877     * Adds a processor which sets the body on the IN message
2878     *
2879     * @param expression   the expression used to set the body
2880     * @return the builder
2881     */
2882    @SuppressWarnings("unchecked")
2883    public Type setBody(Expression expression) {
2884        SetBodyDefinition answer = new SetBodyDefinition(expression);
2885        addOutput(answer);
2886        return (Type) this;
2887    }
2888
2889    /**
2890     * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
2891     * Adds a processor which sets the body on the OUT message
2892     *
2893     * @param expression   the expression used to set the body
2894     * @return the builder
2895     */
2896    @SuppressWarnings("unchecked")
2897    public Type transform(Expression expression) {
2898        TransformDefinition answer = new TransformDefinition(expression);
2899        addOutput(answer);
2900        return (Type) this;
2901    }
2902
2903    /**
2904     * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
2905     * Adds a processor which sets the body on the OUT message
2906     *
2907     * @return a expression builder clause to set the body
2908     */
2909    public ExpressionClause<ProcessorDefinition<Type>> transform() {
2910        ExpressionClause<ProcessorDefinition<Type>> clause =
2911            new ExpressionClause<ProcessorDefinition<Type>>((ProcessorDefinition<Type>) this);
2912        TransformDefinition answer = new TransformDefinition(clause);
2913        addOutput(answer);
2914        return clause;
2915    }
2916
2917    /**
2918     * Executes a script (do not change the message body).
2919     *
2920     * @param expression   the expression used as the script.
2921     * @return the builder
2922     */
2923    @SuppressWarnings("unchecked")
2924    public Type script(Expression expression) {
2925        ScriptDefinition answer = new ScriptDefinition(expression);
2926        addOutput(answer);
2927        return (Type) this;
2928    }
2929
2930    /**
2931     * Executes a script (do not change the message body).
2932     *
2933     * @return a expression builder clause to use as script.
2934     */
2935    public ExpressionClause<ProcessorDefinition<Type>> script() {
2936        ExpressionClause<ProcessorDefinition<Type>> clause =
2937                new ExpressionClause<ProcessorDefinition<Type>>((ProcessorDefinition<Type>) this);
2938        ScriptDefinition answer = new ScriptDefinition(clause);
2939        addOutput(answer);
2940        return clause;
2941    }
2942
2943    /**
2944     * Adds a processor which sets the body on the FAULT message
2945     *
2946     * @param expression   the expression used to set the body
2947     * @return the builder
2948     */
2949    public Type setFaultBody(Expression expression) {
2950        return process(ProcessorBuilder.setFaultBody(expression));
2951    }
2952
2953    /**
2954     * Adds a processor which sets the header on the IN message
2955     *
2956     * @param name  the header name
2957     * @return a expression builder clause to set the header
2958     */
2959    public ExpressionClause<ProcessorDefinition<Type>> setHeader(String name) {
2960        ExpressionClause<ProcessorDefinition<Type>> clause = new ExpressionClause<ProcessorDefinition<Type>>(this);
2961        SetHeaderDefinition answer = new SetHeaderDefinition(name, clause);
2962        addOutput(answer);
2963        return clause;
2964    }
2965
2966    /**
2967     * Adds a processor which sets the header on the IN message
2968     *
2969     * @param name  the header name
2970     * @param expression  the expression used to set the header
2971     * @return the builder
2972     */
2973    @SuppressWarnings("unchecked")
2974    public Type setHeader(String name, Expression expression) {
2975        SetHeaderDefinition answer = new SetHeaderDefinition(name, expression);
2976        addOutput(answer);
2977        return (Type) this;
2978    }
2979
2980    /**
2981     * Adds a processor which sets the header on the OUT message
2982     *
2983     * @param name  the header name
2984     * @return a expression builder clause to set the header
2985     * @deprecated use {@link #setHeader(String)}
2986     */
2987    @Deprecated
2988    public ExpressionClause<ProcessorDefinition<Type>> setOutHeader(String name) {
2989        ExpressionClause<ProcessorDefinition<Type>> clause = new ExpressionClause<ProcessorDefinition<Type>>(this);
2990        SetOutHeaderDefinition answer = new SetOutHeaderDefinition(name, clause);
2991        addOutput(answer);
2992        return clause;
2993    }
2994
2995    /**
2996     * Adds a processor which sets the header on the OUT message
2997     *
2998     * @param name  the header name
2999     * @param expression  the expression used to set the header
3000     * @return the builder
3001     * @deprecated use {@link #setHeader(String, org.apache.camel.Expression)}
3002     */
3003    @SuppressWarnings("unchecked")
3004    @Deprecated
3005    public Type setOutHeader(String name, Expression expression) {
3006        SetOutHeaderDefinition answer = new SetOutHeaderDefinition(name, expression);
3007        addOutput(answer);
3008        return (Type) this;
3009    }
3010
3011    /**
3012     * Adds a processor which sets the header on the FAULT message
3013     *
3014     * @param name  the header name
3015     * @param expression  the expression used to set the header
3016     * @return the builder
3017     * @deprecated use {@link #setHeader(String, org.apache.camel.Expression)}
3018     */
3019    @Deprecated
3020    public Type setFaultHeader(String name, Expression expression) {
3021        return process(ProcessorBuilder.setFaultHeader(name, expression));
3022    }
3023
3024    /**
3025     * Adds a processor which sets the exchange property
3026     *
3027     * @param name  the property name
3028     * @param expression  the expression used to set the property
3029     * @return the builder
3030     */
3031    @SuppressWarnings("unchecked")
3032    public Type setProperty(String name, Expression expression) {
3033        SetPropertyDefinition answer = new SetPropertyDefinition(name, expression);
3034        addOutput(answer);
3035        return (Type) this;
3036    }
3037
3038    /**
3039     * Adds a processor which sets the exchange property
3040     *
3041     * @param name  the property name
3042     * @return a expression builder clause to set the property
3043     */
3044    public ExpressionClause<ProcessorDefinition<Type>> setProperty(String name) {
3045        ExpressionClause<ProcessorDefinition<Type>> clause = new ExpressionClause<ProcessorDefinition<Type>>(this);
3046        SetPropertyDefinition answer = new SetPropertyDefinition(name, clause);
3047        addOutput(answer);
3048        return clause;
3049    }
3050
3051    /**
3052     * Adds a processor which removes the header on the IN message
3053     *
3054     * @param name  the header name
3055     * @return the builder
3056     */
3057    @SuppressWarnings("unchecked")
3058    public Type removeHeader(String name) {
3059        RemoveHeaderDefinition answer = new RemoveHeaderDefinition(name);
3060        addOutput(answer);
3061        return (Type) this;
3062    }
3063
3064    /**
3065     * Adds a processor which removes the headers on the IN message
3066     *
3067     * @param pattern  a pattern to match header names to be removed
3068     * @return the builder
3069     */
3070    @SuppressWarnings("unchecked")
3071    public Type removeHeaders(String pattern) {
3072        RemoveHeadersDefinition answer = new RemoveHeadersDefinition(pattern);
3073        addOutput(answer);
3074        return (Type) this;
3075    }
3076
3077    /**
3078     * Adds a processor which removes the headers on the IN message
3079     *
3080     * @param pattern  a pattern to match header names to be removed
3081     * @param excludePatterns one or more pattern of header names that should be excluded (= preserved)
3082     * @return the builder
3083     */
3084    @SuppressWarnings("unchecked")
3085    public Type removeHeaders(String pattern, String... excludePatterns) {
3086        RemoveHeadersDefinition answer = new RemoveHeadersDefinition(pattern, excludePatterns);
3087        addOutput(answer);
3088        return (Type) this;
3089    }
3090
3091    /**
3092     * Adds a processor which removes the header on the FAULT message
3093     *
3094     * @param name  the header name
3095     * @return the builder
3096     * @deprecated will be removed in the near future. Instead use {@link #removeHeader(String)}
3097     */
3098    @Deprecated
3099    public Type removeFaultHeader(String name) {
3100        return process(ProcessorBuilder.removeFaultHeader(name));
3101    }
3102
3103    /**
3104     * Adds a processor which removes the exchange property
3105     *
3106     * @param name  the property name
3107     * @return the builder
3108     */
3109    @SuppressWarnings("unchecked")
3110    public Type removeProperty(String name) {
3111        RemovePropertyDefinition answer = new RemovePropertyDefinition(name);
3112        addOutput(answer);
3113        return (Type) this;
3114    }
3115    
3116    /**
3117     * Adds a processor which removes the properties in the exchange
3118     *
3119     * @param pattern a pattern to match properties names to be removed
3120     * @return the builder
3121     */
3122    @SuppressWarnings("unchecked")
3123    public Type removeProperties(String pattern) {
3124        RemovePropertiesDefinition answer = new RemovePropertiesDefinition(pattern);
3125        addOutput(answer);
3126        return (Type) this;
3127    }
3128
3129    /**
3130     * Adds a processor which removes the properties in the exchange
3131     *
3132     * @param pattern a pattern to match properties names to be removed
3133     * @param excludePatterns one or more pattern of properties names that should be excluded (= preserved)
3134     * @return the builder
3135     */
3136    @SuppressWarnings("unchecked")
3137    public Type removeProperties(String pattern, String... excludePatterns) {
3138        RemovePropertiesDefinition answer = new RemovePropertiesDefinition(pattern, excludePatterns);
3139        addOutput(answer);
3140        return (Type) this;
3141    }
3142
3143    /**
3144     * Converts the IN message body to the specified type
3145     *
3146     * @param type the type to convert to
3147     * @return the builder
3148     */
3149    @SuppressWarnings("unchecked")
3150    public Type convertBodyTo(Class<?> type) {
3151        addOutput(new ConvertBodyDefinition(type));
3152        return (Type) this;
3153    }
3154    
3155    /**
3156     * Converts the IN message body to the specified type
3157     *
3158     * @param type the type to convert to
3159     * @param charset the charset to use by type converters (not all converters support specifc charset)
3160     * @return the builder
3161     */
3162    @SuppressWarnings("unchecked")
3163    public Type convertBodyTo(Class<?> type, String charset) {
3164        addOutput(new ConvertBodyDefinition(type, charset));
3165        return (Type) this;
3166    }
3167
3168    /**
3169     * Sorts the expression using a default sorting based on toString representation.
3170     *
3171     * @param expression  the expression, must be convertable to {@link List}
3172     * @return the builder
3173     */
3174    public Type sort(Expression expression) {
3175        return sort(expression, null);
3176    }
3177
3178    /**
3179     * Sorts the expression using the given comparator
3180     *
3181     * @param expression  the expression, must be convertable to {@link List}
3182     * @param comparator  the comparator to use for sorting
3183     * @return the builder
3184     */
3185    @SuppressWarnings("unchecked")
3186    public <T> Type sort(Expression expression, Comparator<T> comparator) {
3187        addOutput(new SortDefinition<T>(expression, comparator));
3188        return (Type) this;
3189    }
3190
3191    /**
3192     * Sorts the expression
3193     *
3194     * @return the builder
3195     */
3196    public <T> ExpressionClause<SortDefinition<T>> sort() {
3197        SortDefinition<T> answer = new SortDefinition<T>();
3198        addOutput(answer);
3199        return ExpressionClause.createAndSetExpression(answer);
3200    }
3201
3202    /**
3203     * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
3204     * enriches an exchange with additional data obtained from a <code>resourceUri</code>.
3205     * <p/>
3206     * The difference between this and {@link #pollEnrich(String)} is that this uses a producer
3207     * to obatin the additional data, where as pollEnrich uses a polling consumer.
3208     *
3209     * @param resourceUri           URI of resource endpoint for obtaining additional data.
3210     * @return the builder
3211     * @see org.apache.camel.processor.Enricher
3212     */
3213    public Type enrich(String resourceUri) {
3214        return enrich(resourceUri, null);
3215    }
3216
3217    /**
3218     * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
3219     * enriches an exchange with additional data obtained from a <code>resourceUri</code>.
3220     * 
3221     * @param resourceUri           URI of resource endpoint for obtaining additional data.
3222     * @param aggregationStrategy   aggregation strategy to aggregate input data and additional data.
3223     * @return the builder
3224     * @see org.apache.camel.processor.Enricher
3225     */
3226    public Type enrich(String resourceUri, AggregationStrategy aggregationStrategy) {
3227        return enrich(resourceUri, aggregationStrategy, false);
3228    }
3229
3230    /**
3231     * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
3232     * enriches an exchange with additional data obtained from a <code>resourceUri</code>.
3233     *
3234     * @param resourceUri           URI of resource endpoint for obtaining additional data.
3235     * @param aggregationStrategy   aggregation strategy to aggregate input data and additional data.
3236     * @param aggregateOnException   whether to call {@link org.apache.camel.processor.aggregate.AggregationStrategy#aggregate(org.apache.camel.Exchange, org.apache.camel.Exchange)} if
3237     *                               an exception was thrown.
3238     * @return the builder
3239     * @see org.apache.camel.processor.Enricher
3240     */
3241    public Type enrich(String resourceUri, AggregationStrategy aggregationStrategy, boolean aggregateOnException) {
3242        return enrich(resourceUri, aggregationStrategy, aggregateOnException, false);
3243    }
3244
3245    /**
3246     * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
3247     * enriches an exchange with additional data obtained from a <code>resourceUri</code>.
3248     *
3249     * @param resourceUri           URI of resource endpoint for obtaining additional data.
3250     * @param aggregationStrategy   aggregation strategy to aggregate input data and additional data.
3251     * @param aggregateOnException  whether to call {@link org.apache.camel.processor.aggregate.AggregationStrategy#aggregate(org.apache.camel.Exchange, org.apache.camel.Exchange)} if
3252     *                              an exception was thrown.
3253     * @param shareUnitOfWork       whether to share unit of work
3254     * @return the builder
3255     * @see org.apache.camel.processor.Enricher
3256     */
3257    @SuppressWarnings("unchecked")
3258    public Type enrich(String resourceUri, AggregationStrategy aggregationStrategy, boolean aggregateOnException, boolean shareUnitOfWork) {
3259        EnrichDefinition answer = new EnrichDefinition();
3260        answer.setExpression(new ConstantExpression(resourceUri));
3261        answer.setAggregationStrategy(aggregationStrategy);
3262        answer.setAggregateOnException(aggregateOnException);
3263        answer.setShareUnitOfWork(shareUnitOfWork);
3264        addOutput(answer);
3265        return (Type) this;
3266    }
3267
3268    /**
3269     * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
3270     * enriches an exchange with additional data obtained from a <code>resourceUri</code>.
3271     * <p/>
3272     * The difference between this and {@link #pollEnrich(String)} is that this uses a producer
3273     * to obtain the additional data, where as pollEnrich uses a polling consumer.
3274     *
3275     * @param resourceRef            Reference of resource endpoint for obtaining additional data.
3276     * @param aggregationStrategyRef Reference of aggregation strategy to aggregate input data and additional data.
3277     * @return the builder
3278     * @see org.apache.camel.processor.Enricher
3279     */
3280    public Type enrichRef(String resourceRef, String aggregationStrategyRef) {
3281        return enrichRef(resourceRef, aggregationStrategyRef, false);
3282    }
3283
3284    /**
3285     * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
3286     * enriches an exchange with additional data obtained from a <code>resourceUri</code>.
3287     * <p/>
3288     * The difference between this and {@link #pollEnrich(String)} is that this uses a producer
3289     * to obtain the additional data, where as pollEnrich uses a polling consumer.
3290     *
3291     * @param resourceRef            Reference of resource endpoint for obtaining additional data.
3292     * @param aggregationStrategyRef Reference of aggregation strategy to aggregate input data and additional data.
3293     * @param aggregateOnException   whether to call {@link org.apache.camel.processor.aggregate.AggregationStrategy#aggregate(org.apache.camel.Exchange, org.apache.camel.Exchange)} if
3294     *                               an exception was thrown.
3295     * @return the builder
3296     * @see org.apache.camel.processor.Enricher
3297     */
3298    public Type enrichRef(String resourceRef, String aggregationStrategyRef, boolean aggregateOnException) {
3299        return enrichRef(resourceRef, aggregationStrategyRef, false, false);
3300    }
3301
3302    /**
3303     * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
3304     * enriches an exchange with additional data obtained from a <code>resourceUri</code>.
3305     * <p/>
3306     * The difference between this and {@link #pollEnrich(String)} is that this uses a producer
3307     * to obtain the additional data, where as pollEnrich uses a polling consumer.
3308     *
3309     * @param resourceRef            Reference of resource endpoint for obtaining additional data.
3310     * @param aggregationStrategyRef Reference of aggregation strategy to aggregate input data and additional data.
3311     * @param aggregateOnException   whether to call {@link org.apache.camel.processor.aggregate.AggregationStrategy#aggregate(org.apache.camel.Exchange, org.apache.camel.Exchange)} if
3312     *                               an exception was thrown.
3313     * @param shareUnitOfWork        whether to share unit of work
3314     * @return the builder
3315     * @see org.apache.camel.processor.Enricher
3316     */
3317    @SuppressWarnings("unchecked")
3318    public Type enrichRef(String resourceRef, String aggregationStrategyRef, boolean aggregateOnException, boolean shareUnitOfWork) {
3319        EnrichDefinition answer = new EnrichDefinition();
3320        answer.setExpression(new SimpleExpression("ref:" + resourceRef));
3321        answer.setAggregationStrategyRef(aggregationStrategyRef);
3322        answer.setAggregateOnException(aggregateOnException);
3323        answer.setShareUnitOfWork(shareUnitOfWork);
3324        addOutput(answer);
3325        return (Type) this;
3326    }
3327
3328    /**
3329     * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
3330     * enriches an exchange with additional data obtained from a <code>resourceUri</code>.
3331     * <p/>
3332     * The difference between this and {@link #pollEnrich(String)} is that this uses a producer
3333     * to obtain the additional data, where as pollEnrich uses a polling consumer.
3334     *
3335     * @return a expression builder clause to set the expression to use for computing the endpoint to use
3336     * @see org.apache.camel.processor.PollEnricher
3337     */
3338    public ExpressionClause<EnrichDefinition> enrich() {
3339        EnrichDefinition answer = new EnrichDefinition();
3340        addOutput(answer);
3341        return ExpressionClause.createAndSetExpression(answer);
3342    }
3343
3344    /**
3345     * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
3346     * enriches an exchange with additional data obtained from a <code>resourceUri</code>
3347     * using a {@link org.apache.camel.PollingConsumer} to poll the endpoint.
3348     * <p/>
3349     * The difference between this and {@link #enrich(String)} is that this uses a consumer
3350     * to obtain the additional data, where as enrich uses a producer.
3351     * <p/>
3352     * This method will <tt>block</tt> until data is available, use the method with timeout if you do not
3353     * want to risk waiting a long time before data is available from the resourceUri.
3354     *
3355     * @param resourceUri           URI of resource endpoint for obtaining additional data.
3356     * @return the builder
3357     * @see org.apache.camel.processor.PollEnricher
3358     */
3359    @SuppressWarnings("unchecked")
3360    public Type pollEnrich(String resourceUri) {
3361        return pollEnrich(resourceUri, null);
3362    }
3363
3364    /**
3365     * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
3366     * enriches an exchange with additional data obtained from a <code>resourceUri</code>
3367     * using a {@link org.apache.camel.PollingConsumer} to poll the endpoint.
3368     * <p/>
3369     * The difference between this and {@link #enrich(String)} is that this uses a consumer
3370     * to obtain the additional data, where as enrich uses a producer.
3371     * <p/>
3372     * This method will <b>block</b> until data is available, use the method with timeout if you do not
3373     * want to risk waiting a long time before data is available from the resourceUri.
3374     *
3375     * @param resourceUri           URI of resource endpoint for obtaining additional data.
3376     * @param aggregationStrategy   aggregation strategy to aggregate input data and additional data.
3377     * @return the builder
3378     * @see org.apache.camel.processor.PollEnricher
3379     */
3380    @SuppressWarnings("unchecked")
3381    public Type pollEnrich(String resourceUri, AggregationStrategy aggregationStrategy) {
3382        return pollEnrich(resourceUri, -1, aggregationStrategy);
3383    }
3384
3385    /**
3386     * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
3387     * enriches an exchange with additional data obtained from a <code>resourceUri</code>
3388     * using a {@link org.apache.camel.PollingConsumer} to poll the endpoint.
3389     * <p/>
3390     * The difference between this and {@link #enrich(String)} is that this uses a consumer
3391     * to obtain the additional data, where as enrich uses a producer.
3392     * <p/>
3393     * The timeout controls which operation to use on {@link org.apache.camel.PollingConsumer}.
3394     * If timeout is negative, we use <tt>receive</tt>. If timeout is 0 then we use <tt>receiveNoWait</tt>
3395     * otherwise we use <tt>receive(timeout)</tt>.
3396     *
3397     * @param resourceUri           URI of resource endpoint for obtaining additional data.
3398     * @param timeout               timeout in millis to wait at most for data to be available.
3399     * @param aggregationStrategy   aggregation strategy to aggregate input data and additional data.
3400     * @return the builder
3401     * @see org.apache.camel.processor.PollEnricher
3402     */
3403    @SuppressWarnings("unchecked")
3404    public Type pollEnrich(String resourceUri, long timeout, AggregationStrategy aggregationStrategy) {
3405        return pollEnrich(resourceUri, timeout, aggregationStrategy, false);
3406    }
3407
3408    /**
3409     * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
3410     * enriches an exchange with additional data obtained from a <code>resourceUri</code>
3411     * using a {@link org.apache.camel.PollingConsumer} to poll the endpoint.
3412     * <p/>
3413     * The difference between this and {@link #enrich(String)} is that this uses a consumer
3414     * to obtain the additional data, where as enrich uses a producer.
3415     * <p/>
3416     * The timeout controls which operation to use on {@link org.apache.camel.PollingConsumer}.
3417     * If timeout is negative, we use <tt>receive</tt>. If timeout is 0 then we use <tt>receiveNoWait</tt>
3418     * otherwise we use <tt>receive(timeout)</tt>.
3419     *
3420     * @param resourceUri           URI of resource endpoint for obtaining additional data.
3421     * @param timeout               timeout in millis to wait at most for data to be available.
3422     * @param aggregationStrategy   aggregation strategy to aggregate input data and additional data.
3423     * @param aggregateOnException   whether to call {@link org.apache.camel.processor.aggregate.AggregationStrategy#aggregate(org.apache.camel.Exchange, org.apache.camel.Exchange)} if
3424     *                               an exception was thrown.
3425     * @return the builder
3426     * @see org.apache.camel.processor.PollEnricher
3427     */
3428    @SuppressWarnings("unchecked")
3429    public Type pollEnrich(String resourceUri, long timeout, AggregationStrategy aggregationStrategy, boolean aggregateOnException) {
3430        PollEnrichDefinition pollEnrich = new PollEnrichDefinition();
3431        pollEnrich.setExpression(new ConstantExpression(resourceUri));
3432        pollEnrich.setTimeout(timeout);
3433        pollEnrich.setAggregationStrategy(aggregationStrategy);
3434        pollEnrich.setAggregateOnException(aggregateOnException);
3435        addOutput(pollEnrich);
3436        return (Type) this;
3437    }
3438
3439    /**
3440     * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
3441     * enriches an exchange with additional data obtained from a <code>resourceUri</code>
3442     * using a {@link org.apache.camel.PollingConsumer} to poll the endpoint.
3443     * <p/>
3444     * The difference between this and {@link #enrich(String)} is that this uses a consumer
3445     * to obtain the additional data, where as enrich uses a producer.
3446     * <p/>
3447     * The timeout controls which operation to use on {@link org.apache.camel.PollingConsumer}.
3448     * If timeout is negative, we use <tt>receive</tt>. If timeout is 0 then we use <tt>receiveNoWait</tt>
3449     * otherwise we use <tt>receive(timeout)</tt>.
3450     *
3451     * @param resourceUri           URI of resource endpoint for obtaining additional data.
3452     * @param timeout               timeout in millis to wait at most for data to be available.
3453     * @return the builder
3454     * @see org.apache.camel.processor.PollEnricher
3455     */
3456    @SuppressWarnings("unchecked")
3457    public Type pollEnrich(String resourceUri, long timeout) {
3458        return pollEnrich(resourceUri, timeout, null);
3459    }
3460
3461    /**
3462     * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
3463     * enriches an exchange with additional data obtained from a <code>resourceUri</code>
3464     * using a {@link org.apache.camel.PollingConsumer} to poll the endpoint.
3465     * <p/>
3466     * The difference between this and {@link #enrich(String)} is that this uses a consumer
3467     * to obtain the additional data, where as enrich uses a producer.
3468     * <p/>
3469     * The timeout controls which operation to use on {@link org.apache.camel.PollingConsumer}.
3470     * If timeout is negative, we use <tt>receive</tt>. If timeout is 0 then we use <tt>receiveNoWait</tt>
3471     * otherwise we use <tt>receive(timeout)</tt>.
3472     *
3473     * @param resourceRef            Reference of resource endpoint for obtaining additional data.
3474     * @param timeout                timeout in millis to wait at most for data to be available.
3475     * @param aggregationStrategyRef Reference of aggregation strategy to aggregate input data and additional data.
3476     * @return the builder
3477     * @see org.apache.camel.processor.PollEnricher
3478     */
3479    @SuppressWarnings("unchecked")
3480    public Type pollEnrichRef(String resourceRef, long timeout, String aggregationStrategyRef) {
3481        PollEnrichDefinition pollEnrich = new PollEnrichDefinition();
3482        pollEnrich.setExpression(new SimpleExpression("ref:" + resourceRef));
3483        pollEnrich.setTimeout(timeout);
3484        pollEnrich.setAggregationStrategyRef(aggregationStrategyRef);
3485        addOutput(pollEnrich);
3486        return (Type) this;
3487    }
3488
3489    /**
3490     * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
3491     * enriches an exchange with additional data obtained from a <code>resourceUri</code>
3492     * using a {@link org.apache.camel.PollingConsumer} to poll the endpoint.
3493     * <p/>
3494     * The difference between this and {@link #enrich(String)} is that this uses a consumer
3495     * to obtain the additional data, where as enrich uses a producer.
3496     * <p/>
3497     * The timeout controls which operation to use on {@link org.apache.camel.PollingConsumer}.
3498     * If timeout is negative, we use <tt>receive</tt>. If timeout is 0 then we use <tt>receiveNoWait</tt>
3499     * otherwise we use <tt>receive(timeout)</tt>.
3500     *
3501     * @param resourceRef            Reference of resource endpoint for obtaining additional data.
3502     * @param timeout                timeout in millis to wait at most for data to be available.
3503     * @param aggregationStrategyRef Reference of aggregation strategy to aggregate input data and additional data.
3504     * @param aggregateOnException   whether to call {@link org.apache.camel.processor.aggregate.AggregationStrategy#aggregate(org.apache.camel.Exchange, org.apache.camel.Exchange)} if
3505     *                               an exception was thrown.
3506     * @return the builder
3507     * @see org.apache.camel.processor.PollEnricher
3508     */
3509    @SuppressWarnings("unchecked")
3510    public Type pollEnrichRef(String resourceRef, long timeout, String aggregationStrategyRef, boolean aggregateOnException) {
3511        PollEnrichDefinition pollEnrich = new PollEnrichDefinition();
3512        pollEnrich.setExpression(new SimpleExpression("ref:" + resourceRef));
3513        pollEnrich.setTimeout(timeout);
3514        pollEnrich.setAggregationStrategyRef(aggregationStrategyRef);
3515        pollEnrich.setAggregateOnException(aggregateOnException);
3516        addOutput(pollEnrich);
3517        return (Type) this;
3518    }
3519
3520    /**
3521     * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
3522     * enriches an exchange with additional data obtained from a <code>resourceUri</code>
3523     * using a {@link org.apache.camel.PollingConsumer} to poll the endpoint.
3524     * <p/>
3525     * The difference between this and {@link #enrich(String)} is that this uses a consumer
3526     * to obtain the additional data, where as enrich uses a producer.
3527     * <p/>
3528     * The timeout controls which operation to use on {@link org.apache.camel.PollingConsumer}.
3529     * If timeout is negative, we use <tt>receive</tt>. If timeout is 0 then we use <tt>receiveNoWait</tt>
3530     * otherwise we use <tt>receive(timeout)</tt>.
3531     *
3532     * @param expression             to use an expression to dynamically compute the endpoint to poll from
3533     * @param timeout                timeout in millis to wait at most for data to be available.
3534     * @param aggregationStrategyRef Reference of aggregation strategy to aggregate input data and additional data.
3535     * @param aggregateOnException   whether to call {@link org.apache.camel.processor.aggregate.AggregationStrategy#aggregate(org.apache.camel.Exchange, org.apache.camel.Exchange)} if
3536     *                               an exception was thrown.
3537     * @return the builder
3538     * @see org.apache.camel.processor.PollEnricher
3539     */
3540    @SuppressWarnings("unchecked")
3541    public Type pollEnrich(Expression expression, long timeout, String aggregationStrategyRef, boolean aggregateOnException) {
3542        PollEnrichDefinition pollEnrich = new PollEnrichDefinition();
3543        pollEnrich.setExpression(new ExpressionDefinition(expression));
3544        pollEnrich.setTimeout(timeout);
3545        pollEnrich.setAggregationStrategyRef(aggregationStrategyRef);
3546        pollEnrich.setAggregateOnException(aggregateOnException);
3547        addOutput(pollEnrich);
3548        return (Type) this;
3549    }
3550
3551    /**
3552     * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
3553     * enriches an exchange with additional data obtained from a <code>resourceUri</code>
3554     * using a {@link org.apache.camel.PollingConsumer} to poll the endpoint.
3555     * <p/>
3556     * The difference between this and {@link #enrich(String)} is that this uses a consumer
3557     * to obtain the additional data, where as enrich uses a producer.
3558     * <p/>
3559     * The timeout controls which operation to use on {@link org.apache.camel.PollingConsumer}.
3560     * If timeout is negative, we use <tt>receive</tt>. If timeout is 0 then we use <tt>receiveNoWait</tt>
3561     * otherwise we use <tt>receive(timeout)</tt>.
3562     *
3563     * @return a expression builder clause to set the expression to use for computing the endpoint to poll from
3564     * @see org.apache.camel.processor.PollEnricher
3565     */
3566    public ExpressionClause<PollEnrichDefinition> pollEnrich() {
3567        PollEnrichDefinition answer = new PollEnrichDefinition();
3568        addOutput(answer);
3569        return ExpressionClause.createAndSetExpression(answer);
3570    }
3571
3572    /**
3573     * Adds a onComplection {@link org.apache.camel.spi.Synchronization} hook that invoke this route as
3574     * a callback when the {@link org.apache.camel.Exchange} has finished being processed.
3575     * The hook invoke callbacks for either onComplete or onFailure.
3576     * <p/>
3577     * Will by default always trigger when the {@link org.apache.camel.Exchange} is complete
3578     * (either with success or failed).
3579     * <br/>
3580     * You can limit the callback to either onComplete or onFailure but invoking the nested
3581     * builder method.
3582     * <p/>
3583     * For onFailure the caused exception is stored as a property on the {@link org.apache.camel.Exchange}
3584     * with the key {@link org.apache.camel.Exchange#EXCEPTION_CAUGHT}.
3585     *
3586     * @return the builder
3587     */
3588    public OnCompletionDefinition onCompletion() {
3589        OnCompletionDefinition answer = new OnCompletionDefinition();
3590        // we must remove all existing on completion definition (as they are global)
3591        // and thus we are the only one as route scoped should override any global scoped
3592        answer.removeAllOnCompletionDefinition(this);
3593        popBlock();
3594        addOutput(answer);
3595        pushBlock(answer);
3596        return answer;
3597    }
3598
3599    // DataFormat support
3600    // -------------------------------------------------------------------------
3601
3602    /**
3603     * <a href="http://camel.apache.org/data-format.html">DataFormat:</a>
3604     * Unmarshals the in body using a {@link DataFormat} expression to define
3605     * the format of the input message and the output will be set on the out message body.
3606     *
3607     * @return the expression to create the {@link DataFormat}
3608     */
3609    public DataFormatClause<ProcessorDefinition<Type>> unmarshal() {
3610        return new DataFormatClause<ProcessorDefinition<Type>>(this, DataFormatClause.Operation.Unmarshal);
3611    }
3612
3613    /**
3614     * <a href="http://camel.apache.org/data-format.html">DataFormat:</a>
3615     * Unmarshals the in body using the specified {@link DataFormat}
3616     * and sets the output on the out message body.
3617     *
3618     * @param dataFormatType  the dataformat
3619     * @return the builder
3620     */
3621    @SuppressWarnings("unchecked")
3622    public Type unmarshal(DataFormatDefinition dataFormatType) {
3623        addOutput(new UnmarshalDefinition(dataFormatType));
3624        return (Type) this;
3625    }
3626
3627    /**
3628     * <a href="http://camel.apache.org/data-format.html">DataFormat:</a>
3629     * Unmarshals the in body using the specified {@link DataFormat}
3630     * and sets the output on the out message body.
3631     *
3632     * @param dataFormat  the dataformat
3633     * @return the builder
3634     */
3635    public Type unmarshal(DataFormat dataFormat) {
3636        return unmarshal(new DataFormatDefinition(dataFormat));
3637    }
3638
3639    /**
3640     * <a href="http://camel.apache.org/data-format.html">DataFormat:</a>
3641     * Unmarshals the in body using the specified {@link DataFormat}
3642     * reference in the {@link org.apache.camel.spi.Registry} and sets
3643     * the output on the out message body.
3644     *
3645     * @param dataTypeRef  reference to a {@link DataFormat} to lookup in the registry
3646     * @return the builder
3647     */
3648    @SuppressWarnings("unchecked")
3649    public Type unmarshal(String dataTypeRef) {
3650        addOutput(new UnmarshalDefinition(dataTypeRef));
3651        return (Type) this;
3652    }
3653
3654    /**
3655     * <a href="http://camel.apache.org/data-format.html">DataFormat:</a>
3656     * Marshals the in body using a {@link DataFormat} expression to define
3657     * the format of the output which will be added to the out body.
3658     *
3659     * @return the expression to create the {@link DataFormat}
3660     */
3661    public DataFormatClause<ProcessorDefinition<Type>> marshal() {
3662        return new DataFormatClause<ProcessorDefinition<Type>>(this, DataFormatClause.Operation.Marshal);
3663    }
3664
3665    /**
3666     * <a href="http://camel.apache.org/data-format.html">DataFormat:</a>
3667     * Marshals the in body using the specified {@link DataFormat}
3668     * and sets the output on the out message body.
3669     *
3670     * @param dataFormatType  the dataformat
3671     * @return the builder
3672     */
3673    @SuppressWarnings("unchecked")
3674    public Type marshal(DataFormatDefinition dataFormatType) {
3675        addOutput(new MarshalDefinition(dataFormatType));
3676        return (Type) this;
3677    }
3678
3679    /**
3680     * <a href="http://camel.apache.org/data-format.html">DataFormat:</a>
3681     * Marshals the in body using the specified {@link DataFormat}
3682     * and sets the output on the out message body.
3683     *
3684     * @param dataFormat  the dataformat
3685     * @return the builder
3686     */
3687    public Type marshal(DataFormat dataFormat) {
3688        return marshal(new DataFormatDefinition(dataFormat));
3689    }
3690
3691    /**
3692     * <a href="http://camel.apache.org/data-format.html">DataFormat:</a>
3693     * Marshals the in body the specified {@link DataFormat}
3694     * reference in the {@link org.apache.camel.spi.Registry} and sets
3695     * the output on the out message body.
3696     *
3697     * @param dataTypeRef  reference to a {@link DataFormat} to lookup in the registry
3698     * @return the builder
3699     */
3700    @SuppressWarnings("unchecked")
3701    public Type marshal(String dataTypeRef) {
3702        addOutput(new MarshalDefinition(dataTypeRef));
3703        return (Type) this;
3704    }
3705
3706    /**
3707     * Sets whether or not to inherit the configured error handler.
3708     * <br/>
3709     * The default value is <tt>true</tt>.
3710     * <p/>
3711     * You can use this to disable using the inherited error handler for a given
3712     * DSL such as a load balancer where you want to use a custom error handler strategy.
3713     *
3714     * @param inheritErrorHandler whether to not to inherit the error handler for this node
3715     * @return the builder
3716     */
3717    @SuppressWarnings("unchecked")
3718    public Type inheritErrorHandler(boolean inheritErrorHandler) {
3719        // set on last output
3720        int size = getOutputs().size();
3721        if (size == 0) {
3722            // if no outputs then configure this DSL
3723            setInheritErrorHandler(inheritErrorHandler);
3724        } else {
3725            // configure on last output as its the intended
3726            ProcessorDefinition<?> output = getOutputs().get(size - 1);
3727            if (output != null) {
3728                output.setInheritErrorHandler(inheritErrorHandler);
3729            }
3730        }
3731        return (Type) this;
3732    }
3733
3734    // Properties
3735    // -------------------------------------------------------------------------
3736    public ProcessorDefinition<?> getParent() {
3737        return parent;
3738    }
3739
3740    public void setParent(ProcessorDefinition<?> parent) {
3741        this.parent = parent;
3742    }
3743
3744    public List<InterceptStrategy> getInterceptStrategies() {
3745        return interceptStrategies;
3746    }
3747
3748    public void addInterceptStrategy(InterceptStrategy strategy) {
3749        this.interceptStrategies.add(strategy);
3750    }
3751
3752    public Boolean isInheritErrorHandler() {
3753        return inheritErrorHandler;
3754    }
3755
3756    public void setInheritErrorHandler(Boolean inheritErrorHandler) {
3757        this.inheritErrorHandler = inheritErrorHandler;
3758    }
3759
3760    @Override
3761    public Map<QName, Object> getOtherAttributes() {
3762        return otherAttributes;
3763    }
3764
3765    @Override
3766    public void setOtherAttributes(Map<QName, Object> otherAttributes) {
3767        this.otherAttributes = otherAttributes;
3768    }
3769
3770    /**
3771     * Returns a label to describe this node such as the expression if some kind of expression node
3772     */
3773    public String getLabel() {
3774        return "";
3775    }
3776    
3777}