View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.routing;
8   
9   import org.mule.DefaultMuleEvent;
10  import org.mule.DefaultMuleMessage;
11  import org.mule.api.MuleContext;
12  import org.mule.api.MuleEvent;
13  import org.mule.api.MuleException;
14  import org.mule.api.MuleMessage;
15  import org.mule.api.context.MuleContextAware;
16  import org.mule.api.routing.MessageInfoMapping;
17  import org.mule.api.routing.RouterResultsHandler;
18  import org.mule.processor.AbstractInterceptingMessageProcessor;
19  
20  import java.util.ArrayList;
21  import java.util.List;
22  
23  /**
24   * Splits a message invoking the next message processor one for each split part.
25   * Implementations must implement {@link #splitMessage(MuleEvent)} and determine how
26   * the message is split.
27   *
28   * <p>
29   * <b>EIP Reference:</b> <a href="http://www.eaipatterns.com/Sequencer.html">http://www.eaipatterns.com/Sequencer.html</a>
30   */
31  
32  public abstract class AbstractSplitter extends
33      AbstractInterceptingMessageProcessor implements MuleContextAware
34  {
35  
36      protected MuleContext muleContext;
37      protected RouterResultsHandler resultsHandler = new DefaultRouterResultsHandler();
38      protected CorrelationMode enableCorrelation = CorrelationMode.IF_NOT_SET;
39      protected MessageInfoMapping messageInfoMapping;
40  
41      public MuleEvent process(MuleEvent event) throws MuleException
42      {
43          if (isSplitRequired(event))
44          {
45              List<MuleMessage> parts = splitMessage(event);
46              if (parts.size() > 0)
47              {
48                  if (parts.size() <= 1)
49                  {
50                      logger.warn("Splitter only returned a single result. If this is not expected, please check your split expression");
51                  }
52                  return resultsHandler.aggregateResults(processParts(parts, event), event, muleContext);
53              }
54              else
55              {
56                  logger.warn("Splitter returned no results. If this is not expected, please check your split expression");
57                  return null;
58              }
59          }
60          else
61          {
62              return processNext(event);
63          }
64      }
65  
66      protected boolean isSplitRequired(MuleEvent event)
67      {
68          return true;
69      }
70  
71      protected abstract List<MuleMessage> splitMessage(MuleEvent event) throws MuleException;
72  
73      protected List<MuleEvent> processParts(List parts, MuleEvent event) throws MuleException
74      {
75          if (messageInfoMapping == null)
76          {
77              messageInfoMapping = event.getFlowConstruct().getMessageInfoMapping();
78          }
79          String correlationId = messageInfoMapping.getCorrelationId(
80              event.getMessage());
81          List<MuleEvent> resultEvents = new ArrayList<MuleEvent>();
82          int correlationSequence = 1;
83  
84          MuleMessage originalMessage = event.getMessage();
85          for (Object part : parts)
86          {
87              MuleMessage message;
88              if (part instanceof MuleMessage)
89              {
90                  message = (MuleMessage) part;
91              }
92              else
93              {               
94                  message = new DefaultMuleMessage(originalMessage, muleContext);
95                  message.setPayload(part);
96              }
97  
98              if (enableCorrelation != CorrelationMode.NEVER)
99              {
100                 boolean correlationSet = message.getCorrelationId() != null;
101                 if ((!correlationSet && (enableCorrelation == CorrelationMode.IF_NOT_SET))
102                     || (enableCorrelation == CorrelationMode.ALWAYS))
103                 {
104                     message.setCorrelationId(correlationId);
105                 }
106 
107                 // take correlation group size from the message properties, set by
108                 // concrete
109                 // message splitter implementations
110                 message.setCorrelationGroupSize(parts.size());
111                 message.setCorrelationSequence(correlationSequence++);
112             }
113             resultEvents.add(processNext(new DefaultMuleEvent(message, event)));
114         }
115         return resultEvents;
116     }
117 
118     public void setEnableCorrelation(CorrelationMode enableCorrelation)
119     {
120         this.enableCorrelation = enableCorrelation;
121     }
122 
123     public void setMuleContext(MuleContext context)
124     {
125         this.muleContext = context;
126     }
127 
128     public void setMessageInfoMapping(MessageInfoMapping messageInfoMapping)
129     {
130         this.messageInfoMapping = messageInfoMapping;
131     }
132 
133 }