1
2
3
4
5
6
7
8
9
10
11 package org.mule.routing.outbound;
12
13 import org.mule.DefaultMuleMessage;
14 import org.mule.api.MessagingException;
15 import org.mule.api.MuleContext;
16 import org.mule.api.MuleEvent;
17 import org.mule.api.MuleMessage;
18 import org.mule.api.MuleSession;
19 import org.mule.api.lifecycle.Disposable;
20 import org.mule.api.lifecycle.Initialisable;
21 import org.mule.api.lifecycle.InitialisationException;
22 import org.mule.api.routing.MatchableMessageProcessor;
23 import org.mule.api.routing.OutboundRouter;
24 import org.mule.api.routing.OutboundRouterCatchAllStrategy;
25 import org.mule.api.routing.OutboundRouterCollection;
26 import org.mule.api.routing.RouterStatisticsRecorder;
27 import org.mule.api.routing.RoutingException;
28 import org.mule.api.routing.TransformingMatchable;
29 import org.mule.config.i18n.CoreMessages;
30 import org.mule.management.stats.RouterStatistics;
31 import org.mule.routing.AbstractCatchAllStrategy;
32 import org.mule.util.ObjectUtils;
33
34 import java.util.Iterator;
35 import java.util.List;
36
37 import edu.emory.mathcs.backport.java.util.concurrent.CopyOnWriteArrayList;
38
39 import org.apache.commons.logging.Log;
40 import org.apache.commons.logging.LogFactory;
41
42
43
44
45
46
47
48
49 public class DefaultOutboundRouterCollection implements OutboundRouterCollection
50 {
51
52
53
54
55 protected final transient Log logger = LogFactory.getLog(getClass());
56
57 @SuppressWarnings("unchecked")
58 protected List<MatchableMessageProcessor> routers = new CopyOnWriteArrayList();
59 protected boolean matchAll = false;
60 private OutboundRouterCatchAllStrategy catchAllStrategy;
61
62 protected RouterStatistics statistics = new RouterStatistics(RouterStatistics.TYPE_OUTBOUND);
63 protected MuleContext muleContext;
64
65 public MuleEvent process(final MuleEvent event) throws MessagingException
66 {
67 MuleMessage message = event.getMessage();
68 MuleSession session = event.getSession();
69 MuleEvent result;
70 boolean matchfound = false;
71
72 for (Iterator<MatchableMessageProcessor> iterator = getRoutes().iterator(); iterator.hasNext();)
73 {
74 OutboundRouter outboundRouter = (OutboundRouter) iterator.next();
75
76 final MuleMessage outboundRouterMessage;
77
78
79
80 if (iterator.hasNext()
81 && (isMatchAll() || ((outboundRouter instanceof TransformingMatchable) && ((TransformingMatchable) outboundRouter).isTransformBeforeMatch())))
82 {
83 if (((DefaultMuleMessage) message).isConsumable())
84 {
85 throw new MessagingException(CoreMessages.cannotCopyStreamPayload(message.getPayload()
86 .getClass()
87 .getName()), event);
88 }
89 outboundRouterMessage = new DefaultMuleMessage(message.getPayload(), message, muleContext);
90 }
91 else
92 {
93 outboundRouterMessage = message;
94 }
95
96 try
97 {
98 if (outboundRouter.isMatch(outboundRouterMessage))
99 {
100 matchfound = true;
101
102 final OutboundRouter router = outboundRouter;
103
104 result = router.process(event);
105
106 if (!isMatchAll())
107 {
108 return result;
109 }
110 }
111 }
112 catch (MessagingException e)
113 {
114 throw e;
115 }
116 catch (Exception e)
117 {
118 throw new RoutingException(event, outboundRouter, e);
119 }
120 }
121
122 if (!matchfound && getCatchAllStrategy() != null)
123 {
124 if (logger.isDebugEnabled())
125 {
126 logger.debug("Message did not match any routers on: " + session.getFlowConstruct().getName()
127 + " invoking catch all strategy");
128 }
129 return catchAll(event);
130 }
131 else if (!matchfound)
132 {
133 logger.warn("Message did not match any routers on: "
134 + session.getFlowConstruct().getName()
135 + " and there is no catch all strategy configured on this router. Disposing message "
136 + message);
137 }
138 return event;
139 }
140
141 protected MuleEvent catchAll(MuleEvent event) throws RoutingException
142 {
143 if (getRouterStatistics().isEnabled())
144 {
145 getRouterStatistics().incrementCaughtMessage();
146 }
147
148 return getCatchAllStrategy().process(event);
149 }
150
151 public void initialise() throws InitialisationException
152 {
153 for (MatchableMessageProcessor router : routers)
154 {
155 if (router instanceof Initialisable)
156 {
157 ((Initialisable) router).initialise();
158 }
159 }
160 }
161
162 public void dispose()
163 {
164 for (MatchableMessageProcessor router : routers)
165 {
166 if (router instanceof Disposable)
167 {
168 ((Disposable) router).dispose();
169 }
170 }
171 }
172
173
174 @Deprecated
175 public void setMessageProcessors(List<MatchableMessageProcessor> routers)
176 {
177 for (MatchableMessageProcessor router : routers)
178 {
179 addRoute(router);
180 }
181 }
182
183 public void addRoute(MatchableMessageProcessor router)
184 {
185 if (router instanceof RouterStatisticsRecorder)
186 {
187 ((RouterStatisticsRecorder) router).setRouterStatistics(getRouterStatistics());
188 }
189 routers.add(router);
190 }
191
192 public void removeRoute(MatchableMessageProcessor router)
193 {
194 routers.remove(router);
195 }
196
197 public List<MatchableMessageProcessor> getRoutes()
198 {
199 return routers;
200 }
201
202 public OutboundRouterCatchAllStrategy getCatchAllStrategy()
203 {
204 return catchAllStrategy;
205 }
206
207 public void setCatchAllStrategy(OutboundRouterCatchAllStrategy catchAllStrategy)
208 {
209 this.catchAllStrategy = catchAllStrategy;
210 if (this.catchAllStrategy != null && catchAllStrategy instanceof AbstractCatchAllStrategy)
211 {
212 ((AbstractCatchAllStrategy) this.catchAllStrategy).setRouterStatistics(statistics);
213 }
214 }
215
216 public boolean isMatchAll()
217 {
218 return matchAll;
219 }
220
221 public void setMatchAll(boolean matchAll)
222 {
223 this.matchAll = matchAll;
224 }
225
226 public RouterStatistics getRouterStatistics()
227 {
228 return statistics;
229 }
230
231 public void setRouterStatistics(RouterStatistics stat)
232 {
233 this.statistics = stat;
234 }
235
236 public void setMuleContext(MuleContext context)
237 {
238 this.muleContext = context;
239 }
240
241 public boolean hasEndpoints()
242 {
243 for (Iterator iterator = routers.iterator(); iterator.hasNext();)
244 {
245 OutboundRouter router = (OutboundRouter) iterator.next();
246 if (router.getRoutes().size() > 0 || router.isDynamicRoutes())
247 {
248 return true;
249 }
250 }
251 return false;
252 }
253
254 @Override
255 public String toString()
256 {
257 return ObjectUtils.toString(this);
258 }
259 }