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