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