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