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