View Javadoc

1   /*
2    * $Id: FilteringOutboundRouter.java 9734 2007-11-16 13:13:24Z holger $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.routing.outbound;
12  
13  import org.mule.config.i18n.CoreMessages;
14  import org.mule.impl.MuleMessage;
15  import org.mule.impl.endpoint.MuleEndpointURI;
16  import org.mule.umo.UMOException;
17  import org.mule.umo.UMOFilter;
18  import org.mule.umo.UMOMessage;
19  import org.mule.umo.UMOSession;
20  import org.mule.umo.endpoint.EndpointException;
21  import org.mule.umo.endpoint.UMOEndpoint;
22  import org.mule.umo.endpoint.UMOEndpointURI;
23  import org.mule.umo.routing.CouldNotRouteOutboundMessageException;
24  import org.mule.umo.routing.RoutePathNotFoundException;
25  import org.mule.umo.routing.RoutingException;
26  import org.mule.umo.transformer.TransformerException;
27  import org.mule.umo.transformer.UMOTransformer;
28  import org.mule.util.TemplateParser;
29  
30  import java.util.HashMap;
31  import java.util.Iterator;
32  import java.util.Map;
33  
34  /**
35   * <code>FilteringRouter</code> is a router that accepts events based on a filter
36   * set.
37   */
38  
39  public class FilteringOutboundRouter extends AbstractOutboundRouter
40  {
41      private UMOTransformer transformer;
42  
43      private UMOFilter filter;
44  
45      private boolean useTemplates = false;
46  
47      // We used Square templates as they can exist as part of an URI.
48      private TemplateParser parser = TemplateParser.createSquareBracesStyleParser();
49  
50      public UMOMessage route(UMOMessage message, UMOSession session, boolean synchronous)
51          throws RoutingException
52      {
53          UMOMessage result = null;
54  
55          if (endpoints == null || endpoints.size() == 0)
56          {
57              throw new RoutePathNotFoundException(CoreMessages.noEndpointsForRouter(), message, null);
58          }
59  
60          UMOEndpoint ep = getEndpoint(0, message);
61  
62          try
63          {
64              if (synchronous)
65              {
66                  result = send(session, message, ep);
67              }
68              else
69              {
70                  dispatch(session, message, ep);
71              }
72          }
73          catch (UMOException e)
74          {
75              throw new CouldNotRouteOutboundMessageException(message, ep, e);
76          }
77          return result;
78      }
79  
80      public UMOFilter getFilter()
81      {
82          return filter;
83      }
84  
85      public void setFilter(UMOFilter filter)
86      {
87          this.filter = filter;
88      }
89  
90      public boolean isMatch(UMOMessage message) throws RoutingException
91      {
92          if (getFilter() == null)
93          {
94              return true;
95          }
96          if (transformer != null)
97          {
98              try
99              {
100                 Object payload = transformer.transform(message.getPayload());
101                 message = new MuleMessage(payload, message);
102             }
103             catch (TransformerException e)
104             {
105                 throw new RoutingException(
106                     CoreMessages.transformFailedBeforeFilter(),
107                     message, (UMOEndpoint) endpoints.get(0), e);
108             }
109         }
110         return getFilter().accept(message);
111     }
112 
113     public UMOTransformer getTransformer()
114     {
115         return transformer;
116     }
117 
118     public void setTransformer(UMOTransformer transformer)
119     {
120         this.transformer = transformer;
121     }
122 
123     public void addEndpoint(UMOEndpoint endpoint)
124     {
125         if (!useTemplates && parser.isContainsTemplate(endpoint.getEndpointURI().toString()))
126         {
127             useTemplates = true;
128         }
129         super.addEndpoint(endpoint);
130     }
131 
132     /**
133      * Will Return the endpont at the given index and will resolve any template tags
134      * on the Endpoint URI if necessary
135      * 
136      * @param index the index of the endpoint to get
137      * @param message the current message. This is required if template matching is
138      *            being used
139      * @return the endpoint at the index, with any template tags resolved
140      * @throws CouldNotRouteOutboundMessageException if the template causs the
141      *             endpoint to become illegal or malformed
142      */
143     public UMOEndpoint getEndpoint(int index, UMOMessage message)
144         throws CouldNotRouteOutboundMessageException
145     {
146         if (!useTemplates)
147         {
148             return (UMOEndpoint) endpoints.get(index);
149         }
150         else
151         {
152             UMOEndpoint ep = (UMOEndpoint) endpoints.get(index);
153             String uri = ep.getEndpointURI().toString();
154 
155             if (logger.isDebugEnabled())
156             {
157                 logger.debug("Uri before parsing is: " + uri);
158             }
159 
160             Map props = new HashMap();
161             // Also add the endpoint propertie so that users can set fallback values
162             // when the property is not set on the event
163             props.putAll(ep.getProperties());
164             for (Iterator iterator = message.getPropertyNames().iterator(); iterator.hasNext();)
165             {
166                 String propertyKey = (String) iterator.next();
167                 props.put(propertyKey, message.getProperty(propertyKey));
168             }
169 
170             String newUriString = parser.parse(props, uri);
171             if (logger.isDebugEnabled())
172             {
173                 logger.debug("Uri after parsing is: " + uri);
174             }
175 
176             try
177             {
178                 UMOEndpointURI newUri = new MuleEndpointURI(newUriString);
179                 if (!newUri.getScheme().equalsIgnoreCase(ep.getEndpointURI().getScheme()))
180                 {
181                     throw new CouldNotRouteOutboundMessageException(CoreMessages.schemeCannotChangeForRouter(
182                         ep.getEndpointURI().getScheme(), newUri.getScheme()), message, ep);
183                 }
184                 // dispatch to a clone of the endpoint, don't modify the original
185                 UMOEndpoint resolvedEndpoint = (UMOEndpoint) ep.clone();
186                 resolvedEndpoint.setEndpointURI(newUri);
187                 return resolvedEndpoint;
188             }
189             catch (EndpointException e)
190             {
191                 throw new CouldNotRouteOutboundMessageException(
192                     CoreMessages.templateCausedMalformedEndpoint(uri, newUriString), 
193                     message, ep, e);
194             }
195         }
196     }
197 
198     public boolean isUseTemplates()
199     {
200         return useTemplates;
201     }
202 
203     public void setUseTemplates(boolean useTemplates)
204     {
205         this.useTemplates = useTemplates;
206     }
207 }