use of org.mule.runtime.core.internal.processor.ReferenceProcessor in project mule by mulesoft.
the class DefaultMessageProcessorChainBuilder method build.
/**
* 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
*/
@Override
public MessageProcessorChain build() {
LinkedList<Processor> tempList = new LinkedList<>();
final LinkedList<Processor> processorsForLifecycle = new LinkedList<>();
// Start from last but one message processor and work backwards
for (int i = processors.size() - 1; i >= 0; i--) {
Processor processor = initializeMessageProcessor(processors.get(i));
if (processor instanceof InterceptingMessageProcessor && (!(processor instanceof ReferenceProcessor) || ((ReferenceProcessor) processor).getReferencedProcessor() instanceof InterceptingMessageProcessor)) {
InterceptingMessageProcessor interceptingProcessor = (InterceptingMessageProcessor) processor;
// Processor is intercepting so we can't simply iterate
if (i + 1 < processors.size()) {
// Wrap processors in chain, unless single processor that is already a chain
final MessageProcessorChain innerChain = createSimpleChain(tempList, interceptingProcessor.isBlocking() ? of(BLOCKING_PROCESSING_STRATEGY_INSTANCE) : ofNullable(processingStrategy));
processorsForLifecycle.addFirst(innerChain);
interceptingProcessor.setListener(innerChain);
}
tempList = new LinkedList<>(singletonList(processor));
} else {
// Processor is not intercepting so we can invoke it using iteration
// (add to temp list)
tempList.addFirst(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
Processor head = tempList.size() == 1 ? tempList.get(0) : createSimpleChain(tempList, ofNullable(processingStrategy));
processorsForLifecycle.addFirst(head);
return createInterceptingChain(head, processors, processorsForLifecycle);
}
Aggregations