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