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