View Javadoc

1   /*
2    * $Id: EndpointSelector.java 12269 2008-07-10 04:19:03Z 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.OutboundEndpoint;
17  import org.mule.api.routing.CouldNotRouteOutboundMessageException;
18  import org.mule.api.routing.RoutingException;
19  import org.mule.config.i18n.CoreMessages;
20  import org.mule.util.StringUtils;
21  import org.mule.util.expression.ExpressionEvaluatorManager;
22  
23  import java.util.ArrayList;
24  import java.util.Iterator;
25  import java.util.List;
26  
27  /**
28   * <code>EndpointSelector</code> selects the outgoing endpoint based on a
29   * an expression evaluator  ("header:endpoint" by default).  It will first try to match the
30   * endpoint by name and then by address.
31   * The endpoints to use can be set on the router itself or be global endpoint definitions.
32   * <pre>
33   *
34   * &lt;outbound&gt;
35   *      &lt;endpoint-selector-router evaluator="xpath" expression="/MSG/HEADER/NEXT-ADDRESS"&gt;
36   *          &lt;endpoint name="dest1" address="jms://queue1" /&gt;
37   *          &lt;endpoint name="dest2" address="jms://queue2" /&gt;
38   *          &lt;endpoint name="dest3" address="jms://queue3" /&gt;
39   *      &lt;/endpoint-selector-router&gt;
40   * &lt;/outbound&gt;
41   *
42   * </pre>
43   */
44  public class EndpointSelector extends FilteringOutboundRouter
45  {
46      public static final String DEFAULT_SELECTOR_EVALUATOR = "header";
47      public static final String DEFAULT_SELECTOR_EXPRESSION = "endpoint";
48  
49      private String expression = DEFAULT_SELECTOR_EXPRESSION;
50      private String evaluator = DEFAULT_SELECTOR_EVALUATOR;
51      private String customEvaluator;
52      private String fullExpression;
53  
54      public MuleMessage route(MuleMessage message, MuleSession session, boolean synchronous)
55          throws RoutingException
56      {
57          List endpoints;
58          String endpointName;
59  
60          String prop = getFullExpression();
61          if(!ExpressionEvaluatorManager.isValidExpression(prop))
62          {
63              throw new CouldNotRouteOutboundMessageException(
64                      CoreMessages.expressionInvalidForProperty("expression", prop), message, null);
65          }
66  
67          Object property = ExpressionEvaluatorManager.evaluate(prop, message);
68          if(property ==null)
69          {
70              throw new CouldNotRouteOutboundMessageException(
71                      CoreMessages.propertyIsNotSetOnEvent(getFullExpression()), message, null);
72          }
73  
74          if (property instanceof String)
75          {
76              endpoints = new ArrayList(1);
77              endpoints.add(property);
78          }
79          else if(property instanceof List)
80          {
81              endpoints = (List)property;
82          }
83          else
84          {
85              throw new CouldNotRouteOutboundMessageException(CoreMessages.propertyIsNotSupportedType(
86                      getFullExpression(), new Class[]{String.class, List.class}, property.getClass()), message, null);
87          }
88  
89          MuleMessage result = null;
90          for (Iterator iterator = endpoints.iterator(); iterator.hasNext();)
91          {
92              endpointName = iterator.next().toString();
93  
94              if(StringUtils.isEmpty(endpointName))
95              {
96                  throw new CouldNotRouteOutboundMessageException(
97                          CoreMessages.objectIsNull("Endpoint Name: " + getFullExpression()), message, null);
98              }
99              OutboundEndpoint ep = null;
100             try
101             {
102                 ep = lookupEndpoint(endpointName);
103                 if (ep == null)
104                 {
105                     throw new CouldNotRouteOutboundMessageException(CoreMessages.objectNotFound("Endpoint",
106                         endpointName), message, ep);
107                 }
108                 if (synchronous)
109                 {
110                     // TODO See MULE-2613, we only return the last message here
111                     result = send(session, message, ep);
112                 }
113                 else
114                 {
115                     dispatch(session, message, ep);
116                 }
117             }
118             catch (MuleException e)
119             {
120                 throw new CouldNotRouteOutboundMessageException(message, ep, e);
121             }
122         }
123         return result;
124     }
125 
126     protected OutboundEndpoint lookupEndpoint(String endpointName) throws MuleException
127     {
128         OutboundEndpoint ep;
129         Iterator iterator = endpoints.iterator();
130         while (iterator.hasNext())
131         {
132             ep = (OutboundEndpoint) iterator.next();
133             // Endpoint identifier (deprecated)
134             if (endpointName.equals(ep.getEndpointURI().getEndpointName()))
135             {
136                 return ep;
137             }
138             // Global endpoint
139             else if (endpointName.equals(ep.getName()))
140             {
141                 return ep;
142             }
143             else if (endpointName.equals(ep.getEndpointURI().getUri().toString()))
144             {
145                 return ep;
146             }
147         }
148         return getMuleContext().getRegistry().lookupEndpointFactory().getOutboundEndpoint(endpointName);
149     }
150 
151     public String getFullExpression()
152     {
153         if(fullExpression==null)
154         {
155             if(evaluator.equalsIgnoreCase("custom"))
156             {
157                 evaluator = customEvaluator;
158             }
159                 fullExpression = evaluator + ":" + expression;
160             logger.debug("Full expression for EndpointSelector is: " + fullExpression);
161         }
162         return fullExpression;
163     }
164 
165     public String getExpression()
166     {
167         return expression;
168     }
169 
170     public void setExpression(String expression)
171     {
172         this.expression = expression;
173     }
174 
175     public String getCustomEvaluator()
176     {
177         return customEvaluator;
178     }
179 
180     public void setCustomEvaluator(String customEvaluator)
181     {
182         this.customEvaluator = customEvaluator;
183     }
184 
185     public String getEvaluator()
186     {
187         return evaluator;
188     }
189 
190     public void setEvaluator(String evaluator)
191     {
192         this.evaluator = evaluator;
193     }
194 }