Coverage Report - org.mule.routing.outbound.AbstractMessageSplitter
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractMessageSplitter
80%
33/41
68%
15/22
2.833
 
 1  
 /*
 2  
  * $Id: AbstractMessageSplitter.java 9327 2007-10-24 13:18:33Z holger $
 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.routing.outbound;
 12  
 
 13  
 import org.mule.config.MuleProperties;
 14  
 import org.mule.umo.UMOException;
 15  
 import org.mule.umo.UMOMessage;
 16  
 import org.mule.umo.UMOSession;
 17  
 import org.mule.umo.endpoint.UMOEndpoint;
 18  
 import org.mule.umo.routing.CouldNotRouteOutboundMessageException;
 19  
 import org.mule.umo.routing.RoutingException;
 20  
 
 21  
 import java.util.Iterator;
 22  
 import java.util.List;
 23  
 
 24  
 /**
 25  
  * <code>AbstractMessageSplitter</code> is an outbound Message Splitter used to
 26  
  * split the contents of a received message into sub parts that can be processed by
 27  
  * other components. Each Part is fired as a separate event to each endpoint on the
 28  
  * router. The endpoints can have filters on them to receive only certain message
 29  
  * parts.
 30  
  */
 31  6
 public abstract class AbstractMessageSplitter extends FilteringOutboundRouter
 32  
 {
 33  
     // Determines if the same endpoint will be matched multiple times until a
 34  
     // match is not found. This should be set by overriding classes.
 35  6
     protected boolean multimatch = true;
 36  
 
 37  
     // flag which, if true, makes the splitter honour settings such as remoteSync and
 38  
     // synchronous on the endpoint
 39  6
     protected boolean honorSynchronicity = false;
 40  
 
 41  
     public UMOMessage route(UMOMessage message, UMOSession session, boolean synchronous)
 42  
         throws RoutingException
 43  
     {
 44  10
         String correlationId = (String) propertyExtractor.getProperty(
 45  
             MuleProperties.MULE_CORRELATION_ID_PROPERTY, message);
 46  
 
 47  10
         this.initialise(message);
 48  
 
 49  
         UMOEndpoint endpoint;
 50  10
         UMOMessage result = null;
 51  10
         List list = getEndpoints();
 52  10
         int correlationSequence = 1;
 53  10
         for (Iterator iterator = list.iterator(); iterator.hasNext();)
 54  
         {
 55  26
             endpoint = (UMOEndpoint) iterator.next();
 56  26
             message = getMessagePart(message, endpoint);
 57  
             // TODO MULE-1378
 58  26
             if (message == null)
 59  
             {
 60  
                 // Log a warning if there are no messages for a given endpoint
 61  0
                 logger.warn("Message part is null for endpoint: " + endpoint.getEndpointURI().toString());
 62  
             }
 63  
 
 64  
             // We'll keep looping to get all messages for the current endpoint
 65  
             // before moving to the next endpoint
 66  
             // This can be turned off by setting the multimatch flag to false
 67  50
             while (message != null)
 68  
             {
 69  36
                 if (honorSynchronicity)
 70  
                 {
 71  0
                     synchronous = endpoint.isSynchronous();
 72  
                 }
 73  
                 try
 74  
                 {
 75  36
                     if (enableCorrelation != ENABLE_CORRELATION_NEVER)
 76  
                     {
 77  36
                         boolean correlationSet = message.getCorrelationId() != null;
 78  36
                         if (!correlationSet && (enableCorrelation == ENABLE_CORRELATION_IF_NOT_SET))
 79  
                         {
 80  36
                             message.setCorrelationId(correlationId);
 81  
                         }
 82  
 
 83  
                         // take correlation group size from the message
 84  
                         // properties, set by concrete message splitter
 85  
                         // implementations
 86  36
                         final int groupSize = message.getCorrelationGroupSize();
 87  36
                         message.setCorrelationGroupSize(groupSize);
 88  36
                         message.setCorrelationSequence(correlationSequence++);
 89  
                     }
 90  
 
 91  36
                     if (honorSynchronicity)
 92  
                     {
 93  0
                         message.setBooleanProperty(MuleProperties.MULE_REMOTE_SYNC_PROPERTY,
 94  
                             endpoint.isRemoteSync());
 95  
                     }
 96  
 
 97  36
                     if (synchronous)
 98  
                     {
 99  22
                         result = send(session, message, endpoint);
 100  
                     }
 101  
                     else
 102  
                     {
 103  14
                         dispatch(session, message, endpoint);
 104  
                     }
 105  
                 }
 106  0
                 catch (UMOException e)
 107  
                 {
 108  0
                     throw new CouldNotRouteOutboundMessageException(message, endpoint, e);
 109  36
                 }
 110  
 
 111  36
                 if (!multimatch)
 112  
                 {
 113  12
                     break;
 114  
                 }
 115  
 
 116  24
                 message = this.getMessagePart(message, endpoint);
 117  
             }
 118  
         }
 119  
 
 120  
         // we are done with splitting & routing
 121  10
         this.cleanup();
 122  
 
 123  10
         return result;
 124  
     }
 125  
 
 126  
     /**
 127  
      * This method can be implemented to split the message up before
 128  
      * {@link #getMessagePart(UMOMessage, UMOEndpoint)} method is called.
 129  
      * 
 130  
      * @param message the message being routed
 131  
      */
 132  
     protected void initialise(UMOMessage message)
 133  
     {
 134  
         // nothing to do; subclasses need to implement this
 135  6
     }
 136  
 
 137  
     /**
 138  
      * This method is called after all parts of the original message have been processed;
 139  
      * typically this is the case after {@link #getMessagePart(UMOMessage, UMOEndpoint)}
 140  
      * returned <code>null</code>.
 141  
      */
 142  
     protected void cleanup()
 143  
     {
 144  
         // nothing to do; subclasses need to implement this
 145  
 
 146  
         // MULE-2600 note: this method (as well as initialise()) should be abstract to force
 147  
         // proper implementation by the subclass, but doing so would break compatibility with
 148  
         // exisiting custom splitters..
 149  10
     }
 150  
 
 151  
     public boolean isHonorSynchronicity()
 152  
     {
 153  0
         return honorSynchronicity;
 154  
     }
 155  
 
 156  
     /**
 157  
      * Sets the flag indicating whether the splitter honurs endpoint settings
 158  
      * 
 159  
      * @param honorSynchronicity flag setting
 160  
      */
 161  
     public void setHonorSynchronicity(boolean honorSynchronicity)
 162  
     {
 163  0
         this.honorSynchronicity = honorSynchronicity;
 164  0
     }
 165  
 
 166  
     /**
 167  
      * Retrieves a specific message part for the given endpoint. the message will
 168  
      * then be routed via the provider. <p/> <strong>NOTE:</strong>Implementations
 169  
      * must provide proper synchronization for shared state (payload, properties,
 170  
      * etc.)
 171  
      * 
 172  
      * @param message the current message being processed
 173  
      * @param endpoint the endpoint that will be used to route the resulting message
 174  
      *            part
 175  
      * @return the message part to dispatch
 176  
      */
 177  
     protected abstract UMOMessage getMessagePart(UMOMessage message, UMOEndpoint endpoint);
 178  
 }