1
2
3
4
5
6
7
8
9
10
11 package org.mule.routing;
12
13 import org.mule.DefaultMuleMessage;
14 import org.mule.OptimizedRequestContext;
15 import org.mule.api.MessagingException;
16 import org.mule.api.MuleEvent;
17 import org.mule.api.MuleException;
18 import org.mule.api.MuleMessage;
19 import org.mule.api.MuleSession;
20 import org.mule.api.lifecycle.Disposable;
21 import org.mule.api.lifecycle.Initialisable;
22 import org.mule.api.lifecycle.InitialisationException;
23 import org.mule.api.processor.MessageProcessor;
24 import org.mule.api.routing.MatchableMessageProcessor;
25 import org.mule.api.routing.MatchingRouter;
26 import org.mule.api.routing.TransformingMatchable;
27 import org.mule.config.i18n.CoreMessages;
28
29 import java.util.Iterator;
30 import java.util.List;
31
32 import edu.emory.mathcs.backport.java.util.concurrent.CopyOnWriteArrayList;
33
34 import org.apache.commons.logging.Log;
35 import org.apache.commons.logging.LogFactory;
36
37
38
39
40
41
42 public class AbstractMatchingRouter implements MatchingRouter
43 {
44
45
46
47 protected final transient Log logger = LogFactory.getLog(getClass());
48
49 @SuppressWarnings("unchecked")
50 protected List<MatchableMessageProcessor> matchableRoutes = new CopyOnWriteArrayList();
51 protected boolean matchAll = false;
52 protected MessageProcessor defaultRoute;
53
54 public MuleEvent process(MuleEvent event) throws MuleException
55 {
56 MuleMessage message = event.getMessage();
57 MuleSession session = event.getSession();
58 MuleEvent result;
59 boolean matchfound = false;
60
61 for (Iterator iterator = matchableRoutes.iterator(); iterator.hasNext();)
62 {
63 MatchableMessageProcessor outboundRouter = (MatchableMessageProcessor) iterator.next();
64
65 final MuleEvent eventToRoute;
66
67 boolean copyEvent = false;
68
69
70
71 if (iterator.hasNext())
72 {
73 if (isMatchAll())
74 {
75 copyEvent = true;
76 }
77 else if (outboundRouter instanceof TransformingMatchable)
78 {
79 copyEvent = ((TransformingMatchable) outboundRouter).isTransformBeforeMatch();
80 }
81 }
82
83 if (copyEvent)
84 {
85 if (((DefaultMuleMessage) message).isConsumable())
86 {
87 throw new MessagingException(CoreMessages.cannotCopyStreamPayload(message.getPayload().getClass().getName()), event);
88 }
89 eventToRoute = OptimizedRequestContext.criticalSetEvent(event);
90 }
91 else
92 {
93 eventToRoute = event;
94 }
95
96 if (outboundRouter.isMatch(eventToRoute.getMessage()))
97 {
98 matchfound = true;
99 result = outboundRouter.process(event);
100 if (!isMatchAll())
101 {
102 return result;
103 }
104 }
105 }
106
107 if (!matchfound && defaultRoute != null)
108 {
109 if (logger.isDebugEnabled())
110 {
111 logger.debug("Message did not match any routers on: " + session.getFlowConstruct().getName()
112 + " invoking catch all strategy");
113 }
114 return processDefaultRoute(event);
115 }
116 else if (!matchfound)
117 {
118 logger.warn("Message did not match any routers on: "
119 + session.getFlowConstruct().getName()
120 + " and there is no catch all strategy configured on this router. Disposing message "
121 + message);
122 }
123 return event;
124 }
125
126 protected MuleEvent processDefaultRoute(MuleEvent event) throws MuleException
127 {
128 return defaultRoute.process(event);
129 }
130
131 public boolean isMatchAll()
132 {
133 return matchAll;
134 }
135
136 public void setMatchAll(boolean matchAll)
137 {
138 this.matchAll = matchAll;
139 }
140
141 public void addRoute(MatchableMessageProcessor matchable)
142 {
143 matchableRoutes.add(matchable);
144 }
145
146 public void removeRoute(MatchableMessageProcessor matchable)
147 {
148 matchableRoutes.remove(matchable);
149 }
150
151 public void setDefaultRoute(MessageProcessor defaultRoute)
152 {
153 this.defaultRoute = defaultRoute;
154 }
155
156 public List<MatchableMessageProcessor> getRoutes()
157 {
158 return matchableRoutes;
159 }
160
161 public MessageProcessor getDefaultRoute()
162 {
163 return defaultRoute;
164 }
165
166 public void initialise() throws InitialisationException
167 {
168 for (MatchableMessageProcessor route : matchableRoutes)
169 {
170 if (route instanceof Initialisable)
171 {
172 ((Initialisable) route).initialise();
173 }
174 }
175 }
176
177 public void dispose()
178 {
179 for (MatchableMessageProcessor route : matchableRoutes)
180 {
181 if (route instanceof Disposable)
182 {
183 ((Disposable) route).dispose();
184 }
185 }
186 }
187
188 }