View Javadoc

1   /*
2    * $Id: MessagePropertyFilter.java 19191 2010-08-25 21:05:23Z tcarlson $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.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.filters;
12  
13  import org.mule.api.MuleMessage;
14  import org.mule.api.routing.filter.Filter;
15  import org.mule.api.transport.PropertyScope;
16  import org.mule.util.StringUtils;
17  
18  import org.apache.commons.logging.Log;
19  import org.apache.commons.logging.LogFactory;
20  
21  import static org.mule.util.ClassUtils.equal;
22  import static org.mule.util.ClassUtils.hash;
23  
24  /**
25   * <code>MessagePropertyFilter</code> can be used to filter against properties on
26   * an event. This can be very useful as the event properties represent all the meta
27   * information about the event from the underlying transport, so for an event
28   * received over HTTP you can check for HTTP headers etc. The pattern should be
29   * expressed as a key/value pair, i.e. "propertyName=value". If you want to compare
30   * more than one property you can use the logic filters for And, Or and Not
31   * expressions. By default the comparison is case sensitive; you can set the
32   * <i>caseSensitive</i> property to override this.
33   * <p/>
34   * Since 3.0.0 its possible to set the property value as a wildcard expression i.e.
35   * <p/>
36   * <pre>fooHeader = *foo*</pre>
37   */
38  public class MessagePropertyFilter implements Filter
39  {
40      /**
41       * logger used by this class
42       */
43      protected transient final Log logger = LogFactory.getLog(MessagePropertyFilter.class);
44      private boolean caseSensitive = true;
45      private boolean not = false;
46  
47      private String propertyName;
48      private String propertyValue;
49      private PropertyScope scope = PropertyScope.OUTBOUND;
50  
51      private WildcardFilter wildcardFilter;
52  
53      public MessagePropertyFilter()
54      {
55          super();
56      }
57  
58      public MessagePropertyFilter(String expression)
59      {
60          setPattern(expression);
61      }
62  
63      public boolean accept(MuleMessage message)
64      {
65          if (message == null)
66          {
67              return false;
68          }
69          Object value = message.getProperty(propertyName, scope);
70          boolean match;
71          if (value == null)
72          {
73              match = compare(null, propertyValue);
74          }
75          else
76          {
77              match = compare(value.toString(), propertyValue);
78          }
79          if (!match && logger.isDebugEnabled())
80          {
81              logger.debug(String.format("Property: '%s' not found in scope '%s'. Message %n%s", propertyName, scope, message));
82          }
83          return match;
84      }
85  
86      protected boolean compare(String value1, String value2)
87      {
88          if (value1 == null && value2 != null && !"null".equals(value2) && not)
89          {
90              return true;
91          }
92  
93          if (value1 == null)
94          {
95              value1 = "null";
96          }
97  
98  
99          boolean result;
100 
101         result = wildcardFilter.accept(value1);
102 
103         return (not ? !result : result);
104     }
105 
106     public String getPattern()
107     {
108         return propertyName + '=' + propertyValue;
109     }
110 
111     public void setPattern(String expression)
112     {
113         int x = expression.indexOf(":");
114         int i = expression.indexOf('=');
115 
116         if (i == -1)
117         {
118             throw new IllegalArgumentException(
119                     "Pattern is malformed - it should be a key value pair, i.e. property=value: " + expression);
120         }
121 
122         if (x > -1 && x < i)
123         {
124             setScope(expression.substring(0, x));
125             expression = expression.substring(x + 1);
126             i = expression.indexOf('=');
127         }
128 
129 
130         if (expression.charAt(i - 1) == '!')
131         {
132             not = true;
133             propertyName = expression.substring(0, i - 1).trim();
134         }
135         else
136         {
137             propertyName = expression.substring(0, i).trim();
138         }
139         propertyValue = expression.substring(i + 1).trim();
140 
141         wildcardFilter = new WildcardFilter(propertyValue);
142         wildcardFilter.setCaseSensitive(isCaseSensitive());
143     }
144 
145     public boolean isCaseSensitive()
146     {
147         return caseSensitive;
148     }
149 
150     public void setCaseSensitive(boolean caseSensitive)
151     {
152         this.caseSensitive = caseSensitive;
153         if (wildcardFilter != null)
154         {
155             wildcardFilter.setCaseSensitive(caseSensitive);
156         }
157     }
158 
159     public String getScope()
160     {
161         return scope.getScopeName();
162     }
163 
164     public void setScope(String scope)
165     {
166         if (StringUtils.isBlank(scope))
167         {
168             // ignore and use defaults
169             return;
170         }
171 
172         PropertyScope ps = PropertyScope.get(scope.toLowerCase().trim());
173         if (ps == null)
174         {
175             throw new IllegalArgumentException(String.format("'%s' is not a valid property scope.", scope));
176         }
177         this.scope = ps;
178     }
179 
180     public boolean equals(Object obj)
181     {
182         if (this == obj)
183         {
184             return true;
185         }
186         if (obj == null || getClass() != obj.getClass())
187         {
188             return false;
189         }
190 
191         final MessagePropertyFilter other = (MessagePropertyFilter) obj;
192         return equal(propertyName, other.propertyName)
193                 && equal(propertyValue, other.propertyValue)
194                 && equal(scope, other.scope)
195                 && caseSensitive == other.caseSensitive;
196     }
197 
198     public int hashCode()
199     {
200         return hash(new Object[]{this.getClass(), propertyName, propertyValue, scope, caseSensitive});
201     }
202 }