1
2
3
4
5
6
7
8
9
10
11 package org.mule.routing.outbound;
12
13 import org.mule.config.MuleProperties;
14 import org.mule.impl.MuleMessage;
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.HashMap;
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.Map;
26
27 import org.dom4j.Document;
28
29
30
31
32
33 public class RoundRobinXmlSplitter extends FilteringXmlMessageSplitter
34 {
35
36
37 protected volatile boolean enableEndpointFiltering = false;
38
39
40 public UMOMessage route(UMOMessage message, UMOSession session, boolean synchronous)
41 throws RoutingException
42 {
43 try
44 {
45 String correlationId = (String)propertyExtractor.getProperty(
46 MuleProperties.MULE_CORRELATION_ID_PROPERTY, message);
47
48 this.initialise(message);
49
50 UMOEndpoint endpoint;
51 UMOMessage result = null;
52 Document part;
53
54 List parts = (List)nodesContext.get();
55
56 if (parts == null)
57 {
58 logger.error("There are no parts for current message. No events were routed: " + message);
59 return null;
60 }
61
62 int correlationSequence = 1;
63 int epCounter = 0;
64
65 for (Iterator iterator = parts.iterator(); iterator.hasNext(); epCounter++)
66 {
67 part = (Document)iterator.next();
68 if (epCounter == endpoints.size())
69 {
70 epCounter = 0;
71 }
72
73 Map theProperties = (Map)propertiesContext.get();
74 message = new MuleMessage(part, new HashMap(theProperties));
75
76 if (enableEndpointFiltering)
77 {
78 endpoint = getEndpointForMessage(message);
79 }
80 else
81 {
82 endpoint = (UMOEndpoint)getEndpoints().get(epCounter);
83 }
84
85 if (endpoint == null)
86 {
87 logger.error("There was no matching endpoint for message part: " + part.asXML());
88 }
89 else
90 {
91 try
92 {
93 if (enableCorrelation != ENABLE_CORRELATION_NEVER)
94 {
95 boolean correlationSet = message.getCorrelationId() != null;
96 if (!correlationSet && (enableCorrelation == ENABLE_CORRELATION_IF_NOT_SET))
97 {
98 message.setCorrelationId(correlationId);
99 }
100
101
102
103
104 final int groupSize = message.getCorrelationGroupSize();
105 message.setCorrelationGroupSize(groupSize);
106 message.setCorrelationSequence(correlationSequence++);
107 }
108 if (synchronous)
109 {
110 result = send(session, message, endpoint);
111 }
112 else
113 {
114 dispatch(session, message, endpoint);
115 }
116 }
117 catch (UMOException e)
118 {
119 throw new CouldNotRouteOutboundMessageException(message, endpoint, e);
120 }
121 }
122 }
123 return result;
124 }
125 finally
126 {
127 nodesContext.set(null);
128 propertiesContext.set(null);
129 }
130 }
131
132
133
134
135
136
137
138
139 protected UMOEndpoint getEndpointForMessage(UMOMessage message)
140 {
141 for (int i = 0; i < endpoints.size(); i++)
142 {
143 UMOEndpoint endpoint = (UMOEndpoint)endpoints.get(i);
144
145 try
146 {
147 if (endpoint.getFilter() == null || endpoint.getFilter().accept(message))
148 {
149 if (logger.isDebugEnabled())
150 {
151 logger.debug("Endpoint filter matched for node " + i + ". Routing message over: "
152 + endpoint.getEndpointURI().toString());
153 }
154 return endpoint;
155 }
156 else
157 {
158 if (logger.isDebugEnabled())
159 {
160 logger.debug("Endpoint filter did not match");
161 }
162 }
163 }
164 catch (Exception e)
165 {
166 logger.error("Unable to create message for node at position " + i, e);
167 return null;
168 }
169 }
170
171 return null;
172 }
173
174 public void addEndpoint(UMOEndpoint endpoint)
175 {
176 if (endpoint.getFilter() != null && !enableEndpointFiltering)
177 {
178 throw new IllegalStateException(
179 "Endpoints on the RoundRobin splitter router cannot have filters associated with them");
180 }
181 super.addEndpoint(endpoint);
182 }
183
184 public boolean isEnableEndpointFiltering()
185 {
186 return enableEndpointFiltering;
187 }
188
189 public void setEnableEndpointFiltering(boolean enableEndpointFiltering)
190 {
191 this.enableEndpointFiltering = enableEndpointFiltering;
192 }
193 }