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