001: /*
002: * $Id: FilteringOutboundRouter.java 10961 2008-02-22 19:01:02Z dfeist $
003: * --------------------------------------------------------------------------------------
004: * Copyright (c) MuleSource, Inc. All rights reserved. http://www.mulesource.com
005: *
006: * The software in this package is published under the terms of the CPAL v1.0
007: * license, a copy of which has been included with this distribution in the
008: * LICENSE.txt file.
009: */
010:
011: package org.mule.routing.outbound;
012:
013: import org.mule.api.MuleException;
014: import org.mule.api.MuleMessage;
015: import org.mule.api.MuleSession;
016: import org.mule.api.endpoint.EndpointException;
017: import org.mule.api.endpoint.EndpointURI;
018: import org.mule.api.endpoint.ImmutableEndpoint;
019: import org.mule.api.endpoint.OutboundEndpoint;
020: import org.mule.api.routing.CouldNotRouteOutboundMessageException;
021: import org.mule.api.routing.RoutePathNotFoundException;
022: import org.mule.api.routing.RoutingException;
023: import org.mule.api.routing.filter.Filter;
024: import org.mule.api.transformer.TransformerException;
025: import org.mule.config.i18n.CoreMessages;
026: import org.mule.endpoint.DynamicURIOutboundEndpoint;
027: import org.mule.endpoint.MuleEndpointURI;
028: import org.mule.util.TemplateParser;
029:
030: import java.util.HashMap;
031: import java.util.Iterator;
032: import java.util.LinkedList;
033: import java.util.List;
034: import java.util.Map;
035:
036: /**
037: * <code>FilteringRouter</code> is a router that accepts events based on a filter
038: * set.
039: */
040:
041: public class FilteringOutboundRouter extends AbstractOutboundRouter {
042: private List transformers = new LinkedList();
043:
044: private Filter filter;
045:
046: private boolean useTemplates = false;
047:
048: // We used Square templates as they can exist as part of an URI.
049: private TemplateParser parser = TemplateParser
050: .createSquareBracesStyleParser();
051:
052: public MuleMessage route(MuleMessage message, MuleSession session,
053: boolean synchronous) throws RoutingException {
054: MuleMessage result = null;
055:
056: if (endpoints == null || endpoints.size() == 0) {
057: throw new RoutePathNotFoundException(CoreMessages
058: .noEndpointsForRouter(), message, null);
059: }
060:
061: OutboundEndpoint ep = getEndpoint(0, message);
062:
063: try {
064: if (synchronous) {
065: result = send(session, message, ep);
066: } else {
067: dispatch(session, message, ep);
068: }
069: } catch (MuleException e) {
070: throw new CouldNotRouteOutboundMessageException(message,
071: ep, e);
072: }
073: return result;
074: }
075:
076: public Filter getFilter() {
077: return filter;
078: }
079:
080: public void setFilter(Filter filter) {
081: this .filter = filter;
082: }
083:
084: public boolean isMatch(MuleMessage message) throws RoutingException {
085: if (getFilter() == null) {
086: return true;
087: }
088: try {
089: message.applyTransformers(transformers);
090: } catch (TransformerException e) {
091: throw new RoutingException(CoreMessages
092: .transformFailedBeforeFilter(), message,
093: (ImmutableEndpoint) endpoints.get(0), e);
094: }
095: return getFilter().accept(message);
096: }
097:
098: public List getTransformers() {
099: return transformers;
100: }
101:
102: public void setTransformers(List transformers) {
103: this .transformers = transformers;
104: }
105:
106: public void addEndpoint(OutboundEndpoint endpoint) {
107: if (!useTemplates
108: && parser.isContainsTemplate(endpoint.getEndpointURI()
109: .toString())) {
110: useTemplates = true;
111: }
112: super .addEndpoint(endpoint);
113: }
114:
115: /**
116: * Will Return the endpont at the given index and will resolve any template tags
117: * on the Endpoint URI if necessary
118: *
119: * @param index the index of the endpoint to get
120: * @param message the current message. This is required if template matching is
121: * being used
122: * @return the endpoint at the index, with any template tags resolved
123: * @throws CouldNotRouteOutboundMessageException if the template causs the
124: * endpoint to become illegal or malformed
125: */
126: public OutboundEndpoint getEndpoint(int index, MuleMessage message)
127: throws CouldNotRouteOutboundMessageException {
128: if (!useTemplates) {
129: return (OutboundEndpoint) endpoints.get(index);
130: } else {
131: OutboundEndpoint ep = (OutboundEndpoint) endpoints
132: .get(index);
133: String uri = ep.getEndpointURI().toString();
134:
135: if (logger.isDebugEnabled()) {
136: logger.debug("Uri before parsing is: " + uri);
137: }
138:
139: Map props = new HashMap();
140: // Also add the endpoint propertie so that users can set fallback values
141: // when the property is not set on the event
142: props.putAll(ep.getProperties());
143: for (Iterator iterator = message.getPropertyNames()
144: .iterator(); iterator.hasNext();) {
145: String propertyKey = (String) iterator.next();
146: props
147: .put(propertyKey, message
148: .getProperty(propertyKey));
149: }
150:
151: String newUriString = parser.parse(props, uri);
152: if (logger.isDebugEnabled()) {
153: logger.debug("Uri after parsing is: " + uri);
154: }
155:
156: try {
157: EndpointURI newUri = new MuleEndpointURI(newUriString);
158: if (!newUri.getScheme().equalsIgnoreCase(
159: ep.getEndpointURI().getScheme())) {
160: throw new CouldNotRouteOutboundMessageException(
161: CoreMessages.schemeCannotChangeForRouter(ep
162: .getEndpointURI().getScheme(),
163: newUri.getScheme()), message, ep);
164: }
165:
166: return new DynamicURIOutboundEndpoint(ep, newUri);
167: } catch (EndpointException e) {
168: throw new CouldNotRouteOutboundMessageException(
169: CoreMessages.templateCausedMalformedEndpoint(
170: uri, newUriString), message, ep, e);
171: }
172: }
173: }
174:
175: public boolean isUseTemplates() {
176: return useTemplates;
177: }
178:
179: public void setUseTemplates(boolean useTemplates) {
180: this.useTemplates = useTemplates;
181: }
182: }
|