Coverage Report - org.apache.camel.builder.FromBuilder
 
Classes in this File Line Coverage Branch Coverage Complexity
FromBuilder
62% 
86% 
0
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  
  * contributor license agreements.  See the NOTICE file distributed with
 4  
  * this work for additional information regarding copyright ownership.
 5  
  * The ASF licenses this file to You under the Apache License, Version 2.0
 6  
  * (the "License"); you may not use this file except in compliance with
 7  
  * the License.  You may obtain a copy of the License at
 8  
  *
 9  
  *      http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 package org.apache.camel.builder;
 18  
 
 19  
 import org.apache.camel.Endpoint;
 20  
 import org.apache.camel.Exchange;
 21  
 import org.apache.camel.Expression;
 22  
 import org.apache.camel.Predicate;
 23  
 import org.apache.camel.Processor;
 24  
 import org.apache.camel.Route;
 25  
 import org.apache.camel.impl.EventDrivenConsumerRoute;
 26  
 import org.apache.camel.processor.CompositeProcessor;
 27  
 import org.apache.camel.processor.DelegateProcessor;
 28  
 import org.apache.camel.processor.MulticastProcessor;
 29  
 import org.apache.camel.processor.Pipeline;
 30  
 import org.apache.camel.processor.RecipientList;
 31  
 import org.apache.camel.processor.idempotent.IdempotentConsumer;
 32  
 import org.apache.camel.processor.idempotent.MessageIdRepository;
 33  
 import org.apache.camel.spi.Policy;
 34  
 import org.apache.commons.logging.Log;
 35  
 import org.apache.commons.logging.LogFactory;
 36  
 
 37  
 import java.util.ArrayList;
 38  
 import java.util.Collection;
 39  
 import java.util.Collections;
 40  
 import java.util.List;
 41  
 
 42  
 /**
 43  
  * @version $Revision: 548618 $
 44  
  */
 45  
 public class FromBuilder extends BuilderSupport implements ProcessorFactory {
 46  
     public static final String DEFAULT_TRACE_CATEGORY = "org.apache.camel.TRACE";
 47  
     private RouteBuilder builder;
 48  
     private Endpoint from;
 49  145
     private List<Processor> processors = new ArrayList<Processor>();
 50  145
     private List<ProcessorFactory> processFactories = new ArrayList<ProcessorFactory>();
 51  
     private FromBuilder routeBuilder;
 52  
 
 53  
     public FromBuilder(RouteBuilder builder, Endpoint from) {
 54  54
         super(builder);
 55  54
         this.builder = builder;
 56  54
         this.from = from;
 57  54
     }
 58  
 
 59  
     public FromBuilder(FromBuilder parent) {
 60  91
         super(parent);
 61  91
         this.builder = parent.getBuilder();
 62  91
         this.from = parent.getFrom();
 63  91
     }
 64  
 
 65  
     /**
 66  
      * Sends the exchange to the given endpoint URI
 67  
      */
 68  
     @Fluent
 69  
     public ProcessorFactory to(@FluentArg("uri")String uri) {
 70  48
         return to(endpoint(uri));
 71  
     }
 72  
 
 73  
     /**
 74  
      * Sends the exchange to the given endpoint
 75  
      */
 76  
     @Fluent
 77  
     public ProcessorFactory to(@FluentArg("ref")Endpoint endpoint) {
 78  48
         ToBuilder answer = new ToBuilder(this, endpoint);
 79  48
         addProcessBuilder(answer);
 80  48
         return answer;
 81  
     }
 82  
 
 83  
     /**
 84  
      * Sends the exchange to a list of endpoints using the {@link MulticastProcessor} pattern
 85  
      */
 86  
     @Fluent
 87  
     public ProcessorFactory to(String... uris) {
 88  2
         return to(endpoints(uris));
 89  
     }
 90  
 
 91  
     /**
 92  
      * Sends the exchange to a list of endpoints using the {@link MulticastProcessor} pattern
 93  
      */
 94  
     @Fluent
 95  
     public ProcessorFactory to(
 96  
             @FluentArg(value = "endpoint", attribute = false, element = true)
 97  
             Endpoint... endpoints) {
 98  0
         return to(endpoints(endpoints));
 99  
     }
 100  
 
 101  
     /**
 102  
      * Sends the exchange to a list of endpoint using the {@link MulticastProcessor} pattern
 103  
      */
 104  
     @Fluent
 105  
     public ProcessorFactory to(@FluentArg(value = "endpoint", attribute = false, element = true)
 106  
     Collection<Endpoint> endpoints) {
 107  2
         return addProcessBuilder(new MulticastBuilder(this, endpoints));
 108  
     }
 109  
 
 110  
     /**
 111  
      * Creates a {@link Pipeline} of the list of endpoints so that the message will get processed by each endpoint in turn
 112  
      * and for request/response the output of one endpoint will be the input of the next endpoint
 113  
      */
 114  
     @Fluent
 115  
     public ProcessorFactory pipeline(@FluentArg("uris")String... uris) {
 116  1
         return pipeline(endpoints(uris));
 117  
     }
 118  
 
 119  
     /**
 120  
      * Creates a {@link Pipeline} of the list of endpoints so that the message will get processed by each endpoint in turn
 121  
      * and for request/response the output of one endpoint will be the input of the next endpoint
 122  
      */
 123  
     @Fluent
 124  
     public ProcessorFactory pipeline(@FluentArg("endpoints")Endpoint... endpoints) {
 125  0
         return pipeline(endpoints(endpoints));
 126  
     }
 127  
 
 128  
     /**
 129  
      * Creates a {@link Pipeline} of the list of endpoints so that the message will get processed by each endpoint in turn
 130  
      * and for request/response the output of one endpoint will be the input of the next endpoint
 131  
      */
 132  
     @Fluent
 133  
     public ProcessorFactory pipeline(@FluentArg("endpoints")Collection<Endpoint> endpoints) {
 134  1
         return addProcessBuilder(new PipelineBuilder(this, endpoints));
 135  
     }
 136  
 
 137  
     /**
 138  
      * Creates an {@link IdempotentConsumer} to avoid duplicate messages
 139  
      */
 140  
     @Fluent
 141  
     public IdempotentConsumerBuilder idempotentConsumer(
 142  
             @FluentArg("messageIdExpression")Expression messageIdExpression,
 143  
             @FluentArg("MessageIdRepository")MessageIdRepository messageIdRepository) {
 144  2
         return (IdempotentConsumerBuilder) addProcessBuilder(new IdempotentConsumerBuilder(this, messageIdExpression, messageIdRepository));
 145  
     }
 146  
 
 147  
     /**
 148  
      * Creates a predicate which is applied and only if it is true then
 149  
      * the exchange is forwarded to the destination
 150  
      *
 151  
      * @return the builder for a predicate
 152  
      */
 153  
     @Fluent
 154  
     public FilterBuilder filter(
 155  
             @FluentArg(value = "predicate", element = true)
 156  
             Predicate predicate) {
 157  13
         FilterBuilder answer = new FilterBuilder(this, predicate);
 158  13
         addProcessBuilder(answer);
 159  13
         return answer;
 160  
     }
 161  
 
 162  
     /**
 163  
      * Creates a choice of one or more predicates with an otherwise clause
 164  
      *
 165  
      * @return the builder for a choice expression
 166  
      */
 167  
     @Fluent(nestedActions = true)
 168  
     public ChoiceBuilder choice() {
 169  5
         ChoiceBuilder answer = new ChoiceBuilder(this);
 170  5
         addProcessBuilder(answer);
 171  5
         return answer;
 172  
     }
 173  
 
 174  
     /**
 175  
      * Creates a dynamic <a href="http://activemq.apache.org/camel/recipient-list.html">Recipient List</a> pattern.
 176  
      *
 177  
      * @param receipients is the builder of the expression used in the {@link RecipientList} to decide the destinations
 178  
      */
 179  
     @Fluent
 180  
     public RecipientListBuilder recipientList(
 181  
             @FluentArg(value = "recipients", element = true)
 182  
             Expression receipients) {
 183  2
         RecipientListBuilder answer = new RecipientListBuilder(this, receipients);
 184  2
         addProcessBuilder(answer);
 185  2
         return answer;
 186  
     }
 187  
 
 188  
     /**
 189  
      * A builder for the <a href="http://activemq.apache.org/camel/splitter.html">Splitter</a> pattern
 190  
      * where an expression is evaluated to iterate through each of the parts of a message and then each part is then send to some endpoint.
 191  
      *
 192  
      * @param receipients the expression on which to split
 193  
      * @return the builder
 194  
      */
 195  
     @Fluent
 196  
     public SplitterBuilder splitter(@FluentArg(value = "recipients", element = true)Expression receipients) {
 197  2
         SplitterBuilder answer = new SplitterBuilder(this, receipients);
 198  2
         addProcessBuilder(answer);
 199  2
         return answer;
 200  
     }
 201  
 
 202  
     /**
 203  
      * A builder for the <a href="http://activemq.apache.org/camel/resequencer.html">Resequencer</a> pattern
 204  
      * where an expression is evaluated to be able to compare the message exchanges to reorder them. e.g. you
 205  
      * may wish to sort by some header
 206  
      *
 207  
      * @param expression the expression on which to compare messages in order
 208  
      * @return the builder
 209  
      */
 210  
     public ResequencerBuilder resequencer(Expression<Exchange> expression) {
 211  1
         return resequencer(Collections.<Expression<Exchange>>singletonList(expression));
 212  
     }
 213  
 
 214  
     /**
 215  
      * A builder for the <a href="http://activemq.apache.org/camel/resequencer.html">Resequencer</a> pattern
 216  
      * where a list of expressions are evaluated to be able to compare the message exchanges to reorder them. e.g. you
 217  
      * may wish to sort by some headers
 218  
      *
 219  
      * @param expressions the expressions on which to compare messages in order
 220  
      * @return the builder
 221  
      */
 222  
     @Fluent
 223  
     public ResequencerBuilder resequencer(@FluentArg(value = "expressions")List<Expression<Exchange>> expressions) {
 224  1
         ResequencerBuilder answer = new ResequencerBuilder(this, expressions);
 225  1
         setRouteBuilder(answer);
 226  1
         return answer;
 227  
     }
 228  
 
 229  
     /**
 230  
      * A builder for the <a href="http://activemq.apache.org/camel/resequencer.html">Resequencer</a> pattern
 231  
      * where a list of expressions are evaluated to be able to compare the message exchanges to reorder them. e.g. you
 232  
      * may wish to sort by some headers
 233  
      *
 234  
      * @param expressions the expressions on which to compare messages in order
 235  
      * @return the builder
 236  
      */
 237  
     @Fluent
 238  
     public ResequencerBuilder resequencer(Expression<Exchange>... expressions) {
 239  0
         List<Expression<Exchange>> list = new ArrayList<Expression<Exchange>>();
 240  0
         for (Expression<Exchange> expression : expressions) {
 241  0
             list.add(expression);
 242  
         }
 243  0
         return resequencer(list);
 244  
     }
 245  
 
 246  
     /**
 247  
      * Installs the given error handler builder
 248  
      *
 249  
      * @param errorHandlerBuilder the error handler to be used by default for all child routes
 250  
      * @return the current builder with the error handler configured
 251  
      */
 252  
     @Fluent
 253  
     public FromBuilder errorHandler(@FluentArg("handler")ErrorHandlerBuilder errorHandlerBuilder) {
 254  3
         setErrorHandlerBuilder(errorHandlerBuilder);
 255  3
         return this;
 256  
     }
 257  
 
 258  
     /**
 259  
      * Configures whether or not the error handler is inherited by every processing node (or just the top most one)
 260  
      *
 261  
      * @param condition the falg as to whether error handlers should be inherited or not
 262  
      * @return the current builder
 263  
      */
 264  
     @Fluent
 265  
     public FromBuilder inheritErrorHandler(@FluentArg("condition")boolean condition) {
 266  0
         setInheritErrorHandler(condition);
 267  0
         return this;
 268  
     }
 269  
 
 270  
     @Fluent(nestedActions = true)
 271  
     public InterceptorBuilder intercept() {
 272  2
         InterceptorBuilder answer = new InterceptorBuilder(this);
 273  2
         addProcessBuilder(answer);
 274  2
         return answer;
 275  
     }
 276  
 
 277  
     /**
 278  
      * Trace logs the exchange before it goes to the next processing step using the {@link #DEFAULT_TRACE_CATEGORY} logging
 279  
      * category.
 280  
      *
 281  
      * @return
 282  
      */
 283  
     @Fluent
 284  
     public FromBuilder trace() {
 285  0
         return trace(DEFAULT_TRACE_CATEGORY);
 286  
     }
 287  
 
 288  
     /**
 289  
      * Trace logs the exchange before it goes to the next processing step using the specified logging
 290  
      * category.
 291  
      *
 292  
      * @param category the logging category trace messages will sent to.
 293  
      * @return
 294  
      */
 295  
     @Fluent
 296  
     public FromBuilder trace(@FluentArg("category")String category) {
 297  0
         final Log log = LogFactory.getLog(category);
 298  0
         return intercept(new DelegateProcessor() {
 299  
             @Override
 300  0
             public void process(Exchange exchange) throws Exception {
 301  0
                 log.trace(exchange);
 302  0
                 processNext(exchange);
 303  0
             }
 304  
         });
 305  
     }
 306  
 
 307  
     @Fluent
 308  
     public FromBuilder intercept(@FluentArg("interceptor")DelegateProcessor interceptor) {
 309  0
         InterceptorBuilder answer = new InterceptorBuilder(this);
 310  0
         answer.add(interceptor);
 311  0
         addProcessBuilder(answer);
 312  0
         return answer.target();
 313  
     }
 314  
 
 315  
     @Fluent(nestedActions = true)
 316  
     public PolicyBuilder policies() {
 317  0
         PolicyBuilder answer = new PolicyBuilder(this);
 318  0
         addProcessBuilder(answer);
 319  0
         return answer;
 320  
     }
 321  
 
 322  
     @Fluent
 323  
     public FromBuilder policy(@FluentArg("policy")Policy policy) {
 324  0
         PolicyBuilder answer = new PolicyBuilder(this);
 325  0
         answer.add(policy);
 326  0
         addProcessBuilder(answer);
 327  0
         return answer.target();
 328  
     }
 329  
 
 330  
     // Transformers
 331  
     //-------------------------------------------------------------------------
 332  
 
 333  
     /**
 334  
      * Adds the custom processor to this destination which could be a final destination, or could be a transformation in a pipeline
 335  
      */
 336  
     @Fluent
 337  
     public FromBuilder process(@FluentArg("ref")Processor processor) {
 338  16
         addProcessorBuilder(processor);
 339  16
         return this;
 340  
     }
 341  
 
 342  
     /**
 343  
      * Adds a processor which sets the body on the IN message
 344  
      */
 345  
     @Fluent
 346  
     public FromBuilder setBody(Expression expression) {
 347  1
         addProcessorBuilder(ProcessorBuilder.setBody(expression));
 348  1
         return this;
 349  
     }
 350  
 
 351  
     /**
 352  
      * Adds a processor which sets the body on the OUT message
 353  
      */
 354  
     @Fluent
 355  
     public FromBuilder setOutBody(Expression expression) {
 356  0
         addProcessorBuilder(ProcessorBuilder.setOutBody(expression));
 357  0
         return this;
 358  
     }
 359  
 
 360  
     /**
 361  
      * Adds a processor which sets the header on the IN message
 362  
      */
 363  
     @Fluent
 364  
     public FromBuilder setHeader(String name, Expression expression) {
 365  0
         addProcessorBuilder(ProcessorBuilder.setHeader(name, expression));
 366  0
         return this;
 367  
     }
 368  
 
 369  
     /**
 370  
      * Adds a processor which sets the header on the OUT message
 371  
      */
 372  
     @Fluent
 373  
     public FromBuilder setOutHeader(String name, Expression expression) {
 374  0
         addProcessorBuilder(ProcessorBuilder.setOutHeader(name, expression));
 375  0
         return this;
 376  
     }
 377  
 
 378  
     /**
 379  
      * Adds a processor which sets the exchange property
 380  
      */
 381  
     @Fluent
 382  
     public FromBuilder setProperty(String name, Expression expression) {
 383  0
         addProcessorBuilder(ProcessorBuilder.setProperty(name, expression));
 384  0
         return this;
 385  
     }
 386  
 
 387  
     /**
 388  
      * Converts the IN message body to the specified type
 389  
      */
 390  
     @Fluent
 391  
     public FromBuilder convertBodyTo(Class type) {
 392  0
         addProcessorBuilder(ProcessorBuilder.setBody(Builder.body().convertTo(type)));
 393  0
         return this;
 394  
     }
 395  
 
 396  
     /**
 397  
      * Converts the OUT message body to the specified type
 398  
      */
 399  
     @Fluent
 400  
     public FromBuilder convertOutBodyTo(Class type) {
 401  0
         addProcessorBuilder(ProcessorBuilder.setOutBody(Builder.outBody().convertTo(type)));
 402  0
         return this;
 403  
     }
 404  
 
 405  
     // Properties
 406  
     //-------------------------------------------------------------------------
 407  
     public RouteBuilder getBuilder() {
 408  91
         return builder;
 409  
     }
 410  
 
 411  
     public Endpoint getFrom() {
 412  146
         return from;
 413  
     }
 414  
 
 415  
     public List<Processor> getProcessors() {
 416  0
         return processors;
 417  
     }
 418  
 
 419  
     public ProcessorFactory addProcessBuilder(ProcessorFactory processFactory) {
 420  94
         processFactories.add(processFactory);
 421  94
         return processFactory;
 422  
     }
 423  
 
 424  
     protected void addProcessorBuilder(Processor processor) {
 425  17
         addProcessBuilder(new ConstantProcessorBuilder(processor));
 426  17
     }
 427  
 
 428  
     public void addProcessor(Processor processor) {
 429  0
         processors.add(processor);
 430  0
     }
 431  
 
 432  
     public Route createRoute() throws Exception {
 433  54
         if (routeBuilder != null) {
 434  1
             return routeBuilder.createRoute();
 435  
         }
 436  53
         Processor processor = createProcessor();
 437  53
         if (processor == null) {
 438  0
             throw new IllegalArgumentException("No processor created for: " + this);
 439  
         }
 440  53
         return new EventDrivenConsumerRoute(getFrom(), processor);
 441  
     }
 442  
 
 443  
     public Processor createProcessor() throws Exception {
 444  88
         List<Processor> answer = new ArrayList<Processor>();
 445  
 
 446  88
         for (ProcessorFactory processFactory : processFactories) {
 447  94
             Processor processor = makeProcessor(processFactory);
 448  94
             if (processor == null) {
 449  0
                 throw new IllegalArgumentException("No processor created for processBuilder: " + processFactory);
 450  
             }
 451  94
             answer.add(processor);
 452  94
         }
 453  88
         if (answer.size() == 0) {
 454  0
             return null;
 455  
         }
 456  88
         Processor processor = null;
 457  88
         if (answer.size() == 1) {
 458  82
             processor = answer.get(0);
 459  82
         }
 460  
         else {
 461  6
             processor = new CompositeProcessor(answer);
 462  
         }
 463  88
         return processor;
 464  
     }
 465  
 
 466  
     /**
 467  
      * Creates the processor and wraps it in any necessary interceptors and error handlers
 468  
      */
 469  
     protected Processor makeProcessor(ProcessorFactory processFactory) throws Exception {
 470  94
         Processor processor = processFactory.createProcessor();
 471  94
         processor = wrapProcessor(processor);
 472  94
         return wrapInErrorHandler(processor);
 473  
     }
 474  
 
 475  
     /**
 476  
      * A strategy method to allow newly created processors to be wrapped in an error handler. This feature
 477  
      * could be disabled for child builders such as {@link IdempotentConsumerBuilder} which will rely on the
 478  
      * {@link FromBuilder} to perform the error handling to avoid doubly-wrapped processors with 2 nested error handlers
 479  
      */
 480  
     protected Processor wrapInErrorHandler(Processor processor) throws Exception {
 481  92
         return getErrorHandlerBuilder().createErrorHandler(processor);
 482  
     }
 483  
 
 484  
     /**
 485  
      * A strategy method which allows derived classes to wrap the child processor in some kind of interceptor such as
 486  
      * a filter for the {@link IdempotentConsumerBuilder}.
 487  
      *
 488  
      * @param processor the processor which can be wrapped
 489  
      * @return the original processor or a new wrapped interceptor
 490  
      */
 491  
     protected Processor wrapProcessor(Processor processor) {
 492  92
         return processor;
 493  
     }
 494  
 
 495  
     protected FromBuilder getRouteBuilder() {
 496  0
         return routeBuilder;
 497  
     }
 498  
 
 499  
     protected void setRouteBuilder(FromBuilder routeBuilder) {
 500  1
         this.routeBuilder = routeBuilder;
 501  1
     }
 502  
 }