View Javadoc

1   /*
2    * $Id: AbstractRecipientList.java 7976 2007-08-21 14:26:13Z dirk.olmes $
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.impl.MuleMessage;
14  import org.mule.impl.endpoint.MuleEndpoint;
15  import org.mule.umo.UMOException;
16  import org.mule.umo.UMOMessage;
17  import org.mule.umo.UMOSession;
18  import org.mule.umo.endpoint.UMOEndpoint;
19  import org.mule.umo.routing.CouldNotRouteOutboundMessageException;
20  import org.mule.umo.routing.RoutingException;
21  
22  import java.util.ArrayList;
23  import java.util.Iterator;
24  import java.util.List;
25  
26  import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
27  import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentMap;
28  import org.apache.commons.logging.Log;
29  import org.apache.commons.logging.LogFactory;
30  
31  /**
32   * <code>AbstractRecipientList</code> is used to dispatch a single event to
33   * multiple recipients over the same transport. The recipient endpoints can be
34   * configured statically or can be obtained from the message payload.
35   */
36  
37  public abstract class AbstractRecipientList extends FilteringOutboundRouter
38  {
39      /**
40       * logger used by this class
41       */
42      protected final Log logger = LogFactory.getLog(getClass());
43  
44      private final ConcurrentMap recipientCache = new ConcurrentHashMap();
45  
46      public UMOMessage route(UMOMessage message, UMOSession session, boolean synchronous)
47          throws RoutingException
48      {
49          List recipients = this.getRecipients(message);
50          List results = new ArrayList();
51  
52          if (enableCorrelation != ENABLE_CORRELATION_NEVER)
53          {
54              boolean correlationSet = message.getCorrelationGroupSize() != -1;
55              if (correlationSet && (enableCorrelation == ENABLE_CORRELATION_IF_NOT_SET))
56              {
57                  logger.debug("CorrelationId is already set, not setting Correlation group size");
58              }
59              else
60              {
61                  // the correlationId will be set by the AbstractOutboundRouter
62                  message.setCorrelationGroupSize(recipients.size());
63              }
64          }
65  
66          UMOMessage result = null;
67          UMOEndpoint endpoint;
68          UMOMessage request;
69  
70          for (Iterator iterator = recipients.iterator(); iterator.hasNext();)
71          {
72              String recipient = (String) iterator.next();
73              // Make a copy of the message. Question is do we do a proper clone? in
74              // which case there
75              // would potentially be multiple messages with the same id...
76              request = new MuleMessage(message.getPayload(), message);
77              endpoint = this.getRecipientEndpoint(request, recipient);
78  
79              try
80              {
81                  if (synchronous)
82                  {
83                      result = this.send(session, request, endpoint);
84                      if (result != null)
85                      {
86                          results.add(result.getPayload());
87                      }
88                      else
89                      {
90                          if (logger.isDebugEnabled())
91                          {
92                              logger.debug("No result was returned for sync call to: "
93                                              + endpoint.getEndpointURI());
94                          }
95                      }
96                  }
97                  else
98                  {
99                      this.dispatch(session, request, endpoint);
100                 }
101             }
102             catch (UMOException e)
103             {
104                 throw new CouldNotRouteOutboundMessageException(request, endpoint, e);
105             }
106         }
107 
108         if (results.size() == 0)
109         {
110             return null;
111         }
112         else if (results.size() == 1)
113         {
114             return new MuleMessage(results.get(0), result);
115         }
116         else
117         {
118             return new MuleMessage(results, result);
119         }
120     }
121 
122     protected UMOEndpoint getRecipientEndpoint(UMOMessage message, String recipient) throws RoutingException
123     {
124         UMOEndpoint endpoint = (UMOEndpoint) recipientCache.get(recipient);
125 
126         if (endpoint != null)
127         {
128             return endpoint;
129         }
130 
131         try
132         {
133             endpoint = MuleEndpoint.getOrCreateEndpointForUri(recipient, UMOEndpoint.ENDPOINT_TYPE_SENDER);
134         }
135         catch (UMOException e)
136         {
137             throw new RoutingException(message, endpoint, e);
138         }
139 
140         UMOEndpoint existingEndpoint = (UMOEndpoint) recipientCache.putIfAbsent(recipient, endpoint);
141         if (existingEndpoint != null)
142         {
143             endpoint = existingEndpoint;
144         }
145 
146         return endpoint;
147     }
148 
149     protected abstract List getRecipients(UMOMessage message);
150 
151     public boolean isDynamicEndpoints()
152     {
153         return true;
154     }
155 
156 }