Package org.mule.processor.chain

Source Code of org.mule.processor.chain.DefaultMessageProcessorChainBuilder

/*
* $Id: DefaultMessageProcessorChainBuilder.java 20875 2011-01-04 16:09:25Z aperepel $
* --------------------------------------------------------------------------------------
* Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
*
* The software in this package is published under the terms of the CPAL v1.0
* license, a copy of which has been included with this distribution in the
* LICENSE.txt file.
*/

package org.mule.processor.chain;

import org.mule.api.MuleException;
import org.mule.api.construct.FlowConstruct;
import org.mule.api.processor.InterceptingMessageProcessor;
import org.mule.api.processor.MessageProcessor;
import org.mule.api.processor.MessageProcessorBuilder;
import org.mule.api.processor.MessageProcessorChain;

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

/**
* <p>
* Constructs a chain of {@link MessageProcessor}s and wraps the invocation of the chain in a composite
* MessageProcessor. Both MessageProcessors and InterceptingMessageProcessor's can be chained together
* arbitrarily in a single chain. InterceptingMessageProcessors simply intercept the next MessageProcessor in
* the chain. When other non-intercepting MessageProcessors are used an adapter is used internally to chain
* the MessageProcessor with the next in the chain.
* </p>
* <p>
* The MessageProcessor instance that this builder builds can be nested in other chains as required.
* </p>
*/
public class DefaultMessageProcessorChainBuilder extends AbstractMessageProcessorChainBuilder
{

    public DefaultMessageProcessorChainBuilder()
    {
        // empty
    }

    public DefaultMessageProcessorChainBuilder(FlowConstruct flowConstruct)
    {
        this.flowConstruct = flowConstruct;
    }

    /**
     * This builder supports the chaining together of message processors that intercept and also those that
     * don't. While one can iterate over message processor intercepting message processors need to be chained
     * together. One solution is make all message processors intercepting (via adaption) and chain them all
     * together, this results in huge stack traces and recursive calls with adaptor. The alternative is to
     * build the chain in such a way that we iterate when we can and chain where we need to. <br>
     * We iterate over the list of message processor to be chained together in reverse order collecting up
     * those that can be iterated over in a temporary list, as soon as we have an intercepting message
     * processor we create a DefaultMessageProcessorChain using the temporary list and set it as a listener of
     * the intercepting message processor and then we continue with the algorithm
     */
    public MessageProcessorChain build() throws MuleException
    {
        LinkedList<MessageProcessor> tempList = new LinkedList<MessageProcessor>();

        // Start from last but one message processor and work backwards
        for (int i = processors.size() - 1; i >= 0; i--)
        {
            MessageProcessor processor = initializeMessageProcessor(processors.get(i));
            if (processor instanceof InterceptingMessageProcessor)
            {
                InterceptingMessageProcessor interceptingProcessor = (InterceptingMessageProcessor) processor;
                // Processor is intercepting so we can't simply iterate
                if (i + 1 < processors.size())
                {
                    // The current processor is not the last in the list
                    if (tempList.isEmpty())
                    {
                        interceptingProcessor.setListener(initializeMessageProcessor(processors.get(i + 1)));
                    }
                    else if (tempList.size() == 1)
                    {
                        interceptingProcessor.setListener(tempList.get(0));
                    }
                    else
                    {
                        final DefaultMessageProcessorChain chain = new DefaultMessageProcessorChain(
                            "(inner iterating chain) of " + name, new ArrayList<MessageProcessor>(tempList));
                        interceptingProcessor.setListener(chain);
                    }
                }
                tempList = new LinkedList<MessageProcessor>(Collections.singletonList(processor));
            }
            else
            {
                // Processor is not intercepting so we can invoke it using iteration
                // (add to temp list)
                tempList.addFirst(initializeMessageProcessor(processor));
            }
        }
        // Create the final chain using the current tempList after reserve iteration is complete. This temp
        // list contains the first n processors in the chain that are not intercepting.. with processor n+1
        // having been injected as the listener of processor n
        final DefaultMessageProcessorChain chain = new DefaultMessageProcessorChain(name,
            new ArrayList<MessageProcessor>(tempList));

        // Wrap with something that can apply lifecycle to all processors which are otherwise not visable from
        // DefaultMessageProcessorChain
        return new InterceptingChainLifecycleWrapper(chain, processors, "wrapper for " + name);
    }

    public DefaultMessageProcessorChainBuilder chain(MessageProcessor... processors)
    {
        for (MessageProcessor messageProcessor : processors)
        {
            this.processors.add(messageProcessor);
        }
        return this;
    }

    public DefaultMessageProcessorChainBuilder chain(List<MessageProcessor> processors)
    {
        if (processors != null)
        {
            this.processors.addAll(processors);
        }
        return this;
    }

    public DefaultMessageProcessorChainBuilder chain(MessageProcessorBuilder... builders)
    {
        for (MessageProcessorBuilder messageProcessorBuilder : builders)
        {
            this.processors.add(messageProcessorBuilder);
        }
        return this;
    }

    public DefaultMessageProcessorChainBuilder chainBefore(MessageProcessor processor)
    {
        this.processors.add(0, processor);
        return this;
    }

    public DefaultMessageProcessorChainBuilder chainBefore(MessageProcessorBuilder builder)
    {
        this.processors.add(0, builder);
        return this;
    }
}
TOP

Related Classes of org.mule.processor.chain.DefaultMessageProcessorChainBuilder

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.