001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.camel.model;
018    
019    import java.util.ArrayList;
020    import java.util.Arrays;
021    import java.util.Collection;
022    import java.util.Collections;
023    import java.util.Comparator;
024    import java.util.LinkedList;
025    import java.util.List;
026    
027    import javax.xml.bind.annotation.XmlAccessType;
028    import javax.xml.bind.annotation.XmlAccessorType;
029    import javax.xml.bind.annotation.XmlAttribute;
030    import javax.xml.bind.annotation.XmlTransient;
031    
032    import org.apache.camel.Channel;
033    import org.apache.camel.Endpoint;
034    import org.apache.camel.ExchangePattern;
035    import org.apache.camel.Expression;
036    import org.apache.camel.Predicate;
037    import org.apache.camel.Processor;
038    import org.apache.camel.Route;
039    import org.apache.camel.builder.DataFormatClause;
040    import org.apache.camel.builder.ErrorHandlerBuilder;
041    import org.apache.camel.builder.ErrorHandlerBuilderRef;
042    import org.apache.camel.builder.ExpressionBuilder;
043    import org.apache.camel.builder.ExpressionClause;
044    import org.apache.camel.builder.ProcessorBuilder;
045    import org.apache.camel.model.language.ConstantExpression;
046    import org.apache.camel.model.language.ExpressionDefinition;
047    import org.apache.camel.model.language.LanguageExpression;
048    import org.apache.camel.processor.DefaultChannel;
049    import org.apache.camel.processor.InterceptEndpointProcessor;
050    import org.apache.camel.processor.Pipeline;
051    import org.apache.camel.processor.aggregate.AggregationCollection;
052    import org.apache.camel.processor.aggregate.AggregationStrategy;
053    import org.apache.camel.processor.loadbalancer.LoadBalancer;
054    import org.apache.camel.spi.DataFormat;
055    import org.apache.camel.spi.IdempotentRepository;
056    import org.apache.camel.spi.InterceptStrategy;
057    import org.apache.camel.spi.Policy;
058    import org.apache.camel.spi.RouteContext;
059    import org.apache.camel.spi.TransactedPolicy;
060    import org.apache.commons.logging.Log;
061    import org.apache.commons.logging.LogFactory;
062    
063    import static org.apache.camel.builder.Builder.body;
064    
065    /**
066     * Base class for processor types that most XML types extend.
067     *
068     * @version $Revision: 794544 $
069     */
070    @XmlAccessorType(XmlAccessType.PROPERTY)
071    public abstract class ProcessorDefinition<Type extends ProcessorDefinition> extends OptionalIdentifiedType<Type> implements Block {
072        private static final transient Log LOG = LogFactory.getLog(ProcessorDefinition.class);
073        private ErrorHandlerBuilder errorHandlerBuilder;
074        private NodeFactory nodeFactory;
075        private final LinkedList<Block> blocks = new LinkedList<Block>();
076        private ProcessorDefinition parent;
077        private String errorHandlerRef;
078        private final List<InterceptStrategy> interceptStrategies = new ArrayList<InterceptStrategy>();
079    
080        // else to use an optional attribute in JAXB2
081        public abstract List<ProcessorDefinition> getOutputs();
082    
083    
084        public Processor createProcessor(RouteContext routeContext) throws Exception {
085            throw new UnsupportedOperationException("Not implemented yet for class: " + getClass().getName());
086        }
087    
088        public Processor createOutputsProcessor(RouteContext routeContext) throws Exception {
089            Collection<ProcessorDefinition> outputs = getOutputs();
090            return createOutputsProcessor(routeContext, outputs);
091        }
092    
093        @SuppressWarnings("unchecked")
094        public void addOutput(ProcessorDefinition processorType) {
095            processorType.setParent(this);
096            configureChild(processorType);
097            if (blocks.isEmpty()) {
098                getOutputs().add(processorType);
099            } else {
100                Block block = blocks.getLast();
101                block.addOutput(processorType);
102            }
103        }
104    
105        public void clearOutput() {
106            getOutputs().clear();
107            blocks.clear();
108        }
109    
110        public void addRoutes(RouteContext routeContext, Collection<Route> routes) throws Exception {
111            Processor processor = makeProcessor(routeContext);
112            if (processor == null) {
113                // no processor to add
114                return;
115            }
116    
117            if (!routeContext.isRouteAdded()) {
118                boolean endpointInterceptor = false;
119    
120                // are we routing to an endpoint interceptor, if so we should not add it as an event driven
121                // processor as we use the producer to trigger the interceptor
122                if (processor instanceof Channel) {
123                    Channel channel = (Channel) processor;
124                    Processor next = channel.getNextProcessor();
125                    if (next instanceof InterceptEndpointProcessor) {
126                        endpointInterceptor = true;
127                    }
128                }
129    
130                // only add regular processors as event driven
131                if (endpointInterceptor) {
132                    if (LOG.isDebugEnabled()) {
133                        LOG.debug("Endpoint interceptor should not be added as an event driven consumer route: " + processor);
134                    }
135                } else {
136                    if (LOG.isTraceEnabled()) {
137                        LOG.trace("Adding event driven processor: " + processor);
138                    }
139                    routeContext.addEventDrivenProcessor(processor);
140                }
141    
142            }
143        }
144    
145        /**
146         * Wraps the child processor in whatever necessary interceptors and error handlers
147         */
148        public Processor wrapProcessor(RouteContext routeContext, Processor processor) throws Exception {
149            // dont double wrap
150            if (processor instanceof Channel) {
151                return processor;
152            }
153            return wrapChannel(routeContext, processor);
154        }
155    
156        protected Processor wrapChannel(RouteContext routeContext, Processor processor) throws Exception {
157            // put a channel inbetween this and each output to control the route flow logic
158            Channel channel = createChannel(routeContext);
159            channel.setNextProcessor(processor);
160    
161            // add interceptor strategies to the channel
162            channel.addInterceptStrategies(routeContext.getCamelContext().getInterceptStrategies());
163            channel.addInterceptStrategies(routeContext.getInterceptStrategies());
164            channel.addInterceptStrategies(this.getInterceptStrategies());
165    
166            // init the channel
167            channel.initChannel(this, routeContext);
168    
169            // set the error handler, must be done after init as we can set the error handler as first in the chain
170            if (this instanceof TryDefinition || this instanceof CatchDefinition || this instanceof FinallyDefinition) {
171                // do not use error handler for try .. catch .. finally blocks as it will handle errors itself
172                return channel;
173            } else {
174                // regular definition so add the error handler
175                Processor output = channel.getOutput();
176                Processor errorHandler = getErrorHandlerBuilder().createErrorHandler(routeContext, output);
177                channel.setErrorHandler(errorHandler);
178                return channel;
179            }
180        }
181    
182        /**
183         * Creates a new instance of some kind of composite processor which defaults
184         * to using a {@link Pipeline} but derived classes could change the behaviour
185         */
186        protected Processor createCompositeProcessor(RouteContext routeContext, List<Processor> list) {
187            return new Pipeline(list);
188        }
189    
190        /**
191         * Creates a new instance of the {@link Channel}.
192         */
193        protected Channel createChannel(RouteContext routeContext) {
194            return new DefaultChannel();
195        }
196    
197        protected Processor createOutputsProcessor(RouteContext routeContext, Collection<ProcessorDefinition> outputs) throws Exception {
198            List<Processor> list = new ArrayList<Processor>();
199            for (ProcessorDefinition output : outputs) {
200                Processor processor = output.createProcessor(routeContext);
201                if (output instanceof Channel && processor == null) {
202                    continue;
203                }
204    
205                Processor channel = wrapChannel(routeContext, processor);
206                list.add(channel);
207            }
208    
209            // if more than one output wrap than in a composite processor else just keep it as is
210            Processor processor = null;
211            if (!list.isEmpty()) {
212                if (list.size() == 1) {
213                    processor = list.get(0);
214                } else {
215                    processor = createCompositeProcessor(routeContext, list);
216                }
217            }
218    
219            return processor;
220        }
221    
222        /**
223         * Creates the processor and wraps it in any necessary interceptors and error handlers
224         */
225        protected Processor makeProcessor(RouteContext routeContext) throws Exception {
226            Processor processor = createProcessor(routeContext);
227            if (processor == null) {
228                // no processor to make
229                return null;
230            }
231            return wrapProcessor(routeContext, processor);
232        }
233    
234        protected ErrorHandlerBuilder createErrorHandlerBuilder() {
235            if (errorHandlerRef != null) {
236                return new ErrorHandlerBuilderRef(errorHandlerRef);
237            }
238    
239            // return a reference to the default error handler
240            return new ErrorHandlerBuilderRef(ErrorHandlerBuilderRef.DEFAULT_ERROR_HANDLER_BUILDER);
241        }
242    
243        protected void configureChild(ProcessorDefinition output) {
244            output.setNodeFactory(getNodeFactory());
245            output.setErrorHandlerBuilder(getErrorHandlerBuilder());
246        }
247    
248        // Fluent API
249        // -------------------------------------------------------------------------
250    
251        /**
252         * Sends the exchange to the given endpoint
253         *
254         * @param uri  the endpoint to send to
255         * @return the builder
256         */
257        @SuppressWarnings("unchecked")
258        public Type to(String uri) {
259            addOutput(new ToDefinition(uri));
260            return (Type) this;
261        }   
262        
263        /**
264         * Sends the exchange to the given endpoint
265         *
266         * @param uri  the String formatted endpoint uri to send to
267         * @param args arguments for the string formatting of the uri
268         * @return the builder
269         */
270        @SuppressWarnings("unchecked")
271        public Type toF(String uri, Object... args) {
272            addOutput(new ToDefinition(String.format(uri, args)));
273            return (Type) this;
274        }
275    
276    
277        /**
278         * Sends the exchange to the given endpoint
279         *
280         * @param endpoint  the endpoint to send to
281         * @return the builder
282         */
283        @SuppressWarnings("unchecked")
284        public Type to(Endpoint endpoint) {
285            addOutput(new ToDefinition(endpoint));
286            return (Type) this;
287        }
288        
289        /**
290         * Sends the exchange with certain exchange pattern to the given endpoint
291         *
292         * @param pattern the pattern to use for the message exchange
293         * @param uri  the endpoint to send to
294         * @return the builder
295         */
296        @SuppressWarnings("unchecked")
297        public Type to(ExchangePattern pattern, String uri) {
298            addOutput(new ToDefinition(uri, pattern));
299            return (Type) this;
300        }   
301        
302    
303        /**
304         * Sends the exchange with certain exchange pattern to the given endpoint
305         *
306         * @param pattern the pattern to use for the message exchange
307         * @param endpoint  the endpoint to send to
308         * @return the builder
309         */
310        @SuppressWarnings("unchecked")
311        public Type to(ExchangePattern pattern, Endpoint endpoint) {
312            addOutput(new ToDefinition(endpoint, pattern));
313            return (Type) this;
314        }
315    
316        /**
317         * Sends the exchange to a list of endpoints
318         *
319         * @param uris  list of endpoints to send to
320         * @return the builder
321         */
322        @SuppressWarnings("unchecked")
323        public Type to(String... uris) {
324            for (String uri : uris) {
325                addOutput(new ToDefinition(uri));
326            }
327            return (Type) this;
328        }
329    
330    
331        /**
332         * Sends the exchange to a list of endpoints
333         *
334         * @param endpoints  list of endpoints to send to
335         * @return the builder
336         */
337        @SuppressWarnings("unchecked")
338        public Type to(Endpoint... endpoints) {
339            for (Endpoint endpoint : endpoints) {
340                addOutput(new ToDefinition(endpoint));
341            }
342            return (Type) this;
343        }
344    
345        /**
346         * Sends the exchange to a list of endpoints
347         *
348         * @param endpoints  list of endpoints to send to
349         * @return the builder
350         */
351        @SuppressWarnings("unchecked")
352        public Type to(Iterable<Endpoint> endpoints) {
353            for (Endpoint endpoint : endpoints) {
354                addOutput(new ToDefinition(endpoint));
355            }
356            return (Type) this;
357        }
358        
359        
360        /**
361         * Sends the exchange to a list of endpoints
362         *
363         * @param pattern the pattern to use for the message exchanges
364         * @param uris  list of endpoints to send to
365         * @return the builder
366         */
367        @SuppressWarnings("unchecked")
368        public Type to(ExchangePattern pattern, String... uris) {
369            for (String uri : uris) {
370                addOutput(new ToDefinition(uri, pattern));
371            }
372            return (Type) this;
373        }
374    
375        /**
376         * Sends the exchange to a list of endpoints
377         *
378         * @param pattern the pattern to use for the message exchanges
379         * @param endpoints  list of endpoints to send to
380         * @return the builder
381         */
382        @SuppressWarnings("unchecked")
383        public Type to(ExchangePattern pattern, Endpoint... endpoints) {
384            for (Endpoint endpoint : endpoints) {
385                addOutput(new ToDefinition(endpoint, pattern));
386            }
387            return (Type) this;
388        }
389    
390        /**
391         * Sends the exchange to a list of endpoints
392         *
393         * @param pattern the pattern to use for the message exchanges
394         * @param endpoints  list of endpoints to send to
395         * @return the builder
396         */
397        @SuppressWarnings("unchecked")
398        public Type to(ExchangePattern pattern, Iterable<Endpoint> endpoints) {
399            for (Endpoint endpoint : endpoints) {
400                addOutput(new ToDefinition(endpoint, pattern));
401            }
402            return (Type) this;
403        }
404    
405    
406        /**
407         * <a href="http://camel.apache.org/exchange-pattern.html">ExchangePattern:</a>
408         * set the ExchangePattern {@link ExchangePattern} into the exchange
409         *
410         * @param exchangePattern  instance of {@link ExchangePattern}
411         * @return the builder
412         */
413        @SuppressWarnings("unchecked")
414        public Type setExchangePattern(ExchangePattern exchangePattern) {
415            addOutput(new SetExchangePatternDefinition(exchangePattern));
416            return (Type) this;
417        }
418    
419        /**
420         * <a href="http://camel.apache.org/exchange-pattern.html">ExchangePattern:</a>
421         * set the exchange's ExchangePattern {@link ExchangePattern} to be InOnly
422         *
423         *
424         * @return the builder
425         */
426        public Type inOnly() {
427            return setExchangePattern(ExchangePattern.InOnly);
428        }
429    
430        /**
431         * Sends the message to the given endpoint using an
432         * <a href="http://camel.apache.org/event-message.html">Event Message</a> or
433         * <a href="http://camel.apache.org/exchange-pattern.html">InOnly exchange pattern</a>
434         *
435         * @param uri The endpoint uri which is used for sending the exchange
436         * @return the builder
437         */
438        public Type inOnly(String uri) {
439            return to(ExchangePattern.InOnly, uri);
440        }
441    
442        /**
443         * Sends the message to the given endpoint using an
444         * <a href="http://camel.apache.org/event-message.html">Event Message</a> or 
445         * <a href="http://camel.apache.org/exchange-pattern.html">InOnly exchange pattern</a>
446         *
447         * @param endpoint The endpoint which is used for sending the exchange
448         * @return the builder
449         */
450        public Type inOnly(Endpoint endpoint) {
451            return to(ExchangePattern.InOnly, endpoint);
452        }
453    
454    
455        /**
456         * Sends the message to the given endpoints using an
457         * <a href="http://camel.apache.org/event-message.html">Event Message</a> or
458         * <a href="http://camel.apache.org/exchange-pattern.html">InOnly exchange pattern</a>
459         *
460         * @param uris  list of endpoints to send to
461         * @return the builder
462         */
463        public Type inOnly(String... uris) {
464            return to(ExchangePattern.InOnly, uris);
465        }
466    
467    
468        /**
469         * Sends the message to the given endpoints using an
470         * <a href="http://camel.apache.org/event-message.html">Event Message</a> or
471         * <a href="http://camel.apache.org/exchange-pattern.html">InOnly exchange pattern</a>
472         *
473         * @param endpoints  list of endpoints to send to
474         * @return the builder
475         */
476        public Type inOnly(Endpoint... endpoints) {
477            return to(ExchangePattern.InOnly, endpoints);
478        }
479    
480        /**
481         * Sends the message to the given endpoints using an
482         * <a href="http://camel.apache.org/event-message.html">Event Message</a> or
483         * <a href="http://camel.apache.org/exchange-pattern.html">InOnly exchange pattern</a>
484         *
485         * @param endpoints  list of endpoints to send to
486         * @return the builder
487         */
488        public Type inOnly(Iterable<Endpoint> endpoints) {
489            return to(ExchangePattern.InOnly, endpoints);
490        }
491    
492    
493        /**
494         * <a href="http://camel.apache.org/exchange-pattern.html">ExchangePattern:</a>
495         * set the exchange's ExchangePattern {@link ExchangePattern} to be InOut
496         *
497         *
498         * @return the builder
499         */
500        public Type inOut() {
501            return setExchangePattern(ExchangePattern.InOut);
502        }
503    
504        /**
505         * Sends the message to the given endpoint using an
506         * <a href="http://camel.apache.org/request-reply.html">Request Reply</a> or
507         * <a href="http://camel.apache.org/exchange-pattern.html">InOut exchange pattern</a>
508         *
509         * @param uri The endpoint uri which is used for sending the exchange
510         * @return the builder
511         */
512        public Type inOut(String uri) {
513            return to(ExchangePattern.InOut, uri);
514        }
515    
516    
517        /**
518         * Sends the message to the given endpoint using an
519         * <a href="http://camel.apache.org/request-reply.html">Request Reply</a> or
520         * <a href="http://camel.apache.org/exchange-pattern.html">InOut exchange pattern</a>
521         *
522         * @param endpoint The endpoint which is used for sending the exchange
523         * @return the builder
524         */
525        public Type inOut(Endpoint endpoint) {
526            return to(ExchangePattern.InOut, endpoint);
527        }
528    
529        /**
530         * Sends the message to the given endpoints using an
531         * <a href="http://camel.apache.org/request-reply.html">Request Reply</a> or
532         * <a href="http://camel.apache.org/exchange-pattern.html">InOut exchange pattern</a>
533         *
534         * @param uris  list of endpoints to send to
535         * @return the builder
536         */
537        public Type inOut(String... uris) {
538            return to(ExchangePattern.InOut, uris);
539        }
540    
541    
542        /**
543         * Sends the message to the given endpoints using an
544         * <a href="http://camel.apache.org/request-reply.html">Request Reply</a> or
545         * <a href="http://camel.apache.org/exchange-pattern.html">InOut exchange pattern</a>
546         *
547         * @param endpoints  list of endpoints to send to
548         * @return the builder
549         */
550        public Type inOut(Endpoint... endpoints) {
551            return to(ExchangePattern.InOut, endpoints);
552        }
553    
554        /**
555         * Sends the message to the given endpoints using an
556         * <a href="http://camel.apache.org/request-reply.html">Request Reply</a> or
557         * <a href="http://camel.apache.org/exchange-pattern.html">InOut exchange pattern</a>
558         *
559         * @param endpoints  list of endpoints to send to
560         * @return the builder
561         */
562        public Type inOut(Iterable<Endpoint> endpoints) {
563            return to(ExchangePattern.InOut, endpoints);
564        }
565    
566        /**
567         * Sets the id of this node
568         *
569         * @param id  the id
570         * @return the builder
571         */
572        @SuppressWarnings("unchecked")
573        public Type id(String id) {
574            if (getOutputs().isEmpty()) {
575                // set id on this
576                setId(id);
577            } else {
578                // set it on last output as this is what the user means to do
579                getOutputs().get(getOutputs().size() - 1).setId(id);
580            }
581    
582            return (Type) this;
583        }
584    
585        /**
586         * <a href="http://camel.apache.org/multicast.html">Multicast EIP:</a>
587         * Multicasts messages to all its child outputs; so that each processor and
588         * destination gets a copy of the original message to avoid the processors
589         * interfering with each other.
590         *
591         * @return the builder
592         */
593        public MulticastDefinition multicast() {
594            MulticastDefinition answer = new MulticastDefinition();
595            addOutput(answer);
596            return answer;
597        }
598    
599        /**
600         * <a href="http://camel.apache.org/multicast.html">Multicast EIP:</a>
601         * Multicasts messages to all its child outputs; so that each processor and
602         * destination gets a copy of the original message to avoid the processors
603         * interfering with each other.
604         *
605         * @param aggregationStrategy the strategy used to aggregate responses for
606         *          every part
607         * @param parallelProcessing if is <tt>true</tt> camel will fork thread to call the endpoint producer
608         * @return the builder
609         */
610        public MulticastDefinition multicast(AggregationStrategy aggregationStrategy, boolean parallelProcessing) {
611            MulticastDefinition answer = new MulticastDefinition();
612            addOutput(answer);
613            answer.setAggregationStrategy(aggregationStrategy);
614            answer.setParallelProcessing(parallelProcessing);
615            return answer;
616        }
617    
618        /**
619         * <a href="http://camel.apache.org/multicast.html">Multicast EIP:</a>
620         * Multicasts messages to all its child outputs; so that each processor and
621         * destination gets a copy of the original message to avoid the processors
622         * interfering with each other.
623         *
624         * @param aggregationStrategy the strategy used to aggregate responses for
625         *          every part
626         * @return the builder
627         */
628        public MulticastDefinition multicast(AggregationStrategy aggregationStrategy) {
629            MulticastDefinition answer = new MulticastDefinition();
630            addOutput(answer);
631            answer.setAggregationStrategy(aggregationStrategy);
632            return answer;
633        }
634    
635        /**
636         * <a href="http://camel.apache.org/pipes-nd-filters.html">Pipes and Filters EIP:</a>
637         * Creates a {@link Pipeline} of the list of endpoints so that the message
638         * will get processed by each endpoint in turn and for request/response the
639         * output of one endpoint will be the input of the next endpoint
640         *
641         * @param uris  list of endpoints
642         * @return the builder
643         */
644        public Type pipeline(String... uris) {
645            return to(uris);
646        }
647    
648        /**
649         * <a href="http://camel.apache.org/pipes-nd-filters.html">Pipes and Filters EIP:</a>
650         * Creates a {@link Pipeline} of the list of endpoints so that the message
651         * will get processed by each endpoint in turn and for request/response the
652         * output of one endpoint will be the input of the next endpoint
653         *
654         * @param endpoints  list of endpoints
655         * @return the builder
656         */
657        public Type pipeline(Endpoint... endpoints) {
658            return to(endpoints);
659        }
660    
661        /**
662         * <a href="http://camel.apache.org/pipes-nd-filters.html">Pipes and Filters EIP:</a>
663         * Creates a {@link Pipeline} of the list of endpoints so that the message
664         * will get processed by each endpoint in turn and for request/response the
665         * output of one endpoint will be the input of the next endpoint
666         *
667         * @param endpoints  list of endpoints
668         * @return the builder
669         */
670        public Type pipeline(Collection<Endpoint> endpoints) {
671            return to(endpoints);
672        }
673    
674        /**
675         * Leverages a thread pool for multi threading processing exchanges.
676         * <p/>
677         * The caller thread will either wait for the async route
678         * to complete or imeddiately continue. If continue the OUT message will
679         * contain a {@link java.util.concurrent.Future} handle so you can get the real response
680         * later using this handle.
681         * <p/>
682         * Will default <tt>Always</tt> wait for the async route to complete, but this behavior can be overriden by:
683         * <ul>
684         *   <li>Configuring the <tt>waitForTaskToComplete</tt> option</li>
685         *   <li>Provide an IN header with the key {@link org.apache.camel.Exchange#ASYNC_WAIT} with the
686         * value containing a type {@link org.apache.camel.WaitForTaskToComplete}. The header will take precedence, if provided.</li>
687         * </ul>
688         *
689         * @return the builder
690         */
691        public ThreadsDefinition threads() {
692            ThreadsDefinition answer = new ThreadsDefinition();
693            addOutput(answer);
694            return answer;
695        }
696    
697        /**
698         * Leverages a thread pool for multi threading processing exchanges.
699         * <p/>
700         * See {@link #threads()} for more details.
701         *
702         * @param poolSize the core pool size
703         * @return the builder
704         */
705        public ThreadsDefinition threads(int poolSize) {
706            ThreadsDefinition answer = threads();
707            answer.setPoolSize(poolSize);
708            return answer;
709        }
710    
711        /**
712         * Wraps the sub route using AOP allowing you to do before and after work (AOP around).
713         *
714         * @return the builder
715         */
716        public AOPDefinition aop() {
717            AOPDefinition answer = new AOPDefinition();
718            addOutput(answer);
719            return answer;
720        }
721    
722        /**
723         * Ends the current block
724         *
725         * @return the builder
726         */
727        @SuppressWarnings("unchecked")
728        public ProcessorDefinition<? extends ProcessorDefinition> end() {
729            // when using doTry .. doCatch .. doFinally we should always
730            // end the try definition to avoid having to use 2 x end() in the route
731            // this is counter intuitive for end users
732            if (this instanceof TryDefinition) {
733                popBlock();
734            }
735    
736            if (blocks.isEmpty()) {
737                if (parent == null) {
738                    return this; 
739                }
740                return parent;
741            }
742            popBlock();
743            return this;
744        }
745    
746        /**
747         * <a href="http://camel.apache.org/idempotent-consumer.html">Idempotent consumer EIP:</a>
748         * Creates an {@link org.apache.camel.processor.idempotent.IdempotentConsumer IdempotentConsumer}
749         * to avoid duplicate messages
750         *      
751         * @return the builder
752         */
753        public IdempotentConsumerDefinition idempotentConsumer() {
754            IdempotentConsumerDefinition answer = new IdempotentConsumerDefinition();
755            addOutput(answer);
756            return answer;
757        }
758    
759        /**
760         * <a href="http://camel.apache.org/idempotent-consumer.html">Idempotent consumer EIP:</a>
761         * Creates an {@link org.apache.camel.processor.idempotent.IdempotentConsumer IdempotentConsumer}
762         * to avoid duplicate messages
763         *
764         * @param messageIdExpression  expression to test of duplicate messages
765         * @param idempotentRepository  the repository to use for duplicate chedck
766         * @return the builder
767         */
768        public IdempotentConsumerDefinition idempotentConsumer(Expression messageIdExpression,
769                IdempotentRepository idempotentRepository) {
770            IdempotentConsumerDefinition answer = new IdempotentConsumerDefinition(messageIdExpression, idempotentRepository);
771            addOutput(answer);
772            return answer;
773        }
774    
775        /**
776         * <a href="http://camel.apache.org/idempotent-consumer.html">Idempotent consumer EIP:</a>
777         * Creates an {@link org.apache.camel.processor.idempotent.IdempotentConsumer IdempotentConsumer}
778         * to avoid duplicate messages
779         *
780         * @param idempotentRepository the repository to use for duplicate chedck
781         * @return the builder used to create the expression
782         */
783        public ExpressionClause<IdempotentConsumerDefinition> idempotentConsumer(IdempotentRepository idempotentRepository) {
784            IdempotentConsumerDefinition answer = new IdempotentConsumerDefinition();
785            answer.setMessageIdRepository(idempotentRepository);
786            addOutput(answer);
787            return ExpressionClause.createAndSetExpression(answer);
788        }
789    
790        /**
791         * <a href="http://camel.apache.org/message-filter.html">Message Filter EIP:</a>
792         * Creates a predicate expression which only if it is <tt>true</tt> then the
793         * exchange is forwarded to the destination
794         *
795         * @return the clause used to create the filter expression
796         */
797        public ExpressionClause<FilterDefinition> filter() {
798            FilterDefinition filter = new FilterDefinition();
799            addOutput(filter);
800            return ExpressionClause.createAndSetExpression(filter);
801        }
802    
803        /**
804         * <a href="http://camel.apache.org/message-filter.html">Message Filter EIP:</a>
805         * Creates a predicate which is applied and only if it is <tt>true</tt> then the
806         * exchange is forwarded to the destination
807         *
808         * @param predicate  predicate to use
809         * @return the builder 
810         */
811        public FilterDefinition filter(Predicate predicate) {
812            FilterDefinition filter = new FilterDefinition(predicate);
813            addOutput(filter);
814            return filter;
815        }
816    
817        /**
818         * <a href="http://camel.apache.org/message-filter.html">Message Filter EIP:</a>
819         * Creates a predicate expression which only if it is <tt>true</tt> then the
820         * exchange is forwarded to the destination
821         *
822         * @param expression  the predicate expression to use
823         * @return the builder
824         */
825        public FilterDefinition filter(ExpressionDefinition expression) {
826            FilterDefinition filter = getNodeFactory().createFilter();
827            filter.setExpression(expression);
828            addOutput(filter);
829            return filter;
830        }
831    
832        /**
833         * <a href="http://camel.apache.org/message-filter.html">Message Filter EIP:</a>
834         * Creates a predicate language expression which only if it is <tt>true</tt> then the
835         * exchange is forwarded to the destination
836         *
837         * @param language     language for expression
838         * @param expression   the expression
839         * @return the builder
840         */
841        public FilterDefinition filter(String language, String expression) {
842            return filter(new LanguageExpression(language, expression));
843        }
844    
845        /**
846         * <a href="http://camel.apache.org/load-balancer.html">Load Balancer EIP:</a>
847         * Creates a loadbalance
848         *
849         * @return  the builder
850         */
851        public LoadBalanceDefinition loadBalance() {
852            LoadBalanceDefinition answer = new LoadBalanceDefinition();
853            addOutput(answer);
854            return answer;
855        }
856    
857        /**
858         * <a href="http://camel.apache.org/load-balancer.html">Load Balancer EIP:</a>
859         * Creates a loadbalance
860         *
861         * @param loadBalancer a custom load balancer to use
862         * @return  the builder
863         */
864        public LoadBalanceDefinition loadBalance(LoadBalancer loadBalancer) {
865            LoadBalanceDefinition answer = new LoadBalanceDefinition();
866            addOutput(answer);
867            return answer.loadBalance(loadBalancer);
868        }
869    
870        /**
871         * <a href="http://camel.apache.org/content-based-router.html">Content Based Router EIP:</a>
872         * Creates a choice of one or more predicates with an otherwise clause
873         *
874         * @return the builder for a choice expression
875         */
876        public ChoiceDefinition choice() {
877            ChoiceDefinition answer = new ChoiceDefinition();
878            addOutput(answer);
879            return answer;
880        }
881    
882        /**
883         * Creates a try/catch block
884         *
885         * @return the builder for a tryBlock expression
886         */
887        public TryDefinition doTry() {
888            TryDefinition answer = new TryDefinition();
889            addOutput(answer);
890            return answer;
891        }
892    
893        /**
894         * <a href="http://camel.apache.org/recipient-list.html">Recipient List EIP:</a>
895         * Creates a dynamic recipient list allowing you to route messages to a number of dynamically specified recipients
896         *
897         * @param recipients expression to decide the destinations
898         * @return the builder
899         */
900        @SuppressWarnings("unchecked")
901        public Type recipientList(Expression recipients) {
902            RecipientListDefinition answer = new RecipientListDefinition(recipients);
903            addOutput(answer);
904            return (Type) this;
905        }
906    
907        /**
908         * <a href="http://camel.apache.org/recipient-list.html">Recipient List EIP:</a>
909         * Creates a dynamic recipient list allowing you to route messages to a number of dynamically specified recipients
910         *
911         * @return the expression clause to configure the expression to decide the destinations
912         */
913        public ExpressionClause<ProcessorDefinition<Type>> recipientList() {
914            RecipientListDefinition answer = new RecipientListDefinition();
915            addOutput(answer);
916            ExpressionClause<ProcessorDefinition<Type>> clause = new ExpressionClause<ProcessorDefinition<Type>>(this);
917            answer.setExpression(clause);
918            return clause;
919        }
920    
921        /**
922         * <a href="http://camel.apache.org/routing-slip.html">Routing Slip EIP:</a>
923         * Creates a routing slip allowing you to route a message consecutively through a series of processing
924         * steps where the sequence of steps is not known at design time and can vary for each message.
925         *
926         * @param header  is the header that the {@link org.apache.camel.processor.RoutingSlip RoutingSlip}
927         *                class will look in for the list of URIs to route the message to.
928         * @param uriDelimiter  is the delimiter that will be used to split up
929         *                      the list of URIs in the routing slip.
930         * @return the buiider
931         */
932        @SuppressWarnings("unchecked")
933        public Type routingSlip(String header, String uriDelimiter) {
934            RoutingSlipDefinition answer = new RoutingSlipDefinition(header, uriDelimiter);
935            addOutput(answer);
936            return (Type) this;
937        }
938    
939        /**
940         * <a href="http://camel.apache.org/routing-slip.html">Routing Slip EIP:</a>
941         * Creates a routing slip allowing you to route a message consecutively through a series of processing
942         * steps where the sequence of steps is not known at design time and can vary for each message.
943         * <p>
944         * The list of URIs will be split based on the default delimiter {@link RoutingSlipDefinition#DEFAULT_DELIMITER}
945         *
946         * @param header  is the header that the {@link org.apache.camel.processor.RoutingSlip RoutingSlip}
947         *                class will look in for the list of URIs to route the message to.
948         * @return the builder
949         */
950        @SuppressWarnings("unchecked")
951        public Type routingSlip(String header) {
952            RoutingSlipDefinition answer = new RoutingSlipDefinition(header);
953            addOutput(answer);
954            return (Type) this;
955        }
956    
957        /**
958         * <a href="http://camel.apache.org/splitter.html">Splitter EIP:</a>
959         * Creates a splitter allowing you split a message into a number of pieces and process them individually.
960         * <p>
961         * This splitter responds with the latest message returned from destination
962         * endpoint.
963         *
964         * @return the expression clause builder for the expression on which to split
965         */
966        public ExpressionClause<SplitDefinition> split() {
967            SplitDefinition answer = new SplitDefinition();
968            addOutput(answer);
969            return ExpressionClause.createAndSetExpression(answer);
970        }
971    
972        /**
973         * <a href="http://camel.apache.org/splitter.html">Splitter EIP:</a>
974         * Creates a splitter allowing you split a message into a number of pieces and process them individually.
975         * <p>
976         * This splitter responds with the latest message returned from destination
977         * endpoint.
978         *
979         * @param expression  the expression on which to split the message
980         * @return the builder
981         */
982        public SplitDefinition split(Expression expression) {
983            SplitDefinition answer = new SplitDefinition(expression);
984            addOutput(answer);
985            return answer;
986        }
987    
988        /**
989         * <a href="http://camel.apache.org/splitter.html">Splitter EIP:</a>
990         * Creates a splitter allowing you split a message into a number of pieces and process them individually.
991         * <p>
992         * The splitter responds with the answer produced by the given {@link AggregationStrategy}.
993         *
994         * @param expression  the expression on which to split
995         * @param aggregationStrategy  the strategy used to aggregate responses for every part
996         * @return the builder
997         */
998        public SplitDefinition split(Expression expression, AggregationStrategy aggregationStrategy) {
999            SplitDefinition answer = new SplitDefinition(expression);
1000            addOutput(answer);
1001            answer.setAggregationStrategy(aggregationStrategy);
1002            return answer;
1003        }
1004    
1005        /**
1006         * <a href="http://camel.apache.org/resequencer.html">Resequencer EIP:</a>
1007         * Creates a resequencer allowing you to reorganize messages based on some comparator.
1008         *
1009         * @return the expression clause for the expressions on which to compare messages in order
1010         */
1011        public ExpressionClause<ResequenceDefinition> resequence() {
1012            ResequenceDefinition answer = new ResequenceDefinition();
1013            addOutput(answer);
1014            ExpressionClause<ResequenceDefinition> clause = new ExpressionClause<ResequenceDefinition>(answer);
1015            answer.expression(clause);
1016            return clause;
1017        }
1018    
1019        /**
1020         * <a href="http://camel.apache.org/resequencer.html">Resequencer EIP:</a>
1021         * Creates a resequencer allowing you to reorganize messages based on some comparator.
1022         *
1023         * @param expression the expression on which to compare messages in order
1024         * @return the builder
1025         */
1026        public ResequenceDefinition resequence(Expression expression) {
1027            return resequence(Collections.<Expression>singletonList(expression));
1028        }
1029    
1030        /**
1031         * <a href="http://camel.apache.org/resequencer.html">Resequencer EIP:</a>
1032         * Creates a resequencer allowing you to reorganize messages based on some comparator.
1033         *
1034         * @param expressions the list of expressions on which to compare messages in order
1035         * @return the builder
1036         */
1037        public ResequenceDefinition resequence(List<Expression> expressions) {
1038            ResequenceDefinition answer = new ResequenceDefinition(expressions);
1039            addOutput(answer);
1040            return answer;
1041        }
1042    
1043        /**
1044         * <a href="http://camel.apache.org/resequencer.html">Resequencer EIP:</a>
1045         * Creates a splitter allowing you to reorganise messages based on some comparator.
1046         *
1047         * @param expressions the list of expressions on which to compare messages in order
1048         * @return the builder
1049         */
1050        public ResequenceDefinition resequencer(Expression... expressions) {
1051            List<Expression> list = new ArrayList<Expression>();
1052            list.addAll(Arrays.asList(expressions));
1053            return resequence(list);
1054        }
1055    
1056        /**
1057         * <a href="http://camel.apache.org/aggregator.html">Aggregator EIP:</a>
1058         * Creates an aggregator allowing you to combine a number of messages together into a single message.
1059         *
1060         * @return the expression clause to be used as builder to configure the correlation expression
1061         */
1062        public ExpressionClause<AggregateDefinition> aggregate() {
1063            AggregateDefinition answer = new AggregateDefinition();
1064            addOutput(answer);
1065            return answer.createAndSetExpression();
1066        }
1067    
1068        /**
1069         * <a href="http://camel.apache.org/aggregator.html">Aggregator EIP:</a>
1070         * Creates an aggregator allowing you to combine a number of messages together into a single message.
1071         *
1072         * @param aggregationStrategy the strategy used for the aggregation
1073         * @return the expression clause to be used as builder to configure the correlation expression
1074         */
1075        public ExpressionClause<AggregateDefinition> aggregate(AggregationStrategy aggregationStrategy) {
1076            AggregateDefinition answer = new AggregateDefinition();
1077            answer.setAggregationStrategy(aggregationStrategy);
1078            addOutput(answer);
1079            return answer.createAndSetExpression();
1080        }
1081    
1082        /**
1083         * <a href="http://camel.apache.org/aggregator.html">Aggregator EIP:</a>
1084         * Creates an aggregator allowing you to combine a number of messages together into a single message.
1085         *
1086         * @param aggregationCollection the collection used to perform the aggregation
1087         * @return the builder
1088         */
1089        public AggregateDefinition aggregate(AggregationCollection aggregationCollection) {
1090            AggregateDefinition answer = new AggregateDefinition();
1091            answer.setAggregationCollection(aggregationCollection);
1092            addOutput(answer);
1093            return answer;
1094        }
1095    
1096        /**
1097         * <a href="http://camel.apache.org/aggregator.html">Aggregator EIP:</a>
1098         * Creates an aggregator allowing you to combine a number of messages together into a single message.
1099         *
1100         * @param correlationExpression the expression used to calculate the
1101         *                              correlation key. For a JMS message this could be the
1102         *                              expression <code>header("JMSDestination")</code> or
1103         *                              <code>header("JMSCorrelationID")</code>
1104         * @return the builder
1105         */
1106        public AggregateDefinition aggregate(Expression correlationExpression) {
1107            AggregateDefinition answer = new AggregateDefinition(correlationExpression);
1108            addOutput(answer);
1109            return answer;
1110        }
1111    
1112        /**
1113         * <a href="http://camel.apache.org/aggregator.html">Aggregator EIP:</a>
1114         * Creates an aggregator allowing you to combine a number of messages together into a single message.
1115         *
1116         * @param correlationExpression the expression used to calculate the
1117         *                              correlation key. For a JMS message this could be the
1118         *                              expression <code>header("JMSDestination")</code> or
1119         *                              <code>header("JMSCorrelationID")</code>
1120         * @param aggregationStrategy the strategy used for the aggregation
1121         * @return the builder
1122         */
1123        public AggregateDefinition aggregate(Expression correlationExpression, AggregationStrategy aggregationStrategy) {
1124            AggregateDefinition answer = new AggregateDefinition(correlationExpression, aggregationStrategy);
1125            addOutput(answer);
1126            return answer;
1127        }
1128    
1129        /**
1130         * <a href="http://camel.apache.org/delayer.html">Delayer EIP:</a>
1131         * Creates a delayer allowing you to delay the delivery of messages to some destination.
1132         *
1133         * @param delay  an expression to calculate the delay time in millis
1134         * @return the builder
1135         */
1136        public DelayDefinition delay(Expression delay) {
1137            DelayDefinition answer = new DelayDefinition(delay);
1138            addOutput(answer);
1139            return answer;
1140        }
1141    
1142        /**
1143         * <a href="http://camel.apache.org/delayer.html">Delayer EIP:</a>
1144         * Creates a delayer allowing you to delay the delivery of messages to some destination.
1145         *
1146         * @return the expression clause to create the expression
1147         */
1148        public ExpressionClause<DelayDefinition> delay() {
1149            DelayDefinition answer = new DelayDefinition();
1150            addOutput(answer);
1151            return ExpressionClause.createAndSetExpression(answer);
1152        }
1153    
1154        /**
1155         * <a href="http://camel.apache.org/delayer.html">Delayer EIP:</a>
1156         * Creates a delayer allowing you to delay the delivery of messages to some destination.
1157         *
1158         * @param delay  the delay in millis
1159         * @return the builder
1160         */
1161        public DelayDefinition delay(long delay) {
1162            return delay(ExpressionBuilder.constantExpression(delay));
1163        }
1164    
1165        /**
1166         * <a href="http://camel.apache.org/throttler.html">Throttler EIP:</a>
1167         * Creates a throttler allowing you to ensure that a specific endpoint does not get overloaded,
1168         * or that we don't exceed an agreed SLA with some external service.
1169         * <p/>
1170         * Will default use a time period of 1 second, so setting the maximumRequestCount to eg 10
1171         * will default ensure at most 10 messages per second. 
1172         *
1173         * @param maximumRequestCount  the maximum messages 
1174         * @return the builder
1175         */
1176        public ThrottleDefinition throttle(long maximumRequestCount) {
1177            ThrottleDefinition answer = new ThrottleDefinition(maximumRequestCount);
1178            addOutput(answer);
1179            return answer;
1180        }
1181    
1182        /**
1183         * <a href="http://camel.apache.org/loop.html">Loop EIP:</a>
1184         * Creates a loop allowing to process the a message a number of times and possibly process them
1185         * in a different way. Useful mostly for testing.
1186         *
1187         * @return the clause used to create the loop expression
1188         */
1189        public ExpressionClause<LoopDefinition> loop() {
1190            LoopDefinition loop = new LoopDefinition();
1191            addOutput(loop);
1192            return ExpressionClause.createAndSetExpression(loop);
1193        }
1194    
1195        /**
1196         * <a href="http://camel.apache.org/loop.html">Loop EIP:</a>
1197         * Creates a loop allowing to process the a message a number of times and possibly process them
1198         * in a different way. Useful mostly for testing.
1199         *
1200         * @param expression the loop expression
1201         * @return the builder
1202         */
1203        public LoopDefinition loop(Expression expression) {
1204            LoopDefinition loop = getNodeFactory().createLoop();
1205            loop.setExpression(expression);
1206            addOutput(loop);
1207            return loop;
1208        }
1209    
1210        /**
1211         * <a href="http://camel.apache.org/loop.html">Loop EIP:</a>
1212         * Creates a loop allowing to process the a message a number of times and possibly process them
1213         * in a different way. Useful mostly for testing.
1214         *
1215         * @param count  the number of times
1216         * @return the builder
1217         */
1218        public LoopDefinition loop(int count) {
1219            LoopDefinition loop = getNodeFactory().createLoop();
1220            loop.setExpression(new ConstantExpression(Integer.toString(count)));
1221            addOutput(loop);
1222            return loop;
1223        }
1224    
1225        /**
1226         * Sets the exception on the {@link org.apache.camel.Exchange}
1227         *
1228         * @param exception the exception to throw
1229         * @return the builder
1230         */
1231        @SuppressWarnings("unchecked")
1232        public Type throwException(Exception exception) {
1233            ThrowExceptionDefinition answer = new ThrowExceptionDefinition();
1234            answer.setException(exception);
1235            addOutput(answer);
1236            return (Type) this;
1237        }
1238    
1239        /**
1240         * Marks the exchange for rollback only.
1241         * <p/>
1242         * This is done by setting a {@link org.apache.camel.RollbackExchangeException} on the Exchange
1243         * and mark it for rollback.
1244         *
1245         * @return the builder
1246         */
1247        @SuppressWarnings("unchecked")
1248        public Type rollback() {
1249            return rollback(null);
1250        }
1251    
1252        /**
1253         * Marks the exchange for rollback only.
1254         * <p/>
1255         * This is done by setting a {@link org.apache.camel.RollbackExchangeException} on the Exchange
1256         * and mark it for rollback.
1257         *
1258         * @param message an optional message used for logging purpose why the rollback was triggered
1259         * @return the builder
1260         */
1261        @SuppressWarnings("unchecked")
1262        public Type rollback(String message) {
1263            RollbackDefinition answer = new RollbackDefinition(message);
1264            addOutput(answer);
1265            return (Type) this;
1266        }
1267    
1268        /**
1269         * <a href="http://camel.apache.org/wiretap.html">WireTap EIP:</a>
1270         * Sends messages to all its child outputs; so that each processor and
1271         * destination gets a copy of the original message to avoid the processors
1272         * interfering with each other using {@link ExchangePattern#InOnly}.
1273         *
1274         * @return the builder
1275         */
1276        @SuppressWarnings("unchecked")
1277        public Type wireTap(String uri) {
1278            WireTapDefinition answer = new WireTapDefinition();
1279            answer.setUri(uri);
1280            addOutput(answer);
1281            return (Type) this;
1282        }
1283    
1284        /**
1285         * <a href="http://camel.apache.org/wiretap.html">WireTap EIP:</a>
1286         * Sends a new {@link org.apache.camel.Exchange} to the destination
1287         * using {@link ExchangePattern#InOnly}.
1288         *
1289         * @param uri  the destination
1290         * @param body expression that creates the body to send
1291         * @return the builder
1292         */
1293        @SuppressWarnings("unchecked")
1294        public Type wireTap(String uri, Expression body) {
1295            WireTapDefinition answer = new WireTapDefinition();
1296            answer.setUri(uri);
1297            answer.setNewExchangeExpression(body);
1298            addOutput(answer);
1299            return (Type) this;
1300        }
1301    
1302        /**
1303         * <a href="http://camel.apache.org/wiretap.html">WireTap EIP:</a>
1304         * Sends a new {@link org.apache.camel.Exchange} to the destination
1305         * using {@link ExchangePattern#InOnly}.
1306         *
1307         * @param uri  the destination
1308         * @param processor  processor preparing the new exchange to send
1309         * @return the builder
1310         */
1311        @SuppressWarnings("unchecked")
1312        public Type wireTap(String uri, Processor processor) {
1313            WireTapDefinition answer = new WireTapDefinition();
1314            answer.setUri(uri);
1315            answer.setNewExchangeProcessor(processor);
1316            addOutput(answer);
1317            return (Type) this;
1318        }
1319    
1320        /**
1321         * Pushes the given block on the stack as current block
1322         * @param block  the block
1323         */
1324        void pushBlock(Block block) {
1325            blocks.add(block);
1326        }
1327    
1328        /**
1329         * Pops the block off the stack as current block
1330         * @return the block
1331         */
1332        Block popBlock() {
1333            return blocks.isEmpty() ? null : blocks.removeLast();
1334        }
1335    
1336        /**
1337         * Stops continue routing the current {@link org.apache.camel.Exchange} and marks it as completed.
1338         *
1339         * @return the builder
1340         */
1341        @SuppressWarnings("unchecked")
1342        public Type stop() {
1343            StopDefinition stop = new StopDefinition();
1344            addOutput(stop);
1345            return (Type) this;
1346        }
1347    
1348        /**
1349         * <a href="http://camel.apache.org/exception-clause.html">Exception clause</a>
1350         * for cathing certain exceptions and handling them.
1351         *
1352         * @param exceptionType  the exception to catch
1353         * @return the exception builder to configure
1354         */
1355        public OnExceptionDefinition onException(Class exceptionType) {
1356            OnExceptionDefinition answer = new OnExceptionDefinition(exceptionType);
1357            addOutput(answer);
1358            return answer;
1359        }
1360    
1361        /**
1362         * Apply a {@link Policy}.
1363         * <p/>
1364         * Policy can be used for transactional policies.
1365         *
1366         * @param policy  the policy to apply
1367         * @return the policy builder to configure
1368         */
1369        public PolicyDefinition policy(Policy policy) {
1370            PolicyDefinition answer = new PolicyDefinition(policy);
1371            addOutput(answer);
1372            return answer;
1373        }
1374    
1375        /**
1376         * Apply a {@link Policy}.
1377         * <p/>
1378         * Policy can be used for transactional policies.
1379         *
1380         * @param ref  reference to lookup a policy in the registry
1381         * @return the policy builder to configure
1382         */
1383        public PolicyDefinition policy(String ref) {
1384            PolicyDefinition answer = new PolicyDefinition();
1385            answer.setRef(ref);
1386            addOutput(answer);
1387            return answer;
1388        }
1389    
1390        /**
1391         * Marks this route as transacted and uses the default transacted policy found in the registry.
1392         *
1393         * @return the policy builder to configure
1394         */
1395        public PolicyDefinition transacted() {
1396            PolicyDefinition answer = new PolicyDefinition();
1397            answer.setType(TransactedPolicy.class);
1398            addOutput(answer);
1399            return answer;
1400        }
1401    
1402        /**
1403         * Marks this route as transacted.
1404         *
1405         * @param ref  reference to lookup a transacted policy in the registry
1406         * @return the policy builder to configure
1407         */
1408        public PolicyDefinition transacted(String ref) {
1409            PolicyDefinition answer = new PolicyDefinition();
1410            answer.setType(TransactedPolicy.class);
1411            answer.setRef(ref);
1412            addOutput(answer);
1413            return answer;
1414        }
1415    
1416        /**
1417         * Installs the given <a href="http://camel.apache.org/error-handler.html">error handler</a> builder.
1418         *
1419         * @param errorHandlerBuilder the error handler to be used by default for all child routes
1420         * @return the current builder with the error handler configured
1421         */
1422        @SuppressWarnings("unchecked")
1423        public Type errorHandler(ErrorHandlerBuilder errorHandlerBuilder) {
1424            setErrorHandlerBuilder(errorHandlerBuilder);
1425            return (Type) this;
1426        }
1427    
1428        // Transformers
1429        // -------------------------------------------------------------------------
1430    
1431        /**
1432         * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
1433         * Adds the custom processor to this destination which could be a final
1434         * destination, or could be a transformation in a pipeline
1435         *
1436         * @param processor  the custom {@link Processor}
1437         * @return the builder
1438         */
1439        @SuppressWarnings("unchecked")
1440        public Type process(Processor processor) {
1441            ProcessDefinition answer = new ProcessDefinition(processor);
1442            addOutput(answer);
1443            return (Type) this;
1444        }
1445    
1446        /**
1447         * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
1448         * Adds the custom processor reference to this destination which could be a final
1449         * destination, or could be a transformation in a pipeline
1450         *
1451         * @param ref   reference to a {@link Processor} to lookup in the registry
1452         * @return the builder
1453         */
1454        @SuppressWarnings("unchecked")
1455        public Type processRef(String ref) {
1456            ProcessDefinition answer = new ProcessDefinition();
1457            answer.setRef(ref);
1458            addOutput(answer);
1459            return (Type) this;
1460        }
1461    
1462        /**
1463         * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
1464         * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
1465         *
1466         * @param bean  the bean to invoke
1467         * @return the builder
1468         */
1469        @SuppressWarnings("unchecked")
1470        public Type bean(Object bean) {
1471            BeanDefinition answer = new BeanDefinition();
1472            answer.setBean(bean);
1473            addOutput(answer);
1474            return (Type) this;
1475        }
1476    
1477        /**
1478         * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
1479         * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
1480         *
1481         * @param bean  the bean to invoke
1482         * @param method  the method name to invoke on the bean (can be used to avoid ambiguty)
1483         * @return the builder
1484         */
1485        @SuppressWarnings("unchecked")
1486        public Type bean(Object bean, String method) {
1487            BeanDefinition answer = new BeanDefinition();
1488            answer.setBean(bean);
1489            answer.setMethod(method);
1490            addOutput(answer);
1491            return (Type) this;
1492        }
1493    
1494        /**
1495         * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
1496         * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
1497         *
1498         * @param  beanType  the bean class, Camel will instantiate an object at runtime
1499         * @return the builder
1500         */
1501        @SuppressWarnings("unchecked")
1502        public Type bean(Class beanType) {
1503            BeanDefinition answer = new BeanDefinition();
1504            answer.setBeanType(beanType);
1505            addOutput(answer);
1506            return (Type) this;
1507        }
1508    
1509        /**
1510         * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
1511         * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
1512         *
1513         * @param  beanType  the bean class, Camel will instantiate an object at runtime
1514         * @param method  the method name to invoke on the bean (can be used to avoid ambiguty)
1515         * @return the builder
1516         */
1517        @SuppressWarnings("unchecked")
1518        public Type bean(Class beanType, String method) {
1519            BeanDefinition answer = new BeanDefinition();
1520            answer.setBeanType(beanType);
1521            answer.setMethod(method);
1522            addOutput(answer);
1523            return (Type) this;
1524        }
1525    
1526        /**
1527         * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
1528         * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
1529         *
1530         * @param ref  reference to a bean to lookup in the registry
1531         * @return the builder
1532         */
1533        @SuppressWarnings("unchecked")
1534        public Type beanRef(String ref) {
1535            BeanDefinition answer = new BeanDefinition(ref);
1536            addOutput(answer);
1537            return (Type) this;
1538        }
1539    
1540        /**
1541         * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
1542         * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
1543         *
1544         * @param ref  reference to a bean to lookup in the registry
1545         * @param method  the method name to invoke on the bean (can be used to avoid ambiguty)
1546         * @return the builder
1547         */
1548        @SuppressWarnings("unchecked")
1549        public Type beanRef(String ref, String method) {
1550            BeanDefinition answer = new BeanDefinition(ref, method);
1551            addOutput(answer);
1552            return (Type) this;
1553        }
1554    
1555        /**
1556         * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
1557         * Adds a processor which sets the body on the IN message
1558         *
1559         * @return a expression builder clause to set the body
1560         */
1561        public ExpressionClause<ProcessorDefinition<Type>> setBody() {
1562            ExpressionClause<ProcessorDefinition<Type>> clause = new ExpressionClause<ProcessorDefinition<Type>>(this);
1563            SetBodyDefinition answer = new SetBodyDefinition(clause);
1564            addOutput(answer);
1565            return clause;
1566        }
1567    
1568        /**
1569         * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
1570         * Adds a processor which sets the body on the IN message
1571         *
1572         * @param expression   the expression used to set the body
1573         * @return the builder
1574         */
1575        @SuppressWarnings("unchecked")
1576        public Type setBody(Expression expression) {
1577            SetBodyDefinition answer = new SetBodyDefinition(expression);
1578            addOutput(answer);
1579            return (Type) this;
1580        }
1581    
1582        /**
1583         * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
1584         * Adds a processor which sets the body on the OUT message
1585         *
1586         * @param expression   the expression used to set the body
1587         * @return the builder
1588         */
1589        @SuppressWarnings("unchecked")
1590        public Type transform(Expression expression) {
1591            TransformDefinition answer = new TransformDefinition(expression);
1592            addOutput(answer);
1593            return (Type) this;
1594        }
1595    
1596        /**
1597         * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
1598         * Adds a processor which sets the body on the OUT message
1599         *
1600         * @return a expression builder clause to set the body
1601         */
1602        public ExpressionClause<ProcessorDefinition<Type>> transform() {
1603            ExpressionClause<ProcessorDefinition<Type>> clause = new ExpressionClause<ProcessorDefinition<Type>>((Type) this);
1604            TransformDefinition answer = new TransformDefinition(clause);
1605            addOutput(answer);
1606            return clause;
1607        }
1608    
1609        /**
1610         * Adds a processor which sets the body on the FAULT message
1611         *
1612         * @param expression   the expression used to set the body
1613         * @return the builder
1614         */
1615        public Type setFaultBody(Expression expression) {
1616            return process(ProcessorBuilder.setFaultBody(expression));
1617        }
1618    
1619        /**
1620         * Adds a processor which sets the header on the IN message
1621         *
1622         * @param name  the header name
1623         * @return a expression builder clause to set the header
1624         */
1625        public ExpressionClause<ProcessorDefinition<Type>> setHeader(String name) {
1626            ExpressionClause<ProcessorDefinition<Type>> clause = new ExpressionClause<ProcessorDefinition<Type>>(this);
1627            SetHeaderDefinition answer = new SetHeaderDefinition(name, clause);
1628            addOutput(answer);
1629            return clause;
1630        }
1631    
1632        /**
1633         * Adds a processor which sets the header on the IN message
1634         *
1635         * @param name  the header name
1636         * @param expression  the expression used to set the header
1637         * @return the builder
1638         */
1639        @SuppressWarnings("unchecked")
1640        public Type setHeader(String name, Expression expression) {
1641            SetHeaderDefinition answer = new SetHeaderDefinition(name, expression);
1642            addOutput(answer);
1643            return (Type) this;
1644        }
1645    
1646        /**
1647         * Adds a processor which sets the header on the OUT message
1648         *
1649         * @param name  the header name
1650         * @return a expression builder clause to set the header
1651         */
1652        public ExpressionClause<ProcessorDefinition<Type>> setOutHeader(String name) {
1653            ExpressionClause<ProcessorDefinition<Type>> clause = new ExpressionClause<ProcessorDefinition<Type>>(this);
1654            SetOutHeaderDefinition answer = new SetOutHeaderDefinition(name, clause);
1655            addOutput(answer);
1656            return clause;
1657        }
1658    
1659        /**
1660         * Adds a processor which sets the header on the OUT message
1661         *
1662         * @param name  the header name
1663         * @param expression  the expression used to set the header
1664         * @return the builder
1665         */
1666        @SuppressWarnings("unchecked")
1667        public Type setOutHeader(String name, Expression expression) {
1668            SetOutHeaderDefinition answer = new SetOutHeaderDefinition(name, expression);
1669            addOutput(answer);
1670            return (Type) this;
1671        }
1672    
1673        /**
1674         * Adds a processor which sets the header on the FAULT message
1675         *
1676         * @param name  the header name
1677         * @param expression  the expression used to set the header
1678         * @return the builder
1679         */
1680        public Type setFaultHeader(String name, Expression expression) {
1681            return process(ProcessorBuilder.setFaultHeader(name, expression));
1682        }
1683    
1684        /**
1685         * Adds a processor which sets the exchange property
1686         *
1687         * @param name  the property name
1688         * @param expression  the expression used to set the property
1689         * @return the builder
1690         */
1691        @SuppressWarnings("unchecked")
1692        public Type setProperty(String name, Expression expression) {
1693            SetPropertyDefinition answer = new SetPropertyDefinition(name, expression);
1694            addOutput(answer);
1695            return (Type) this;
1696        }
1697    
1698    
1699        /**
1700         * Adds a processor which sets the exchange property
1701         *
1702         * @param name  the property name
1703         * @return a expression builder clause to set the property
1704         */
1705        public ExpressionClause<ProcessorDefinition<Type>> setProperty(String name) {
1706            ExpressionClause<ProcessorDefinition<Type>> clause = new ExpressionClause<ProcessorDefinition<Type>>(this);
1707            SetPropertyDefinition answer = new SetPropertyDefinition(name, clause);
1708            addOutput(answer);
1709            return clause;
1710        }
1711    
1712        /**
1713         * Adds a processor which removes the header on the IN message
1714         *
1715         * @param name  the header name
1716         * @return the builder
1717         */
1718        @SuppressWarnings("unchecked")
1719        public Type removeHeader(String name) {
1720            RemoveHeaderDefinition answer = new RemoveHeaderDefinition(name);
1721            addOutput(answer);
1722            return (Type) this;
1723        }
1724    
1725        /**
1726         * Adds a processor which removes the header on the FAULT message
1727         *
1728         * @param name  the header name
1729         * @return the builder
1730         */
1731        public Type removeFaultHeader(String name) {
1732            return process(ProcessorBuilder.removeFaultHeader(name));
1733        }
1734    
1735        /**
1736         * Adds a processor which removes the exchange property
1737         *
1738         * @param name  the property name
1739         * @return the builder
1740         */
1741        @SuppressWarnings("unchecked")
1742        public Type removeProperty(String name) {
1743            RemovePropertyDefinition answer = new RemovePropertyDefinition(name);
1744            addOutput(answer);
1745            return (Type) this;
1746        }
1747    
1748        /**
1749         * Converts the IN message body to the specified type
1750         *
1751         * @param type the type to convert to
1752         * @return the builder
1753         */
1754        @SuppressWarnings("unchecked")
1755        public Type convertBodyTo(Class type) {
1756            addOutput(new ConvertBodyDefinition(type));
1757            return (Type) this;
1758        }
1759        
1760        /**
1761         * Converts the IN message body to the specified type
1762         *
1763         * @param type the type to convert to
1764         * @param charset the charset to use by type converters (not all converters support specifc charset)
1765         * @return the builder
1766         */
1767        @SuppressWarnings("unchecked")
1768        public Type convertBodyTo(Class type, String charset) {
1769            addOutput(new ConvertBodyDefinition(type, charset));
1770            return (Type) this;
1771        }
1772    
1773        /**
1774         * Sorts the IN message body using the given comparator.
1775         * The IN body mut be convertable to {@link List}.
1776         *
1777         * @param comparator  the comparator to use for sorting
1778         * @return the builder
1779         */
1780        @SuppressWarnings("unchecked")
1781        public Type sortBody(Comparator comparator) {
1782            addOutput(new SortDefinition(body(), comparator));
1783            return (Type) this;
1784        }
1785    
1786        /**
1787         * Sorts the IN message body using a default sorting based on toString representation.
1788         * The IN body mut be convertable to {@link List}.
1789         *
1790         * @return the builder
1791         */
1792        public Type sortBody() {
1793            return sortBody(null);
1794        }
1795    
1796        /**
1797         * Sorts the expression using the given comparator
1798         *
1799         * @param expression  the expression, must be convertable to {@link List}
1800         * @param comparator  the comparator to use for sorting
1801         * @return the builder
1802         */
1803        @SuppressWarnings("unchecked")
1804        public Type sort(Expression expression, Comparator comparator) {
1805            addOutput(new SortDefinition(expression, comparator));
1806            return (Type) this;
1807        }
1808    
1809        /**
1810         * Sorts the expression using a default sorting based on toString representation. 
1811         *
1812         * @param expression  the expression, must be convertable to {@link List}
1813         * @return the builder
1814         */
1815        public Type sort(Expression expression) {
1816            return sort(expression, null);
1817        }
1818    
1819        /**
1820         * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
1821         * enriches an exchange with additional data obtained from a <code>resourceUri</code>.
1822         * 
1823         * @param resourceUri           URI of resource endpoint for obtaining additional data.
1824         * @param aggregationStrategy   aggregation strategy to aggregate input data and additional data.
1825         * @return the builder
1826         * @see org.apache.camel.processor.Enricher
1827         */
1828        @SuppressWarnings("unchecked")
1829        public Type enrich(String resourceUri, AggregationStrategy aggregationStrategy) {
1830            addOutput(new EnrichDefinition(aggregationStrategy, resourceUri));
1831            return (Type) this;
1832        }
1833    
1834        /**
1835         * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
1836         * enriches an exchange with additional data obtained from a <code>resourceUri</code>.
1837         * <p/>
1838         * The difference between this and {@link #pollEnrich(String)} is that this uses a producer
1839         * to obatin the additional data, where as pollEnrich uses a polling consumer.
1840         *
1841         * @param resourceUri           URI of resource endpoint for obtaining additional data.
1842         * @return the builder
1843         * @see org.apache.camel.processor.Enricher
1844         */
1845        @SuppressWarnings("unchecked")
1846        public Type enrich(String resourceUri) {
1847            addOutput(new EnrichDefinition(resourceUri));
1848            return (Type) this;
1849        }
1850    
1851        /**
1852         * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
1853         * enriches an exchange with additional data obtained from a <code>resourceUri</code>
1854         * using a {@link org.apache.camel.PollingConsumer} to poll the endpoint.
1855         * <p/>
1856         * The difference between this and {@link #enrich(String)} is that this uses a consumer
1857         * to obatin the additional data, where as enrich uses a producer.
1858         * <p/>
1859         * This method will block until data is avialable, use the method with timeout if you do not
1860         * want to risk waiting a long time before data is available from the resourceUri.
1861         *
1862         * @param resourceUri           URI of resource endpoint for obtaining additional data.
1863         * @return the builder
1864         * @see org.apache.camel.processor.PollEnricher
1865         */
1866        @SuppressWarnings("unchecked")
1867        public Type pollEnrich(String resourceUri) {
1868            addOutput(new PollEnrichDefinition(null, resourceUri, 0));
1869            return (Type) this;
1870        }
1871    
1872        /**
1873         * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
1874         * enriches an exchange with additional data obtained from a <code>resourceUri</code>
1875         * using a {@link org.apache.camel.PollingConsumer} to poll the endpoint.
1876         * <p/>
1877         * The difference between this and {@link #enrich(String)} is that this uses a consumer
1878         * to obatin the additional data, where as enrich uses a producer.
1879         * <p/>
1880         * This method will block until data is avialable, use the method with timeout if you do not
1881         * want to risk waiting a long time before data is available from the resourceUri.
1882         *
1883         * @param resourceUri           URI of resource endpoint for obtaining additional data.
1884         * @param aggregationStrategy   aggregation strategy to aggregate input data and additional data.
1885         * @return the builder
1886         * @see org.apache.camel.processor.PollEnricher
1887         */
1888        @SuppressWarnings("unchecked")
1889        public Type pollEnrich(String resourceUri, AggregationStrategy aggregationStrategy) {
1890            addOutput(new PollEnrichDefinition(aggregationStrategy, resourceUri, 0));
1891            return (Type) this;
1892        }
1893    
1894        /**
1895         * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
1896         * enriches an exchange with additional data obtained from a <code>resourceUri</code>
1897         * using a {@link org.apache.camel.PollingConsumer} to poll the endpoint.
1898         * <p/>
1899         * The difference between this and {@link #enrich(String)} is that this uses a consumer
1900         * to obatin the additional data, where as enrich uses a producer.
1901         * <p/>
1902         * The timeout controls which operation to use on {@link org.apache.camel.PollingConsumer}.
1903         * If timeout is negative, we use <tt>receive</tt>. If timeout is 0 then we use <tt>receiveNoWait</tt>
1904         * otherwise we use <tt>receive(timeout)</tt>.
1905         *
1906         * @param resourceUri           URI of resource endpoint for obtaining additional data.
1907         * @param timeout               timeout in millis to wait at most for data to be available.
1908         * @param aggregationStrategy   aggregation strategy to aggregate input data and additional data.
1909         * @return the builder
1910         * @see org.apache.camel.processor.PollEnricher
1911         */
1912        @SuppressWarnings("unchecked")
1913        public Type pollEnrich(String resourceUri, long timeout, AggregationStrategy aggregationStrategy) {
1914            addOutput(new PollEnrichDefinition(aggregationStrategy, resourceUri, timeout));
1915            return (Type) this;
1916        }
1917    
1918        /**
1919         * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a>
1920         * enriches an exchange with additional data obtained from a <code>resourceUri</code>
1921         * using a {@link org.apache.camel.PollingConsumer} to poll the endpoint.
1922         * <p/>
1923         * The difference between this and {@link #enrich(String)} is that this uses a consumer
1924         * to obatin the additional data, where as enrich uses a producer.
1925         * <p/>
1926         * The timeout controls which operation to use on {@link org.apache.camel.PollingConsumer}.
1927         * If timeout is negative, we use <tt>receive</tt>. If timeout is 0 then we use <tt>receiveNoWait</tt>
1928         * otherwise we use <tt>receive(timeout)</tt>.
1929         *
1930         * @param resourceUri           URI of resource endpoint for obtaining additional data.
1931         * @param timeout               timeout in millis to wait at most for data to be available.
1932         * @return the builder
1933         * @see org.apache.camel.processor.PollEnricher
1934         */
1935        @SuppressWarnings("unchecked")
1936        public Type pollEnrich(String resourceUri, long timeout) {
1937            addOutput(new PollEnrichDefinition(null, resourceUri, timeout));
1938            return (Type) this;
1939        }
1940    
1941        /**
1942         * Adds a onComplection {@link org.apache.camel.spi.Synchronization} hook that invoke this route as
1943         * a callback when the {@link org.apache.camel.Exchange} has finished being processed.
1944         * The hook invoke callbacks for either onComplete or onFailure.
1945         * <p/>
1946         * Will by default always trigger when the {@link org.apache.camel.Exchange} is complete
1947         * (either with success or failed).
1948         * <br/>
1949         * You can limit the callback to either onComplete or onFailure but invoking the nested
1950         * builder method.
1951         * <p/>
1952         * For onFailure the caused exception is stored as a property on the {@link org.apache.camel.Exchange}
1953         * with the key {@link org.apache.camel.Exchange#EXCEPTION_CAUGHT}.
1954         *
1955         * @return the builder
1956         */
1957        @SuppressWarnings("unchecked")
1958        public OnCompletionDefinition onCompletion() {
1959            OnCompletionDefinition answer = new OnCompletionDefinition();
1960            // we must remove all existing on completion definition (as they are global)
1961            // and thus we are the only one as route scoped should override any global scoped
1962            answer.removeAllOnCompletionDefinition(this);
1963            popBlock();
1964            addOutput(answer);
1965            pushBlock(answer);
1966            return answer;
1967        }
1968    
1969        // DataFormat support
1970        // -------------------------------------------------------------------------
1971    
1972        /**
1973         * <a href="http://camel.apache.org/data-format.html">DataFormat:</a>
1974         * Unmarshals the in body using a {@link DataFormat} expression to define
1975         * the format of the input message and the output will be set on the out message body.
1976         *
1977         * @return the expression to create the {@link DataFormat}
1978         */
1979        public DataFormatClause<ProcessorDefinition<Type>> unmarshal() {
1980            return new DataFormatClause<ProcessorDefinition<Type>>(this, DataFormatClause.Operation.Unmarshal);
1981        }
1982    
1983        /**
1984         * <a href="http://camel.apache.org/data-format.html">DataFormat:</a>
1985         * Unmarshals the in body using the specified {@link DataFormat}
1986         * and sets the output on the out message body.
1987         *
1988         * @param dataFormatType  the dataformat
1989         * @return the builder
1990         */
1991        @SuppressWarnings("unchecked")
1992        public Type unmarshal(DataFormatDefinition dataFormatType) {
1993            addOutput(new UnmarshalDefinition(dataFormatType));
1994            return (Type) this;
1995        }
1996    
1997        /**
1998         * <a href="http://camel.apache.org/data-format.html">DataFormat:</a>
1999         * Unmarshals the in body using the specified {@link DataFormat}
2000         * and sets the output on the out message body.
2001         *
2002         * @param dataFormat  the dataformat
2003         * @return the builder
2004         */
2005        public Type unmarshal(DataFormat dataFormat) {
2006            return unmarshal(new DataFormatDefinition(dataFormat));
2007        }
2008    
2009        /**
2010         * <a href="http://camel.apache.org/data-format.html">DataFormat:</a>
2011         * Unmarshals the in body using the specified {@link DataFormat}
2012         * reference in the {@link org.apache.camel.spi.Registry} and sets
2013         * the output on the out message body.
2014         *
2015         * @param dataTypeRef  reference to a {@link DataFormat} to lookup in the registry
2016         * @return the builder
2017         */
2018        @SuppressWarnings("unchecked")
2019        public Type unmarshal(String dataTypeRef) {
2020            addOutput(new UnmarshalDefinition(dataTypeRef));
2021            return (Type) this;
2022        }
2023    
2024        /**
2025         * <a href="http://camel.apache.org/data-format.html">DataFormat:</a>
2026         * Marshals the in body using a {@link DataFormat} expression to define
2027         * the format of the output which will be added to the out body.
2028         *
2029         * @return the expression to create the {@link DataFormat}
2030         */
2031        public DataFormatClause<ProcessorDefinition<Type>> marshal() {
2032            return new DataFormatClause<ProcessorDefinition<Type>>(this, DataFormatClause.Operation.Marshal);
2033        }
2034    
2035        /**
2036         * <a href="http://camel.apache.org/data-format.html">DataFormat:</a>
2037         * Marshals the in body using the specified {@link DataFormat}
2038         * and sets the output on the out message body.
2039         *
2040         * @param dataFormatType  the dataformat
2041         * @return the builder
2042         */
2043        @SuppressWarnings("unchecked")
2044        public Type marshal(DataFormatDefinition dataFormatType) {
2045            addOutput(new MarshalDefinition(dataFormatType));
2046            return (Type) this;
2047        }
2048    
2049        /**
2050         * <a href="http://camel.apache.org/data-format.html">DataFormat:</a>
2051         * Marshals the in body using the specified {@link DataFormat}
2052         * and sets the output on the out message body.
2053         *
2054         * @param dataFormat  the dataformat
2055         * @return the builder
2056         */
2057        public Type marshal(DataFormat dataFormat) {
2058            return marshal(new DataFormatDefinition(dataFormat));
2059        }
2060    
2061        /**
2062         * <a href="http://camel.apache.org/data-format.html">DataFormat:</a>
2063         * Marshals the in body the specified {@link DataFormat}
2064         * reference in the {@link org.apache.camel.spi.Registry} and sets
2065         * the output on the out message body.
2066         *
2067         * @param dataTypeRef  reference to a {@link DataFormat} to lookup in the registry
2068         * @return the builder
2069         */
2070        @SuppressWarnings("unchecked")
2071        public Type marshal(String dataTypeRef) {
2072            addOutput(new MarshalDefinition(dataTypeRef));
2073            return (Type) this;
2074        }
2075    
2076        // Properties
2077        // -------------------------------------------------------------------------
2078        @XmlTransient
2079        @SuppressWarnings("unchecked")
2080        public ProcessorDefinition<? extends ProcessorDefinition> getParent() {
2081            return parent;
2082        }
2083    
2084        public void setParent(ProcessorDefinition<? extends ProcessorDefinition> parent) {
2085            this.parent = parent;
2086        }
2087    
2088        @XmlTransient
2089        public ErrorHandlerBuilder getErrorHandlerBuilder() {
2090            if (errorHandlerBuilder == null) {
2091                errorHandlerBuilder = createErrorHandlerBuilder();
2092            }
2093            return errorHandlerBuilder;
2094        }
2095    
2096        /**
2097         * Sets the error handler to use with processors created by this builder
2098         */
2099        public void setErrorHandlerBuilder(ErrorHandlerBuilder errorHandlerBuilder) {
2100            this.errorHandlerBuilder = errorHandlerBuilder;
2101        }
2102    
2103        /**
2104         * Sets the error handler if one is not already set
2105         */
2106        protected void setErrorHandlerBuilderIfNull(ErrorHandlerBuilder errorHandlerBuilder) {
2107            if (this.errorHandlerBuilder == null) {
2108                setErrorHandlerBuilder(errorHandlerBuilder);
2109            }
2110        }
2111    
2112        public String getErrorHandlerRef() {
2113            return errorHandlerRef;
2114        }
2115    
2116        /**
2117         * Sets the bean ref name of the error handler builder to use on this route
2118         */
2119        @XmlAttribute(required = false)
2120        public void setErrorHandlerRef(String errorHandlerRef) {
2121            this.errorHandlerRef = errorHandlerRef;
2122            setErrorHandlerBuilder(new ErrorHandlerBuilderRef(errorHandlerRef));
2123        }
2124    
2125        @XmlTransient
2126        public NodeFactory getNodeFactory() {
2127            if (nodeFactory == null) {
2128                nodeFactory = new NodeFactory();
2129            }
2130            return nodeFactory;
2131        }
2132    
2133        public void setNodeFactory(NodeFactory nodeFactory) {
2134            this.nodeFactory = nodeFactory;
2135        }
2136    
2137        @XmlTransient
2138        public List<InterceptStrategy> getInterceptStrategies() {
2139            return interceptStrategies;
2140        }
2141    
2142        public void addInterceptStrategy(InterceptStrategy strategy) {
2143            this.interceptStrategies.add(strategy);
2144        }
2145    
2146        /**
2147         * Returns a label to describe this node such as the expression if some kind of expression node
2148         */
2149        public String getLabel() {
2150            return "";
2151        }
2152    
2153    
2154    }