Coverage Report - org.mule.util.expression.ExpressionEvaluatorManager
 
Classes in this File Line Coverage Branch Coverage Complexity
ExpressionEvaluatorManager
77%
41/53
68%
19/28
2.462
ExpressionEvaluatorManager$1
100%
2/2
N/A
2.462
 
 1  
 /*
 2  
  * $Id: ExpressionEvaluatorManager.java 12100 2008-06-19 08:58:48Z rossmason $
 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  
 package org.mule.util.expression;
 11  
 
 12  
 import org.mule.api.lifecycle.Disposable;
 13  
 import org.mule.config.i18n.CoreMessages;
 14  
 import org.mule.util.TemplateParser;
 15  
 
 16  
 import java.util.Iterator;
 17  
 
 18  
 import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
 19  
 import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentMap;
 20  
 
 21  
 /**
 22  
  * Provides universal access for evaluating expressions embedded in Mule configurations, such  as Xml, Java,
 23  
  * scripting and annotations.
 24  
  *
 25  
  * Users can register or unregister {@link ExpressionEvaluator} through this interface.
 26  
  * */
 27  0
 public class ExpressionEvaluatorManager
 28  
 {
 29  
 
 30  
     public static final String DEFAULT_EXPRESSION_PREFIX = "${";
 31  
 
 32  2
     private static TemplateParser parser = TemplateParser.createAntStyleParser();
 33  
 
 34  2
     private static ConcurrentMap evaluators = new ConcurrentHashMap(8);
 35  
 
 36  
     public static void registerEvaluator(ExpressionEvaluator extractor)
 37  
     {
 38  13756
         if (extractor == null)
 39  
         {
 40  2
             throw new IllegalArgumentException(CoreMessages.objectIsNull("extractor").getMessage());
 41  
         }
 42  13754
         Object previous = evaluators.putIfAbsent(extractor.getName(), extractor);
 43  13754
         if (previous != null)
 44  
         {
 45  2
             throw new IllegalArgumentException(CoreMessages.objectAlreadyExists(extractor.getName()).getMessage());
 46  
         }
 47  13752
     }
 48  
 
 49  
     /**
 50  
      * Checks whether an evaluator is registered with the manager
 51  
      * @param name the name of the expression evaluator
 52  
      * @return true if the evaluator is registered with the manager, false otherwise
 53  
      */
 54  
     public static boolean isEvaluatorRegistered(String name)
 55  
     {
 56  8
         return evaluators.containsKey(name);
 57  
     }
 58  
 
 59  
     /**
 60  
      * Removes the evaluator with the given name
 61  
      * @param name the name of the evaluator to remove
 62  
      */
 63  
     public static ExpressionEvaluator unregisterEvaluator(String name)
 64  
     {
 65  2
         if (name==null)
 66  
         {
 67  2
             return null;
 68  
         }
 69  
         
 70  0
         ExpressionEvaluator evaluator = (ExpressionEvaluator) ExpressionEvaluatorManager.evaluators.remove(name);
 71  0
         if (evaluator instanceof Disposable)
 72  
         {
 73  0
             ((Disposable) evaluator).dispose();
 74  
         }
 75  0
         return evaluator;
 76  
     }
 77  
 
 78  
     /**
 79  
      * Evaluates the given expression.  The expression should be a single expression definition with or without 
 80  
      * enclosing braces. i.e. "mule:serviceName" and "${mule:serviceName}" are both valid. For situations where
 81  
      * one or more expressions need to be parsed within a single text, the {@link #parse(String, Object, boolean)}
 82  
      * method should be used since it will iterate through all expressions in a string.
 83  
      *
 84  
      * @param expression a single expression i.e. xpath://foo
 85  
      * @param object The object (usually {@link org.mule.api.MuleMessage}) to evaluate the expression on.
 86  
      * @return the result of the evaluation
 87  
      * @throws ExpressionRuntimeException if the expression is invalid, or a null is found for the expression and
 88  
      * 'failIfNull is set to true.
 89  
      */
 90  
     public static Object evaluate(String expression, Object object) throws ExpressionRuntimeException
 91  
     {
 92  116
         return evaluate(expression, object, DEFAULT_EXPRESSION_PREFIX, false);
 93  
     }
 94  
 
 95  
     /**
 96  
      * Evaluates the given expression.  The expression should be a single expression definition with or without
 97  
      * enclosing braces. i.e. "mule:serviceName" and "${mule:serviceName}" are both valid. For situations where
 98  
      * one or more expressions need to be parsed within a single text, the {@link #parse(String, Object, boolean)}
 99  
      * method should be used since it will iterate through all expressions in a string.
 100  
      *
 101  
      * @param expression a single expression i.e. xpath://foo
 102  
      * @param object The object (usually {@link org.mule.api.MuleMessage}) to evaluate the expression on.
 103  
      * @param failIfNull determines if an exception should be thrown if expression could not be evaluated or returns
 104  
      * null.
 105  
      * @return the result of the evaluation
 106  
      * @throws ExpressionRuntimeException if the expression is invalid, or a null is found for the expression and
 107  
      * 'failIfNull is set to true.
 108  
      */
 109  
     public static Object evaluate(String expression, Object object, boolean failIfNull) throws ExpressionRuntimeException
 110  
     {
 111  16
         return evaluate(expression, object, DEFAULT_EXPRESSION_PREFIX, failIfNull);
 112  
     }
 113  
 
 114  
     /**
 115  
      * Evaluates the given expression.  The expression should be a single expression definition with or without
 116  
      * enclosing braces. i.e. "mule:serviceName" and "${mule:serviceName}" are both valid. For situations where
 117  
      * one or more expressions need to be parsed within a single text, the {@link #parse(String, Object, boolean)}
 118  
      * method should be used since it will iterate through all expressions in a string.
 119  
      *
 120  
      * @param expression a single expression i.e. xpath://foo
 121  
      * @param evaluator the evaluator to use when executing the expression
 122  
      * @param object The object (usually {@link org.mule.api.MuleMessage}) to evaluate the expression on.
 123  
      * It is unlikely that users will want to change this execpt maybe to use "["  instead.
 124  
      * @param failIfNull determines if an exception should be thrown if expression could not be evaluated or returns
 125  
      * null.
 126  
      * @return the result of the evaluation
 127  
      * @throws ExpressionRuntimeException if the expression is invalid, or a null is found for the expression and
 128  
      * 'failIfNull is set to true.
 129  
      */
 130  
     public static Object evaluate(String expression, String evaluator, Object object, boolean failIfNull) throws ExpressionRuntimeException
 131  
     {
 132  132
         ExpressionEvaluator extractor = (ExpressionEvaluator) evaluators.get(evaluator);
 133  132
         if (extractor == null)
 134  
         {
 135  0
             throw new IllegalArgumentException(CoreMessages.expressionEvaluatorNotRegistered(evaluator).getMessage());
 136  
         }
 137  132
         Object result = extractor.evaluate(expression, object);
 138  126
         if (result == null && failIfNull)
 139  
         {
 140  0
             throw new ExpressionRuntimeException(CoreMessages.expressionEvaluatorReturnedNull(evaluator, expression));
 141  
         }
 142  126
         return result;
 143  
     }
 144  
     /**
 145  
      * Evaluates the given expression.  The expression should be a single expression definition with or without
 146  
      * enclosing braces. i.e. "mule:serviceName" and "${mule:serviceName}" are both valid. For situations where
 147  
      * one or more expressions need to be parsed within a single text, the {@link #parse(String, Object, boolean)}
 148  
      * method should be used since it will iterate through all expressions in a string.
 149  
      *
 150  
      * @param expression a single expression i.e. xpath://foo
 151  
      * @param object The object (usually {@link org.mule.api.MuleMessage}) to evaluate the expression on.
 152  
      * @param expressionPrefix the expression prefix to use. The default is "${" but any character is valid.
 153  
      * It is unlikely that users will want to change this except maybe to use "["  instead.
 154  
      * @param failIfNull determines if an exception should be thrown if expression could not be evaluated or returns
 155  
      * null.
 156  
      * @return the result of the evaluation
 157  
      * @throws ExpressionRuntimeException if the expression is invalid, or a null is found for the expression and
 158  
      * 'failIfNull is set to true.
 159  
      */
 160  
     public static Object evaluate(String expression, Object object, String expressionPrefix, boolean failIfNull) throws ExpressionRuntimeException
 161  
     {
 162  
         String name;
 163  
 
 164  132
         if (expression == null)
 165  
         {
 166  0
             throw new IllegalArgumentException(CoreMessages.objectIsNull("expression").getMessage());
 167  
         }
 168  132
         if (expression.startsWith(expressionPrefix))
 169  
         {
 170  60
             expression = expression.substring(2, expression.length()-1);
 171  
         }
 172  132
         int i = expression.indexOf(":");
 173  132
         if (i >- 1)
 174  
         {
 175  126
             name = expression.substring(0, i);
 176  126
             expression = expression.substring(i+1);
 177  
         }
 178  
         else
 179  
         {
 180  6
             name = expression;
 181  6
             expression = null;
 182  
         }
 183  132
         return evaluate(expression, name, object, failIfNull);
 184  
 
 185  
 
 186  
     }
 187  
 
 188  
     /**
 189  
      * Evaluates expressions in a given string. This method will iterate through each expression and evaluate it. If
 190  
      * a user needs to evaluate a single expression they can use {@link #evaluate(String, Object, boolean)}.
 191  
      *
 192  
      * @param expression a single expression i.e. xpath://foo
 193  
      * @param object The object (usually {@link org.mule.api.MuleMessage}) to evaluate the expression on.
 194  
 
 195  
      * @return the result of the evaluation
 196  
      * @throws ExpressionRuntimeException if the expression is invalid, or a null is found for the expression and
 197  
      * 'failIfNull is set to true.
 198  
      */
 199  
     public static String parse(String expression, Object object) throws ExpressionRuntimeException
 200  
     {
 201  0
         return parse(expression, object, false);
 202  
     }
 203  
 
 204  
     /**
 205  
      * Evaluates expressions in a given string. This method will iterate through each expression and evaluate it. If
 206  
      * a user needs to evaluate a single expression they can use {@link #evaluate(String, Object, boolean)}.
 207  
      *
 208  
      * @param expression a single expression i.e. xpath://foo
 209  
      * @param object The object (usually {@link org.mule.api.MuleMessage}) to evaluate the expression on.
 210  
      * @param failIfNull determines if an exception should be thrown if expression could not be evaluated or returns
 211  
      * null.
 212  
      * @return the result of the evaluation
 213  
      * @throws ExpressionRuntimeException if the expression is invalid, or a null is found for the expression and
 214  
      * 'failIfNull is set to true.
 215  
      */
 216  
     public static String parse(final String expression, final Object object, final boolean failIfNull) throws ExpressionRuntimeException
 217  
     {
 218  14
         return parser.parse(new TemplateParser.TemplateCallback() {
 219  14
             public Object match(String token)
 220  
             {
 221  14
                 return evaluate(token, object, failIfNull);
 222  
             }
 223  
         }, expression);
 224  
     }
 225  
 
 226  
     /**
 227  
      * Clears all registered evaluators from the manager.
 228  
      */
 229  
     public static synchronized void clearEvaluators()
 230  
     {
 231  2304
         for (Iterator iterator = evaluators.values().iterator(); iterator.hasNext();)
 232  
         {
 233  13752
             ExpressionEvaluator evaluator = (ExpressionEvaluator)iterator.next();
 234  13752
             if(evaluator instanceof Disposable)
 235  
             {
 236  0
                 ((Disposable) evaluator).dispose();
 237  
             }
 238  13752
         }
 239  2304
         evaluators.clear();
 240  2304
     }
 241  
 
 242  
     /**
 243  
      * Determines if the expression is valid or not.  This only validates single expressions.
 244  
      * @param expression the expression to validate
 245  
      * @return true if the expression evaluator is recognised
 246  
      */
 247  
     public static boolean isValidExpression(String expression)
 248  
     {
 249  8
         return isValidExpression(expression, DEFAULT_EXPRESSION_PREFIX);
 250  
     }
 251  
 
 252  
     /**
 253  
      * Determines if the expression is valid or not.  This only validates single expressions.
 254  
      * @param expression the expression to validate
 255  
      * @param expressionPrefix the prefix used for this expression. if the expression is ${bean:msg.header}
 256  
      * the prefix is "${"
 257  
      * @return true if the expression evaluator is recognised
 258  
      */
 259  
     public static boolean isValidExpression(String expression, String expressionPrefix)
 260  
     {
 261  8
         if(expression.startsWith(expressionPrefix))
 262  
         {
 263  0
             expression = expression.substring(2, expression.length()-1);
 264  
         }
 265  
         String name;
 266  8
         int i = expression.indexOf(":");
 267  8
         if(i>-1)
 268  
         {
 269  8
             name = expression.substring(0, i);
 270  
         }
 271  
         else
 272  
         {
 273  0
             name = expression;
 274  
         }
 275  8
         return isEvaluatorRegistered(name);
 276  
     }
 277  
 
 278  
 }