You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mb...@apache.org on 2007/08/10 17:48:14 UTC

svn commit: r564629 - /commons/proper/el/trunk/src/java/org/apache/commons/el/ExpressionEvaluatorImpl.java

Author: mbenson
Date: Fri Aug 10 08:48:13 2007
New Revision: 564629

URL: http://svn.apache.org/viewvc?view=rev&rev=564629
Log:
format

Modified:
    commons/proper/el/trunk/src/java/org/apache/commons/el/ExpressionEvaluatorImpl.java

Modified: commons/proper/el/trunk/src/java/org/apache/commons/el/ExpressionEvaluatorImpl.java
URL: http://svn.apache.org/viewvc/commons/proper/el/trunk/src/java/org/apache/commons/el/ExpressionEvaluatorImpl.java?view=diff&rev=564629&r1=564628&r2=564629
==============================================================================
--- commons/proper/el/trunk/src/java/org/apache/commons/el/ExpressionEvaluatorImpl.java (original)
+++ commons/proper/el/trunk/src/java/org/apache/commons/el/ExpressionEvaluatorImpl.java Fri Aug 10 08:48:13 2007
@@ -86,86 +86,81 @@
  * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author$
  **/
 
-public class ExpressionEvaluatorImpl
-  extends ExpressionEvaluator
-{
-    //-------------------------------------
+public class ExpressionEvaluatorImpl extends ExpressionEvaluator {
+    // -------------------------------------
     // Constants
-    //-------------------------------------
+    // -------------------------------------
     private static Log log = LogFactory.getLog(ExpressionEvaluatorImpl.class);
 
-  //-------------------------------------
-  // Member variables
-  //-------------------------------------
-
-  /** The mapping from expression String to its parsed form (String,
-      Expression, or ExpressionString) **/
-  static Map sCachedExpressionStrings = 
-    Collections.synchronizedMap (new HashMap ());
-
-  /** The mapping from ExpectedType to Maps mapping literal String to
-      parsed value **/
-  static Map sCachedExpectedTypes = new HashMap ();  
-
-  /** Flag if the cache should be bypassed **/
-  boolean mBypassCache;
-
-  //-------------------------------------
-  /**
-   *
-   * Constructor
-   **/
-  public ExpressionEvaluatorImpl () { }
-
-  /**
-   *
-   * Constructor
-   *
-   * @param pBypassCache flag indicating if the cache should be
-   * bypassed
-   **/
-  public ExpressionEvaluatorImpl (boolean pBypassCache)
-  {
-    mBypassCache = pBypassCache;
-  }
-
-  //-------------------------------------
-
-  /**
-   *
-   * Prepare an expression for later evaluation.  This method should perform
-   * syntactic validation of the expression; if in doing so it detects 
-   * errors, it should raise an ELParseException.
-   *
-   * @param expression The expression to be evaluated.
-   * @param expectedType The expected type of the result of the evaluation
-   * @param fMapper A FunctionMapper to resolve functions found in
-   *     the expression.  It can be null, in which case no functions
-   *     are supported for this invocation.  The ExpressionEvaluator
-   *     must not hold on to the FunctionMapper reference after
-   *     returning from <code>parseExpression()</code>.  The
-   *     <code>Expression</code> object returned must invoke the same
-   *     functions regardless of whether the mappings in the
-   *     provided <code>FunctionMapper</code> instance change between
-   *     calling <code>ExpressionEvaluator.parseExpression()</code>
-   *     and <code>Expression.evaluate()</code>.
-   * @return The Expression object encapsulating the arguments.
-   *
-   * @exception ELException Thrown if parsing errors were found.
-   **/
-  public javax.servlet.jsp.el.Expression parseExpression(String expression, 
-							 Class expectedType, 
-							 FunctionMapper fMapper)
-    throws ELException 
-  {
-    // Validate and then create an Expression object.
-    parseExpressionString(expression);
-        
-    // Create an Expression object that knows how to evaluate this.
-    return new JSTLExpression(this, expression, expectedType, fMapper);
-  }
+    // -------------------------------------
+    // Member variables
+    // -------------------------------------
+
+    /** The mapping from expression String to its parsed form (String,
+        Expression, or ExpressionString) **/
+    static Map sCachedExpressionStrings = Collections
+            .synchronizedMap(new HashMap());
+
+    /** The mapping from ExpectedType to Maps mapping literal String to
+        parsed value **/
+    static Map sCachedExpectedTypes = new HashMap();
+
+    /** Flag if the cache should be bypassed **/
+    boolean mBypassCache;
+
+    // -------------------------------------
+    /**
+     *
+     * Constructor
+     **/
+    public ExpressionEvaluatorImpl() {
+    }
+
+    /**
+     *
+     * Constructor
+     *
+     * @param pBypassCache flag indicating if the cache should be
+     * bypassed
+     **/
+    public ExpressionEvaluatorImpl(boolean pBypassCache) {
+        mBypassCache = pBypassCache;
+    }
+
+    // -------------------------------------
 
-  //-------------------------------------
+    /**
+     *
+     * Prepare an expression for later evaluation.  This method should perform
+     * syntactic validation of the expression; if in doing so it detects 
+     * errors, it should raise an ELParseException.
+     *
+     * @param expression The expression to be evaluated.
+     * @param expectedType The expected type of the result of the evaluation
+     * @param fMapper A FunctionMapper to resolve functions found in
+     *     the expression.  It can be null, in which case no functions
+     *     are supported for this invocation.  The ExpressionEvaluator
+     *     must not hold on to the FunctionMapper reference after
+     *     returning from <code>parseExpression()</code>.  The
+     *     <code>Expression</code> object returned must invoke the same
+     *     functions regardless of whether the mappings in the
+     *     provided <code>FunctionMapper</code> instance change between
+     *     calling <code>ExpressionEvaluator.parseExpression()</code>
+     *     and <code>Expression.evaluate()</code>.
+     * @return The Expression object encapsulating the arguments.
+     *
+     * @exception ELException Thrown if parsing errors were found.
+     **/
+    public javax.servlet.jsp.el.Expression parseExpression(String expression,
+            Class expectedType, FunctionMapper fMapper) throws ELException {
+        // Validate and then create an Expression object.
+        parseExpressionString(expression);
+
+        // Create an Expression object that knows how to evaluate this.
+        return new JSTLExpression(this, expression, expectedType, fMapper);
+    }
+
+    // -------------------------------------
     /**
      *
      * Evaluates the given expression String
@@ -180,312 +175,277 @@
      * @return the expression String evaluated to the given expected
      * type
      **/
-  public Object evaluate (String pExpressionString,
-		   Class pExpectedType,
-		   VariableResolver pResolver,
-		   FunctionMapper functions)
-    throws ELException
-  {
-    // Check for null expression strings
-    if (pExpressionString == null) {
-      throw new ELException
-	(Constants.NULL_EXPRESSION_STRING);
-    }
-
-    // Get the parsed version of the expression string
-    Object parsedValue = parseExpressionString (pExpressionString);
-
-    // Evaluate differently based on the parsed type
-    if (parsedValue instanceof String) {
-      // Convert the String, and cache the conversion
-      String strValue = (String) parsedValue;
-      return convertStaticValueToExpectedType (strValue, pExpectedType);
-    }
-
-    else if (parsedValue instanceof Expression) {
-      // Evaluate the expression and convert
-      Object value = 
-	((Expression) parsedValue).evaluate (pResolver,
-					     functions);
-      return convertToExpectedType (value, pExpectedType);
-    }
-
-    else if (parsedValue instanceof ExpressionString) {
-      // Evaluate the expression/string list and convert
-      String strValue = 
-	((ExpressionString) parsedValue).evaluate (pResolver, functions);
-      return convertToExpectedType (strValue, pExpectedType);
-    }
-
-    else {
-      // This should never be reached
-      return null;
-    }
-  }
-
-  //-------------------------------------
-  /**
-   *
-   * Gets the parsed form of the given expression string.  If the
-   * parsed form is cached (and caching is not bypassed), return the
-   * cached form, otherwise parse and cache the value.  Returns either
-   * a String, Expression, or ExpressionString.
-   **/
-  public Object parseExpressionString (String pExpressionString)
-    throws ELException
-  {
-    // See if it's an empty String
-    if (pExpressionString.length () == 0) {
-      return "";
-    }
-
-    // See if it's in the cache
-    Object ret = 
-      mBypassCache ?
-      null :
-      sCachedExpressionStrings.get (pExpressionString);
-
-    if (ret == null) {
-      // Parse the expression
-      Reader r = new StringReader (pExpressionString);
-      ELParser parser = new ELParser (r);
-      try {
-	ret = parser.ExpressionString ();
-	sCachedExpressionStrings.put (pExpressionString, ret);
-      }
-      catch (ParseException exc) {
-	throw new ELException 
-	  (formatParseException (pExpressionString,
-				 exc));
-      }
-      catch (TokenMgrError exc) {
-	// Note - this should never be reached, since the parser is
-	// constructed to tokenize any input (illegal inputs get
-	// parsed to <BADLY_ESCAPED_STRING_LITERAL> or
-	// <ILLEGAL_CHARACTER>
-	throw new ELException (exc.getMessage ());
-      }
-    }
-    return ret;
-  }
-
-  //-------------------------------------
-  /**
-   *
-   * Converts the given value to the specified expected type.
-   **/
-  Object convertToExpectedType (Object pValue,
-				Class pExpectedType)
-    throws ELException
-  {
-    return Coercions.coerce (pValue, pExpectedType);
-  }
-
-  //-------------------------------------
-  /**
-   *
-   * Converts the given String, specified as a static expression
-   * string, to the given expected type.  The conversion is cached.
-   **/
-  Object convertStaticValueToExpectedType (String pValue, Class pExpectedType)
-    throws ELException
-  {
-    // See if the value is already of the expected type
-    if (pExpectedType == String.class ||
-	pExpectedType == Object.class) {
-      return pValue;
-    }
-
-    // Find the cached value
-    Map valueByString = getOrCreateExpectedTypeMap (pExpectedType);
-    if (!mBypassCache &&
-	valueByString.containsKey (pValue)) {
-      return valueByString.get (pValue);
-    }
-    else {
-      // Convert from a String
-      Object ret = Coercions.coerce (pValue, pExpectedType);
-      valueByString.put (pValue, ret);
-      return ret;
-    }
-  }
-
-  //-------------------------------------
-  /**
-   *
-   * Creates or returns the Map that maps string literals to parsed
-   * values for the specified expected type.
-   **/
-  static Map getOrCreateExpectedTypeMap (Class pExpectedType)
-  {
-    synchronized (sCachedExpectedTypes) {
-      Map ret = (Map) sCachedExpectedTypes.get (pExpectedType);
-      if (ret == null) {
-	ret = Collections.synchronizedMap (new HashMap ());
-	sCachedExpectedTypes.put (pExpectedType, ret);
-      }
-      return ret;
-    }
-  }
-
-  //-------------------------------------
-  // Formatting ParseException
-  //-------------------------------------
-  /**
-   *
-   * Formats a ParseException into an error message suitable for
-   * displaying on a web page
-   **/
-  static String formatParseException (String pExpressionString,
-				      ParseException pExc)
-  {
-    // Generate the String of expected tokens
-    StringBuffer expectedBuf = new StringBuffer ();
-    int maxSize = 0;
-    boolean printedOne = false;
-
-    if (pExc.expectedTokenSequences == null)
-      return pExc.toString();
-
-    for (int i = 0; i < pExc.expectedTokenSequences.length; i++) {
-      if (maxSize < pExc.expectedTokenSequences [i].length) {
-        maxSize = pExc.expectedTokenSequences [i].length;
-      }
-      for (int j = 0; j < pExc.expectedTokenSequences [i].length; j++) {
-	if (printedOne) {
-	  expectedBuf.append (", ");
-	}
-        expectedBuf.append 
-	  (pExc.tokenImage [pExc.expectedTokenSequences [i] [j]]);
-	printedOne = true;
-      }
-    }
-    String expected = expectedBuf.toString ();
-
-    // Generate the String of encountered tokens
-    StringBuffer encounteredBuf = new StringBuffer ();
-    Token tok = pExc.currentToken.next;
-    for (int i = 0; i < maxSize; i++) {
-      if (i != 0) encounteredBuf.append (" ");
-      if (tok.kind == 0) {
-        encounteredBuf.append (pExc.tokenImage [0]);
-        break;
-      }
-      encounteredBuf.append (addEscapes (tok.image));
-      tok = tok.next; 
-    }
-    String encountered = encounteredBuf.toString ();
-
-    // Format the error message
-    return MessageFormat.format
-      (Constants.PARSE_EXCEPTION,
-       new Object [] {
-	 expected,
-	 encountered,
-       });
-  }
-
-  //-------------------------------------
-  /**
-   *
-   * Used to convert raw characters to their escaped version when
-   * these raw version cannot be used as part of an ASCII string
-   * literal.
-   **/
-  static String addEscapes (String str)
-  {
-    StringBuffer retval = new StringBuffer ();
-    char ch;
-    for (int i = 0, length = str.length(); i < length; i++) {
-      switch (str.charAt (i)) {
-	case 0 :
-	  continue;
-	case '\b':
-	  retval.append ("\\b");
-	  continue;
-	case '\t':
-	  retval.append ("\\t");
-	  continue;
-	case '\n':
-	  retval.append ("\\n");
-	  continue;
-	case '\f':
-	  retval.append ("\\f");
-	  continue;
-	case '\r':
-	  retval.append ("\\r");
-	  continue;
-	default:
-	  if ((ch = str.charAt (i)) < 0x20 || ch > 0x7e) {
-	    String s = "0000" + Integer.toString (ch, 16);
-	    retval.append ("\\u" + s.substring (s.length () - 4, s.length ()));
-	  }
-	  else {
-	    retval.append (ch);
-	  }
-	  continue;
-        }
-    }
-    return retval.toString ();
-  }
-
-  //-------------------------------------
-  // Testing methods
-  //-------------------------------------
-  /**
-   *
-   * Parses the given expression string, then converts it back to a
-   * String in its canonical form.  This is used to test parsing.
-   **/
-  public String parseAndRender (String pExpressionString)
-    throws ELException
-  {
-    Object val = parseExpressionString (pExpressionString);
-    if (val instanceof String) {
-      return (String) val;
-    }
-    else if (val instanceof Expression) {
-      return "${" + ((Expression) val).getExpressionString () + "}";
-    }
-    else if (val instanceof ExpressionString) {
-      return ((ExpressionString) val).getExpressionString ();
-    }
-    else {
-      return "";
-    }
-  }
-
-  /**
-   * An object that encapsulates an expression to be evaluated by 
-   * the JSTL evaluator.
-   */
-  private class JSTLExpression
-    extends javax.servlet.jsp.el.Expression
-  {
-    private ExpressionEvaluatorImpl evaluator;
-    private String expression;
-    private Class expectedType;
-    private FunctionMapper fMapper;
-
-    public JSTLExpression(ExpressionEvaluatorImpl evaluator, String expression,
-			  Class expectedType, FunctionMapper fMapper)
-    {
-      this.evaluator = evaluator;
-      this.expression = expression;
-      this.expectedType = expectedType;
-      this.fMapper = fMapper;
-    }
-        
-    public Object evaluate( VariableResolver vResolver )
-      throws ELException
-    {
-      return evaluator.evaluate(this.expression,
-				this.expectedType,
-				vResolver,
-				this.fMapper);
+    public Object evaluate(String pExpressionString, Class pExpectedType,
+            VariableResolver pResolver, FunctionMapper functions)
+            throws ELException {
+        // Check for null expression strings
+        if (pExpressionString == null) {
+            throw new ELException(Constants.NULL_EXPRESSION_STRING);
+        }
+
+        // Get the parsed version of the expression string
+        Object parsedValue = parseExpressionString(pExpressionString);
+
+        // Evaluate differently based on the parsed type
+        if (parsedValue instanceof String) {
+            // Convert the String, and cache the conversion
+            String strValue = (String) parsedValue;
+            return convertStaticValueToExpectedType(strValue, pExpectedType);
+        }
+
+        else if (parsedValue instanceof Expression) {
+            // Evaluate the expression and convert
+            Object value = ((Expression) parsedValue).evaluate(pResolver,
+                    functions);
+            return convertToExpectedType(value, pExpectedType);
+        }
+
+        else if (parsedValue instanceof ExpressionString) {
+            // Evaluate the expression/string list and convert
+            String strValue = ((ExpressionString) parsedValue).evaluate(
+                    pResolver, functions);
+            return convertToExpectedType(strValue, pExpectedType);
+        }
+
+        else {
+            // This should never be reached
+            return null;
+        }
+    }
+
+    // -------------------------------------
+    /**
+     *
+     * Gets the parsed form of the given expression string.  If the
+     * parsed form is cached (and caching is not bypassed), return the
+     * cached form, otherwise parse and cache the value.  Returns either
+     * a String, Expression, or ExpressionString.
+     **/
+    public Object parseExpressionString(String pExpressionString)
+            throws ELException {
+        // See if it's an empty String
+        if (pExpressionString.length() == 0) {
+            return "";
+        }
+
+        // See if it's in the cache
+        Object ret = mBypassCache ? null : sCachedExpressionStrings
+                .get(pExpressionString);
+
+        if (ret == null) {
+            // Parse the expression
+            Reader r = new StringReader(pExpressionString);
+            ELParser parser = new ELParser(r);
+            try {
+                ret = parser.ExpressionString();
+                sCachedExpressionStrings.put(pExpressionString, ret);
+            } catch (ParseException exc) {
+                throw new ELException(formatParseException(pExpressionString,
+                        exc));
+            } catch (TokenMgrError exc) {
+                // Note - this should never be reached, since the parser is
+                // constructed to tokenize any input (illegal inputs get
+                // parsed to <BADLY_ESCAPED_STRING_LITERAL> or
+                // <ILLEGAL_CHARACTER>
+                throw new ELException(exc.getMessage());
+            }
+        }
+        return ret;
+    }
+
+    // -------------------------------------
+    /**
+     *
+     * Converts the given value to the specified expected type.
+     **/
+    Object convertToExpectedType(Object pValue, Class pExpectedType)
+            throws ELException {
+        return Coercions.coerce(pValue, pExpectedType);
+    }
+
+    // -------------------------------------
+    /**
+     *
+     * Converts the given String, specified as a static expression
+     * string, to the given expected type.  The conversion is cached.
+     **/
+    Object convertStaticValueToExpectedType(String pValue, Class pExpectedType)
+            throws ELException {
+        // See if the value is already of the expected type
+        if (pExpectedType == String.class || pExpectedType == Object.class) {
+            return pValue;
+        }
+
+        // Find the cached value
+        Map valueByString = getOrCreateExpectedTypeMap(pExpectedType);
+        if (!mBypassCache && valueByString.containsKey(pValue)) {
+            return valueByString.get(pValue);
+        } else {
+            // Convert from a String
+            Object ret = Coercions.coerce(pValue, pExpectedType);
+            valueByString.put(pValue, ret);
+            return ret;
+        }
+    }
+
+    // -------------------------------------
+    /**
+     *
+     * Creates or returns the Map that maps string literals to parsed
+     * values for the specified expected type.
+     **/
+    static Map getOrCreateExpectedTypeMap(Class pExpectedType) {
+        synchronized (sCachedExpectedTypes) {
+            Map ret = (Map) sCachedExpectedTypes.get(pExpectedType);
+            if (ret == null) {
+                ret = Collections.synchronizedMap(new HashMap());
+                sCachedExpectedTypes.put(pExpectedType, ret);
+            }
+            return ret;
+        }
+    }
+
+    // -------------------------------------
+    // Formatting ParseException
+    // -------------------------------------
+    /**
+     *
+     * Formats a ParseException into an error message suitable for
+     * displaying on a web page
+     **/
+    static String formatParseException(String pExpressionString,
+            ParseException pExc) {
+        // Generate the String of expected tokens
+        StringBuffer expectedBuf = new StringBuffer();
+        int maxSize = 0;
+        boolean printedOne = false;
+
+        if (pExc.expectedTokenSequences == null)
+            return pExc.toString();
+
+        for (int i = 0; i < pExc.expectedTokenSequences.length; i++) {
+            if (maxSize < pExc.expectedTokenSequences[i].length) {
+                maxSize = pExc.expectedTokenSequences[i].length;
+            }
+            for (int j = 0; j < pExc.expectedTokenSequences[i].length; j++) {
+                if (printedOne) {
+                    expectedBuf.append(", ");
+                }
+                expectedBuf
+                        .append(pExc.tokenImage[pExc.expectedTokenSequences[i][j]]);
+                printedOne = true;
+            }
+        }
+        String expected = expectedBuf.toString();
+
+        // Generate the String of encountered tokens
+        StringBuffer encounteredBuf = new StringBuffer();
+        Token tok = pExc.currentToken.next;
+        for (int i = 0; i < maxSize; i++) {
+            if (i != 0)
+                encounteredBuf.append(" ");
+            if (tok.kind == 0) {
+                encounteredBuf.append(pExc.tokenImage[0]);
+                break;
+            }
+            encounteredBuf.append(addEscapes(tok.image));
+            tok = tok.next;
+        }
+        String encountered = encounteredBuf.toString();
+
+        // Format the error message
+        return MessageFormat.format(Constants.PARSE_EXCEPTION, new Object[] {
+                expected, encountered, });
+    }
+
+    // -------------------------------------
+    /**
+     *
+     * Used to convert raw characters to their escaped version when
+     * these raw version cannot be used as part of an ASCII string
+     * literal.
+     **/
+    static String addEscapes(String str) {
+        StringBuffer retval = new StringBuffer();
+        char ch;
+        for (int i = 0, length = str.length(); i < length; i++) {
+            switch (str.charAt(i)) {
+            case 0:
+                continue;
+            case '\b':
+                retval.append("\\b");
+                continue;
+            case '\t':
+                retval.append("\\t");
+                continue;
+            case '\n':
+                retval.append("\\n");
+                continue;
+            case '\f':
+                retval.append("\\f");
+                continue;
+            case '\r':
+                retval.append("\\r");
+                continue;
+            default:
+                if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
+                    String s = "0000" + Integer.toString(ch, 16);
+                    retval.append("\\u"
+                            + s.substring(s.length() - 4, s.length()));
+                } else {
+                    retval.append(ch);
+                }
+                continue;
+            }
+        }
+        return retval.toString();
+    }
+
+    // -------------------------------------
+    // Testing methods
+    // -------------------------------------
+    /**
+     *
+     * Parses the given expression string, then converts it back to a
+     * String in its canonical form.  This is used to test parsing.
+     **/
+    public String parseAndRender(String pExpressionString) throws ELException {
+        Object val = parseExpressionString(pExpressionString);
+        if (val instanceof String) {
+            return (String) val;
+        } else if (val instanceof Expression) {
+            return "${" + ((Expression) val).getExpressionString() + "}";
+        } else if (val instanceof ExpressionString) {
+            return ((ExpressionString) val).getExpressionString();
+        } else {
+            return "";
+        }
+    }
+
+    /**
+     * An object that encapsulates an expression to be evaluated by 
+     * the JSTL evaluator.
+     */
+    private class JSTLExpression extends javax.servlet.jsp.el.Expression {
+        private ExpressionEvaluatorImpl evaluator;
+        private String expression;
+        private Class expectedType;
+        private FunctionMapper fMapper;
+
+        public JSTLExpression(ExpressionEvaluatorImpl evaluator,
+                String expression, Class expectedType, FunctionMapper fMapper) {
+            this.evaluator = evaluator;
+            this.expression = expression;
+            this.expectedType = expectedType;
+            this.fMapper = fMapper;
+        }
+
+        public Object evaluate(VariableResolver vResolver) throws ELException {
+            return evaluator.evaluate(this.expression, this.expectedType,
+                    vResolver, this.fMapper);
+        }
     }
-  }
 
-  //-------------------------------------
+    // -------------------------------------
 
 }