Package org.apache.camel.builder

Source Code of org.apache.camel.builder.FromBuilder

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.builder;

import org.apache.camel.Endpoint;
import org.apache.camel.Exchange;
import org.apache.camel.Expression;
import org.apache.camel.Predicate;
import org.apache.camel.Processor;
import org.apache.camel.Route;
import org.apache.camel.impl.EventDrivenConsumerRoute;
import org.apache.camel.processor.CompositeProcessor;
import org.apache.camel.processor.DelegateProcessor;
import org.apache.camel.processor.MulticastProcessor;
import org.apache.camel.processor.Pipeline;
import org.apache.camel.processor.RecipientList;
import org.apache.camel.processor.idempotent.IdempotentConsumer;
import org.apache.camel.processor.idempotent.MessageIdRepository;
import org.apache.camel.spi.Policy;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
* @version $Revision: 548618 $
*/
public class FromBuilder extends BuilderSupport implements ProcessorFactory {
    public static final String DEFAULT_TRACE_CATEGORY = "org.apache.camel.TRACE";
    private RouteBuilder builder;
    private Endpoint from;
    private List<Processor> processors = new ArrayList<Processor>();
    private List<ProcessorFactory> processFactories = new ArrayList<ProcessorFactory>();
    private FromBuilder routeBuilder;

    public FromBuilder(RouteBuilder builder, Endpoint from) {
        super(builder);
        this.builder = builder;
        this.from = from;
    }

    public FromBuilder(FromBuilder parent) {
        super(parent);
        this.builder = parent.getBuilder();
        this.from = parent.getFrom();
    }

    /**
     * Sends the exchange to the given endpoint URI
     */
    @Fluent
    public ProcessorFactory to(@FluentArg("uri")String uri) {
        return to(endpoint(uri));
    }

    /**
     * Sends the exchange to the given endpoint
     */
    @Fluent
    public ProcessorFactory to(@FluentArg("ref")Endpoint endpoint) {
        ToBuilder answer = new ToBuilder(this, endpoint);
        addProcessBuilder(answer);
        return answer;
    }

    /**
     * Sends the exchange to a list of endpoints using the {@link MulticastProcessor} pattern
     */
    @Fluent
    public ProcessorFactory to(String... uris) {
        return to(endpoints(uris));
    }

    /**
     * Sends the exchange to a list of endpoints using the {@link MulticastProcessor} pattern
     */
    @Fluent
    public ProcessorFactory to(
            @FluentArg(value = "endpoint", attribute = false, element = true)
            Endpoint... endpoints) {
        return to(endpoints(endpoints));
    }

    /**
     * Sends the exchange to a list of endpoint using the {@link MulticastProcessor} pattern
     */
    @Fluent
    public ProcessorFactory to(@FluentArg(value = "endpoint", attribute = false, element = true)
    Collection<Endpoint> endpoints) {
        return addProcessBuilder(new MulticastBuilder(this, endpoints));
    }

    /**
     * Creates a {@link Pipeline} of the list of endpoints so that the message will get processed by each endpoint in turn
     * and for request/response the output of one endpoint will be the input of the next endpoint
     */
    @Fluent
    public ProcessorFactory pipeline(@FluentArg("uris")String... uris) {
        return pipeline(endpoints(uris));
    }

    /**
     * Creates a {@link Pipeline} of the list of endpoints so that the message will get processed by each endpoint in turn
     * and for request/response the output of one endpoint will be the input of the next endpoint
     */
    @Fluent
    public ProcessorFactory pipeline(@FluentArg("endpoints")Endpoint... endpoints) {
        return pipeline(endpoints(endpoints));
    }

    /**
     * Creates a {@link Pipeline} of the list of endpoints so that the message will get processed by each endpoint in turn
     * and for request/response the output of one endpoint will be the input of the next endpoint
     */
    @Fluent
    public ProcessorFactory pipeline(@FluentArg("endpoints")Collection<Endpoint> endpoints) {
        return addProcessBuilder(new PipelineBuilder(this, endpoints));
    }

    /**
     * Creates an {@link IdempotentConsumer} to avoid duplicate messages
     */
    @Fluent
    public IdempotentConsumerBuilder idempotentConsumer(
            @FluentArg("messageIdExpression")Expression messageIdExpression,
            @FluentArg("MessageIdRepository")MessageIdRepository messageIdRepository) {
        return (IdempotentConsumerBuilder) addProcessBuilder(new IdempotentConsumerBuilder(this, messageIdExpression, messageIdRepository));
    }

    /**
     * Creates a predicate which is applied and only if it is true then
     * the exchange is forwarded to the destination
     *
     * @return the builder for a predicate
     */
    @Fluent
    public FilterBuilder filter(
            @FluentArg(value = "predicate", element = true)
            Predicate predicate) {
        FilterBuilder answer = new FilterBuilder(this, predicate);
        addProcessBuilder(answer);
        return answer;
    }

    /**
     * Creates a choice of one or more predicates with an otherwise clause
     *
     * @return the builder for a choice expression
     */
    @Fluent(nestedActions = true)
    public ChoiceBuilder choice() {
        ChoiceBuilder answer = new ChoiceBuilder(this);
        addProcessBuilder(answer);
        return answer;
    }

