View Javadoc

1   /*
2    * $Id: DefaultMessageProcessorChain.java 23069 2011-10-03 19:22:25Z pablo.lagreca $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.processor.chain;
12  
13  import org.mule.MessageExchangePattern;
14  import org.mule.OptimizedRequestContext;
15  import org.mule.api.MuleEvent;
16  import org.mule.api.MuleException;
17  import org.mule.api.component.Component;
18  import org.mule.api.construct.FlowConstruct;
19  import org.mule.api.endpoint.OutboundEndpoint;
20  import org.mule.api.processor.MessageProcessor;
21  import org.mule.api.processor.MessageProcessorChain;
22  import org.mule.api.processor.RequestReplyReplierMessageProcessor;
23  import org.mule.api.transformer.Transformer;
24  import org.mule.construct.Flow;
25  import org.mule.context.notification.MessageProcessorNotification;
26  import org.mule.routing.MessageFilter;
27  
28  import java.util.Arrays;
29  import java.util.Iterator;
30  import java.util.List;
31  
32  public class DefaultMessageProcessorChain extends AbstractMessageProcessorChain
33  {
34  
35      protected DefaultMessageProcessorChain(List<MessageProcessor> processors)
36      {   
37          super(null, processors);
38      }
39  
40      protected DefaultMessageProcessorChain(MessageProcessor... processors)
41      {
42          super(null, Arrays.asList(processors));
43      }
44  
45      protected DefaultMessageProcessorChain(String name, List<MessageProcessor> processors)
46      {
47          super(name, processors);
48      }
49  
50      protected DefaultMessageProcessorChain(String name, MessageProcessor... processors)
51      {
52          super(name, Arrays.asList(processors));
53      }
54  
55      public static MessageProcessorChain from(MessageProcessor messageProcessor)
56      {
57          return new DefaultMessageProcessorChain(messageProcessor);
58      }
59  
60      public static MessageProcessorChain from(MessageProcessor... messageProcessors) throws MuleException
61      {
62          return new DefaultMessageProcessorChainBuilder().chain(messageProcessors).build();
63      }
64  
65      public static MessageProcessorChain from(List<MessageProcessor> messageProcessors) throws MuleException
66      {
67          return new DefaultMessageProcessorChainBuilder().chain(messageProcessors).build();
68      }
69      
70      protected MuleEvent doProcess(MuleEvent event) throws MuleException
71      {
72          FlowConstruct flowConstruct = event.getFlowConstruct();
73          MuleEvent currentEvent = event;
74          MuleEvent resultEvent;
75          MuleEvent copy = null;
76          Iterator<MessageProcessor> processorIterator = processors.iterator();
77          MessageProcessor processor = null;
78          if (processorIterator.hasNext())
79          {
80              processor = processorIterator.next();
81          }
82          boolean resultWasNull = false;
83          while (processor != null)
84          {
85              MessageProcessor nextProcessor = null;
86              if (processorIterator.hasNext())
87              {
88                  nextProcessor = processorIterator.next();
89              }
90              fireNotification(event.getFlowConstruct(), event, processor,
91                  MessageProcessorNotification.MESSAGE_PROCESSOR_PRE_INVOKE);
92  
93              if (flowConstruct instanceof Flow && nextProcessor != null
94                  && processorMayReturnNull(processor))
95              {
96                  copy = OptimizedRequestContext.criticalSetEvent(currentEvent);
97              }
98  
99              resultEvent = processor.process(currentEvent);
100             if (resultWasNull && processor instanceof RequestReplyReplierMessageProcessor)
101             {
102                 // reply-to processing should not resurrect a dead event
103                 resultEvent = null;
104             }
105 
106             fireNotification(event.getFlowConstruct(), resultEvent, processor,
107                 MessageProcessorNotification.MESSAGE_PROCESSOR_POST_INVOKE);
108 
109 
110             if (resultEvent != null)
111             {
112                 resultWasNull = false;
113                 currentEvent = resultEvent;
114             }
115             else if (flowConstruct instanceof Flow && nextProcessor != null)
116             {
117                 resultWasNull = true;
118                 // // In a flow when a MessageProcessor returns null the next
119                 // processor acts as an implicit
120                 // // branch receiving a copy of the message used for previous
121                 // MessageProcessor
122                 if (copy != null)
123                 {
124                     currentEvent = copy;
125                 }
126                 else
127                 {
128                     // this should not happen
129                     currentEvent = OptimizedRequestContext.criticalSetEvent(currentEvent);
130                 }
131             }
132             else
133             {
134                 // But in a service we don't do any implicit branching.
135                 return null;
136             }
137             processor = nextProcessor;
138         }
139         return currentEvent;
140     }
141 
142     protected boolean processorMayReturnNull(MessageProcessor processor)
143     {
144         if (processor instanceof OutboundEndpoint)
145         {
146             MessageExchangePattern exchangePattern = ((OutboundEndpoint) processor).getExchangePattern();
147             return exchangePattern == null ? true : !exchangePattern.hasResponse();
148         }
149         else if (processor instanceof Component || processor instanceof Transformer
150                  || processor instanceof MessageFilter)
151         {
152             return false;
153         }
154         else
155         {
156             return true;
157         }
158     }
159 
160 }