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