View Javadoc

1   /*
2    * $Id: FilteringOutboundRouter.java 10961 2008-02-22 19:01:02Z dfeist $
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.api.MuleException;
14  import org.mule.api.MuleMessage;
15  import org.mule.api.MuleSession;
16  import org.mule.api.endpoint.EndpointException;
17  import org.mule.api.endpoint.EndpointURI;
18  import org.mule.api.endpoint.ImmutableEndpoint;
19  import org.mule.api.endpoint.OutboundEndpoint;
20  import org.mule.api.routing.CouldNotRouteOutboundMessageException;
21  import org.mule.api.routing.RoutePathNotFoundException;
22  import org.mule.api.routing.RoutingException;
23  import org.mule.api.routing.filter.Filter;
24  import org.mule.api.transformer.TransformerException;
25  import org.mule.config.i18n.CoreMessages;
26  import org.mule.endpoint.DynamicURIOutboundEndpoint;
27  import org.mule.endpoint.MuleEndpointURI;
28  import org.mule.util.TemplateParser;
29  
30  import java.util.HashMap;
31  import java.util.Iterator;
32  import java.util.LinkedList;
33  import java.util.List;
34  import java.util.Map;
35  
36  /**
37   * <code>FilteringRouter</code> is a router that accepts events based on a filter
38   * set.
39   */
40  
41  public class FilteringOutboundRouter extends AbstractOutboundRouter
42  {
43      private List transformers = new LinkedList();
44  
45      private Filter filter;
46  
47      private boolean useTemplates = false;
48  
49      // We used Square templates as they can exist as part of an URI.
50      private TemplateParser parser = TemplateParser.createSquareBracesStyleParser();
51  
52      public MuleMessage route(MuleMessage message, MuleSession session, boolean synchronous)
53          throws RoutingException
54      {
55          MuleMessage result = null;
56  
57          if (endpoints == null || endpoints.size() == 0)
58          {
59              throw new RoutePathNotFoundException(CoreMessages.noEndpointsForRouter(), message, null);
60          }
61  
62          OutboundEndpoint ep = getEndpoint(0, message);
63  
64          try
65          {
66              if (synchronous)
67              {
68                  result = send(session, message, ep);
69              }
70              else
71              {
72                  dispatch(session, message, ep);
73              }
74          }
75          catch (MuleException e)
76          {
77              throw new CouldNotRouteOutboundMessageException(message, ep, e);
78          }
79          return result;
80      }
81  
82      public Filter getFilter()
83      {
84          return filter;
85      }
86  
87      public void setFilter(Filter filter)
88      {
89          this.filter = filter;
90      }
91  
92      public boolean isMatch(MuleMessage message) throws RoutingException
93      {
94          if (getFilter() == null)
95          {
96              return true;
97          }
98          try
99          {
100             message.applyTransformers(transformers);
101         }
102         catch (TransformerException e)
103         {
104             throw new RoutingException(
105                     CoreMessages.transformFailedBeforeFilter(),
106                     message, (ImmutableEndpoint) endpoints.get(0), e);
107         }
108         return getFilter().accept(message);
109     }
110 
111     public List getTransformers()
112     {
113         return transformers;
114     }
115 
116     public void setTransformers(List transformers)
117     {
118         this.transformers = transformers;
119     }
120 
121     public void addEndpoint(OutboundEndpoint endpoint)
122     {
123         if (!useTemplates && parser.isContainsTemplate(endpoint.getEndpointURI().toString()))
124         {
125             useTemplates = true;
126         }
127         super.addEndpoint(endpoint);
128     }
129 
130     /**
131      * Will Return the endpont at the given index and will resolve any template tags
132      * on the Endpoint URI if necessary
133      * 
134      * @param index the index of the endpoint to get
135      * @param message the current message. This is required if template matching is
136      *            being used
137      * @return the endpoint at the index, with any template tags resolved
138      * @throws CouldNotRouteOutboundMessageException if the template causs the
139      *             endpoint to become illegal or malformed
140      */
141     public OutboundEndpoint getEndpoint(int index, MuleMessage message)
142         throws CouldNotRouteOutboundMessageException
143     {
144         if (!useTemplates)
145         {
146             return (OutboundEndpoint) endpoints.get(index);
147         }
148         else
149         {
150             OutboundEndpoint ep = (OutboundEndpoint) endpoints.get(index);
151             String uri = ep.getEndpointURI().toString();
152 
153             if (logger.isDebugEnabled())
154             {
155                 logger.debug("Uri before parsing is: " + uri);
156             }
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 
168             String newUriString = parser.parse(props, uri);
169             if (logger.isDebugEnabled())
170             {
171                 logger.debug("Uri after parsing is: " + uri);
172             }
173 
174             try
175             {
176                 EndpointURI newUri = new MuleEndpointURI(newUriString);
177                 if (!newUri.getScheme().equalsIgnoreCase(ep.getEndpointURI().getScheme()))
178                 {
179                     throw new CouldNotRouteOutboundMessageException(CoreMessages.schemeCannotChangeForRouter(
180                         ep.getEndpointURI().getScheme(), newUri.getScheme()), message, ep);
181                 }
182 
183                 return new DynamicURIOutboundEndpoint(ep, newUri);
184             }
185             catch (EndpointException e)
186             {
187                 throw new CouldNotRouteOutboundMessageException(
188                     CoreMessages.templateCausedMalformedEndpoint(uri, newUriString), 
189                     message, ep, e);
190             }
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 }