View Javadoc

1   /*
2    * $Id: FilteringOutboundRouter.java 7976 2007-08-21 14:26:13Z dirk.olmes $
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             if (logger.isDebugEnabled())
155             {
156                 logger.debug("Uri before parsing is: " + uri);
157             }
158             Map props = new HashMap();
159             // Also add the endpoint propertie so that users can set fallback values
160             // when the property is not set on the event
161             props.putAll(ep.getProperties());
162             for (Iterator iterator = message.getPropertyNames().iterator(); iterator.hasNext();)
163             {
164                 String propertyKey = (String) iterator.next();
165                 props.put(propertyKey, message.getProperty(propertyKey));
166             }
167             String newUriString = parser.parse(props, uri);
168             if (logger.isDebugEnabled())
169             {
170                 logger.debug("Uri after parsing is: " + uri);
171             }
172             try
173             {
174                 UMOEndpointURI newUri = new MuleEndpointURI(newUriString);
175                 if (!newUri.getScheme().equalsIgnoreCase(ep.getEndpointURI().getScheme()))
176                 {
177                     throw new CouldNotRouteOutboundMessageException(
178                         CoreMessages.schemeCannotChangeForRouter(ep.getEndpointURI().getScheme(),
179                         newUri.getScheme()), message, ep);
180                 }
181                 ep.setEndpointURI(newUri);
182             }
183             catch (EndpointException e)
184             {
185                 throw new CouldNotRouteOutboundMessageException(
186                     CoreMessages.templateCausedMalformedEndpoint(uri, newUriString), 
187                     message, ep, e);
188             }
189 
190             return ep;
191         }
192     }
193 
194     public boolean isUseTemplates()
195     {
196         return useTemplates;
197     }
198 
199     public void setUseTemplates(boolean useTemplates)
200     {
201         this.useTemplates = useTemplates;
202     }
203 }