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