View Javadoc

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