    /**
     * Creates a dynamic <a href="http://activemq.apache.org/camel/recipient-list.html">Recipient List</a> pattern.
     *
     * @param receipients is the builder of the expression used in the {@link RecipientList} to decide the destinations
     */
    @Fluent
    public RecipientListBuilder recipientList(
            @FluentArg(value = "recipients", element = true)
            Expression receipients) {
        RecipientListBuilder answer = new RecipientListBuilder(this, receipients);
        addProcessBuilder(answer);
        return answer;
    }

    /**
     * A builder for the <a href="http://activemq.apache.org/camel/splitter.html">Splitter</a> pattern
     * 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.
     *
     * @param receipients the expression on which to split
     * @return the builder
     */
    @Fluent
    public SplitterBuilder splitter(@FluentArg(value = "recipients", element = true)Expression receipients) {
        SplitterBuilder answer = new SplitterBuilder(this, receipients);
        addProcessBuilder(answer);
        return answer;
    }

    /**
     * A builder for the <a href="http://activemq.apache.org/camel/resequencer.html">Resequencer</a> pattern
     * where an expression is evaluated to be able to compare the message exchanges to reorder them. e.g. you
     * may wish to sort by some header
     *
     * @param expression the expression on which to compare messages in order
     * @return the builder
     */
    public ResequencerBuilder resequencer(Expression<Exchange> expression) {
        return resequencer(Collections.<Expression<Exchange>>singletonList(expression));
    }

    /**
     * A builder for the <a href="http://activemq.apache.org/camel/resequencer.html">Resequencer</a> pattern
     * where a list of expressions are evaluated to be able to compare the message exchanges to reorder them. e.g. you
     * may wish to sort by some headers
     *
     * @param expressions the expressions on which to compare messages in order
     * @return the builder
     */
    @Fluent
    public ResequencerBuilder resequencer(@FluentArg(value = "expressions")List<Expression<Exchange>> expressions) {
        ResequencerBuilder answer = new ResequencerBuilder(this, expressions);
        setRouteBuilder(answer);
        return answer;
    }

    /**
     * A builder for the <a href="http://activemq.apache.org/camel/resequencer.html">Resequencer</a> pattern
     * where a list of expressions are evaluated to be able to compare the message exchanges to reorder them. e.g. you
     * may wish to sort by some headers
     *
     * @param expressions the expressions on which to compare messages in order
     * @return the builder
     */
    @Fluent
    public ResequencerBuilder resequencer(Expression<Exchange>... expressions) {
        List<Expression<Exchange>> list = new ArrayList<Expression<Exchange>>();
        for (Expression<Exchange> expression : expressions) {
            list.add(expression);
        }
        return resequencer(list);
    }

    /**
     * Installs the given error handler builder
     *
     * @param errorHandlerBuilder the error handler to be used by default for all child routes
     * @return the current builder with the error handler configured
     */
    @Fluent
    public FromBuilder errorHandler(@FluentArg("handler")ErrorHandlerBuilder errorHandlerBuilder) {
        setErrorHandlerBuilder(errorHandlerBuilder);
        return this;
    }

    /**
     * Configures whether or not the error handler is inherited by every processing node (or just the top most one)
     *
     * @param condition the falg as to whether error handlers should be inherited or not
     * @return the current builder
     */
    @Fluent
    public FromBuilder inheritErrorHandler(@FluentArg("condition")boolean condition) {
        setInheritErrorHandler(condition);
        return this;
    }

    @Fluent(nestedActions = true)
    public InterceptorBuilder intercept() {
        InterceptorBuilder answer = new InterceptorBuilder(this);
        addProcessBuilder(answer);
        return answer;
    }

    /**
     * Trace logs the exchange before it goes to the next processing step using the {@link #DEFAULT_TRACE_CATEGORY} logging
     * category.
     *
     * @return
     */
    @Fluent
    public FromBuilder trace() {
        return trace(DEFAULT_TRACE_CATEGORY);
    }

    /**
     * Trace logs the exchange before it goes to the next processing step using the specified logging
     * category.
     *
     * @param category the logging category trace messages will sent to.
     * @return
     */
    @Fluent
    public FromBuilder trace(@FluentArg("category")String category) {
        final Log log = LogFactory.getLog(category);
        return intercept(new DelegateProcessor() {
            @Override
            public void process(Exchange exchange) throws Exception {
                log.trace(exchange);
                processNext(exchange);
            }
        });
    }

    @Fluent
    public FromBuilder intercept(@FluentArg("interceptor")DelegateProcessor interceptor) {
        InterceptorBuilder answer = new InterceptorBuilder(this);
        answer.add(interceptor);
        addProcessBuilder(answer);
        return answer.target();
    }

    @Fluent(nestedActions = true)
    public PolicyBuilder policies() {
        PolicyBuilder answer = new PolicyBuilder(this);
        addProcessBuilder(answer);
        return answer;
    }

