Coverage Report - org.mule.routing.filters.ExpressionFilter
 
Classes in this File Line Coverage Branch Coverage Complexity
ExpressionFilter
0%
0/84
0%
0/44
0
 
 1  
 /*
 2  
  * $Id: ExpressionFilter.java 19365 2010-09-04 03:24:52Z dirk.olmes $
 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  
 package org.mule.routing.filters;
 11  
 
 12  
 import org.mule.api.MuleContext;
 13  
 import org.mule.api.MuleMessage;
 14  
 import org.mule.api.context.MuleContextAware;
 15  
 import org.mule.api.routing.filter.Filter;
 16  
 import org.mule.expression.ExpressionConfig;
 17  
 
 18  
 import java.text.MessageFormat;
 19  
 
 20  
 import org.apache.commons.logging.Log;
 21  
 import org.apache.commons.logging.LogFactory;
 22  
 
 23  
 import static org.mule.util.ClassUtils.equal;
 24  
 import static org.mule.util.ClassUtils.hash;
 25  
 
 26  
 /**
 27  
  * Allows boolean expressions to be executed on a message. Note that when using this filter you must be able to either specify
 28  
  * a boolean expression when using an expression filter or use one of the standard Mule filters.  These can be defined as follows -
 29  
  *
 30  
  * <ul>
 31  
  * <li>RegEx - 'regex:<pattern>': #[regex:'error' [0-9]]</li>
 32  
  * <li>Wildcard - 'wildcard:<pattern>': #[wildcard: *foo*</li>
 33  
  * <li>PayloadType - 'payload-type:<fully qualified class name>': #[payload:javax.jms.TextMessage]</li>
 34  
  * <li>ExceptionType - 'exception-type:<fully qualified class name>': #[exception-type:java.io.FileNotFoundException]</li>
 35  
  * <li>Header - 'header:<boolean expression>': #[header:foo!=null]</li>
 36  
  * </ul>
 37  
  *
 38  
  * Otherwise you can use eny expression filter providing you can define a boolean expression i.e.
 39  
  * <code>
 40  
  * #[xpath:count(/Foo/Bar) == 0]
 41  
  * </code>
 42  
  *
 43  
  * Note that it if the expression is not a boolean expression this filter will return true if the expression returns a result
 44  
  * 
 45  
  */
 46  
 public class ExpressionFilter implements Filter, MuleContextAware
 47  
 {
 48  
     /**
 49  
      * logger used by this class
 50  
      */
 51  0
     protected transient final Log logger = LogFactory.getLog(ExpressionFilter.class);
 52  
 
 53  
     private ExpressionConfig config;
 54  
     private String fullExpression;
 55  0
     private boolean nullReturnsTrue = false;
 56  
     private MuleContext muleContext;
 57  
 
 58  
     /**
 59  
      * The class-loader that should be used to load any classes used in scripts.
 60  
      * Default to the classloader used to load this filter
 61  
      **/
 62  0
     private ClassLoader expressionEvaluationClassLoader = Thread.currentThread().getContextClassLoader();
 63  
     
 64  
     /** For evaluators that are not expression languages we can delegate the execution to another filter */
 65  
     private Filter delegateFilter;
 66  
 
 67  
     public ExpressionFilter(String evaluator, String customEvaluator, String expression)
 68  0
     {
 69  0
         this.config = new ExpressionConfig(expression, evaluator, customEvaluator);
 70  0
     }
 71  
 
 72  
     public ExpressionFilter(String evaluator, String expression)
 73  0
     {
 74  0
         this.config = new ExpressionConfig(expression, evaluator, null);
 75  0
     }
 76  
 
 77  
     public ExpressionFilter(String expression)
 78  0
     {
 79  0
         this.config = new ExpressionConfig();
 80  0
         this.config.parse(expression);
 81  0
     }
 82  
 
 83  
     public ExpressionFilter()
 84  
     {
 85  0
         super();
 86  0
         this.config = new ExpressionConfig();
 87  0
     }
 88  
 
 89  
     public void setMuleContext(MuleContext context)
 90  
     {
 91  0
         this.muleContext = context;
 92  0
     }
 93  
 
 94  
     /**
 95  
      * Check a given message against this filter.
 96  
      *
 97  
      * @param message a non null message to filter.
 98  
      * @return <code>true</code> if the message matches the filter
 99  
      */
 100  
     public boolean accept(MuleMessage message)
 101  
     {
 102  0
         String expr = getFullExpression();
 103  0
         if (delegateFilter != null)
 104  
         {
 105  0
             boolean result = delegateFilter.accept(message);
 106  0
             if (logger.isDebugEnabled())
 107  
             {
 108  0
                 logger.debug(MessageFormat.format("Result of expression filter: {0} is: {1}", expr, result));
 109  
             }
 110  0
             return result;
 111  
         }
 112  
 
 113  
         Object result;
 114  
 
 115  
         // MULE-4797 Because there is no way to specify the class-loader that script
 116  
         // engines use and because scripts when used for expressions are compiled in
 117  
         // runtime rather than at initialization the only way to ensure the correct
 118  
         // class-loader to used is to switch it out here. We may want to consider
 119  
         // passing the class-loader to the ExpressionManager and only doing this for
 120  
         // certain ExpressionEvaluators further in.
 121  0
         ClassLoader originalContextClassLoader = Thread.currentThread().getContextClassLoader();
 122  
         try
 123  
         {
 124  0
             Thread.currentThread().setContextClassLoader(expressionEvaluationClassLoader);
 125  0
             result = muleContext.getExpressionManager().evaluate(expr, message, false);
 126  
         }
 127  
         finally
 128  
         {
 129  
             // Restore original context class-loader
 130  0
             Thread.currentThread().setContextClassLoader(originalContextClassLoader);
 131  0
         }
 132  
 
 133  0
         if (result == null)
 134  
         {
 135  0
             return nullReturnsTrue;
 136  
         }
 137  0
         else if (result instanceof Boolean)
 138  
         {
 139  0
             return (Boolean) result;
 140  
         }
 141  0
         else if (result instanceof String)
 142  
         {
 143  0
             if(result.toString().toLowerCase().equalsIgnoreCase("false"))
 144  
             {
 145  0
                 return false;
 146  
             }
 147  0
             else if(result.toString().toLowerCase().equalsIgnoreCase("true"))
 148  
             {
 149  0
                 return true;
 150  
             }
 151  
             else
 152  
             {
 153  0
                 return !nullReturnsTrue;
 154  
             }
 155  
         }
 156  
         else
 157  
         {
 158  0
             logger.warn("Expression: " + expr + ", returned an non-boolean result. Returning: "
 159  
                         + !nullReturnsTrue);
 160  0
             return !nullReturnsTrue;
 161  
         }
 162  
     }
 163  
 
 164  
     protected String getFullExpression()
 165  
     {
 166  0
         if(fullExpression==null)
 167  
         {
 168  
             //Handle non-expression filters
 169  0
             if(config.getEvaluator().equals("header"))
 170  
             {
 171  0
                 delegateFilter = new MessagePropertyFilter(config.getExpression());
 172  
             }
 173  0
             else if(config.getEvaluator().equals("regex"))
 174  
             {
 175  0
                 delegateFilter = new RegExFilter(config.getExpression());
 176  
             }
 177  0
             else if(config.getEvaluator().equals("wildcard"))
 178  
             {
 179  0
                 delegateFilter = new WildcardFilter(config.getExpression());
 180  
             }
 181  0
             else if(config.getEvaluator().equals("payload-type"))
 182  
             {
 183  
                 try
 184  
                 {
 185  0
                     delegateFilter = new PayloadTypeFilter(config.getExpression());
 186  
                 }
 187  0
                 catch (ClassNotFoundException e)
 188  
                 {
 189  0
                     IllegalArgumentException iae = new IllegalArgumentException();
 190  0
                     iae.initCause(e);
 191  0
                     throw iae;
 192  0
                 }
 193  
             }
 194  0
             else if(config.getEvaluator().equals("exception-type"))
 195  
             {
 196  
                 try
 197  
                 {
 198  0
                     delegateFilter = new ExceptionTypeFilter(config.getExpression());
 199  
                 }
 200  0
                 catch (ClassNotFoundException e)
 201  
                 {
 202  0
                     IllegalArgumentException iae = new IllegalArgumentException();
 203  0
                     iae.initCause(e);
 204  0
                     throw iae;
 205  0
                 }
 206  
             }
 207  
             else
 208  
             {
 209  
                 //In the case of 'payload' the expression can be null
 210  0
                 fullExpression = config.getFullExpression(muleContext.getExpressionManager());
 211  
             }
 212  
         }
 213  0
         return fullExpression;
 214  
     }
 215  
 
 216  
     public String getCustomEvaluator()
 217  
     {
 218  0
         return config.getCustomEvaluator();
 219  
     }
 220  
 
 221  
     public void setCustomEvaluator(String customEvaluator)
 222  
     {
 223  0
         this.config.setCustomEvaluator(customEvaluator);
 224  0
         fullExpression=null;        
 225  0
     }
 226  
 
 227  
     public String getEvaluator()
 228  
     {
 229  0
         return config.getEvaluator();
 230  
     }
 231  
 
 232  
     public void setEvaluator(String evaluator)
 233  
     {
 234  0
         this.config.setEvaluator(evaluator);
 235  0
         fullExpression=null;
 236  0
     }
 237  
 
 238  
     public String getExpression()
 239  
     {
 240  0
         return config.getExpression();
 241  
     }
 242  
 
 243  
     public void setExpression(String expression)
 244  
     {
 245  0
         this.config.setExpression(expression);
 246  0
         fullExpression=null;
 247  0
     }
 248  
 
 249  
     public boolean isNullReturnsTrue()
 250  
     {
 251  0
         return nullReturnsTrue;
 252  
     }
 253  
 
 254  
     public void setNullReturnsTrue(boolean nullReturnsTrue)
 255  
     {
 256  0
         this.nullReturnsTrue = nullReturnsTrue;
 257  0
     }
 258  
 
 259  
     @Override
 260  
     public boolean equals(Object obj)
 261  
     {
 262  0
         if (this == obj) return true;
 263  0
         if (obj == null || getClass() != obj.getClass()) return false;
 264  
 
 265  0
         final ExpressionFilter other = (ExpressionFilter) obj;
 266  0
         return equal(config, other.config)
 267  
             && equal(delegateFilter, other.delegateFilter)
 268  
             && nullReturnsTrue == other.nullReturnsTrue;
 269  
     }
 270  
 
 271  
     @Override
 272  
     public int hashCode()
 273  
     {
 274  0
         return hash(new Object[]{this.getClass(), config, delegateFilter, nullReturnsTrue});
 275  
     }
 276  
 }