    @Fluent
    public FromBuilder policy(@FluentArg("policy")Policy policy) {
        PolicyBuilder answer = new PolicyBuilder(this);
        answer.add(policy);
        addProcessBuilder(answer);
        return answer.target();
    }

    // Transformers
    //-------------------------------------------------------------------------

    /**
     * Adds the custom processor to this destination which could be a final destination, or could be a transformation in a pipeline
     */
    @Fluent
    public FromBuilder process(@FluentArg("ref")Processor processor) {
        addProcessorBuilder(processor);
        return this;
    }

    /**
     * Adds a processor which sets the body on the IN message
     */
    @Fluent
    public FromBuilder setBody(Expression expression) {
        addProcessorBuilder(ProcessorBuilder.setBody(expression));
        return this;
    }

    /**
     * Adds a processor which sets the body on the OUT message
     */
    @Fluent
    public FromBuilder setOutBody(Expression expression) {
        addProcessorBuilder(ProcessorBuilder.setOutBody(expression));
        return this;
    }

    /**
     * Adds a processor which sets the header on the IN message
     */
    @Fluent
    public FromBuilder setHeader(String name, Expression expression) {
        addProcessorBuilder(ProcessorBuilder.setHeader(name, expression));
        return this;
    }

    /**
     * Adds a processor which sets the header on the OUT message
     */
    @Fluent
    public FromBuilder setOutHeader(String name, Expression expression) {
        addProcessorBuilder(ProcessorBuilder.setOutHeader(name, expression));
        return this;
    }

    /**
     * Adds a processor which sets the exchange property
     */
    @Fluent
    public FromBuilder setProperty(String name, Expression expression) {
        addProcessorBuilder(ProcessorBuilder.setProperty(name, expression));
        return this;
    }

    /**
     * Converts the IN message body to the specified type
     */
    @Fluent
    public FromBuilder convertBodyTo(Class type) {
        addProcessorBuilder(ProcessorBuilder.setBody(Builder.body().convertTo(type)));
        return this;
    }

    /**
     * Converts the OUT message body to the specified type
     */
    @Fluent
    public FromBuilder convertOutBodyTo(Class type) {
        addProcessorBuilder(ProcessorBuilder.setOutBody(Builder.outBody().convertTo(type)));
        return this;
    }

    // Properties
    //-------------------------------------------------------------------------
    public RouteBuilder getBuilder() {
        return builder;
    }

    public Endpoint getFrom() {
        return from;
    }

    public List<Processor> getProcessors() {
        return processors;
    }

    public ProcessorFactory addProcessBuilder(ProcessorFactory processFactory) {
        processFactories.add(processFactory);
        return processFactory;
    }

    protected void addProcessorBuilder(Processor processor) {
        addProcessBuilder(new ConstantProcessorBuilder(processor));
    }

    public void addProcessor(Processor processor) {
        processors.add(processor);
    }

    public Route createRoute() throws Exception {
        if (routeBuilder != null) {
            return routeBuilder.createRoute();
        }
        Processor processor = createProcessor();
        if (processor == null) {
            throw new IllegalArgumentException("No processor created for: " + this);
        }
        return new EventDrivenConsumerRoute(getFrom(), processor);
    }

    public Processor createProcessor() throws Exception {
        List<Processor> answer = new ArrayList<Processor>();

        for (ProcessorFactory processFactory : processFactories) {
            Processor processor = makeProcessor(processFactory);
            if (processor == null) {
                throw new IllegalArgumentException("No processor created for processBuilder: " + processFactory);
            }
            answer.add(processor);
        }
        if (answer.size() == 0) {
            return null;
        }
        Processor processor = null;
        if (answer.size() == 1) {
            processor = answer.get(0);
        }
        else {
            processor = new CompositeProcessor(answer);
        }
        return processor;
    }

    /**
     * Creates the processor and wraps it in any necessary interceptors and error handlers
     */
    protected Processor makeProcessor(ProcessorFactory processFactory) throws Exception {
        Processor processor = processFactory.createProcessor();
        processor = wrapProcessor(processor);
        return wrapInErrorHandler(processor);
    }

    /**
     * A strategy method to allow newly created processors to be wrapped in an error handler. This feature
     * could be disabled for child builders such as {@link IdempotentConsumerBuilder} which will rely on the
     * {@link FromBuilder} to perform the error handling to avoid doubly-wrapped processors with 2 nested error handlers
     */
    protected Processor wrapInErrorHandler(Processor processor) throws Exception {
        return getErrorHandlerBuilder().createErrorHandler(processor);
    }

    /**
     * A strategy method which allows derived classes to wrap the child processor in some kind of interceptor such as
     * a filter for the {@link IdempotentConsumerBuilder}.
     *
     * @param processor the processor which can be wrapped
     * @return the original processor or a new wrapped interceptor
     */
    protected Processor wrapProcessor(Processor processor) {
        return processor;
    }

    protected FromBuilder getRouteBuilder() {
        return routeBuilder;
    }

    protected void setRouteBuilder(FromBuilder routeBuilder) {
        this.routeBuilder = routeBuilder;
    }
}
TOP

Related Classes of org.apache.camel.builder.FromBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.