commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bay...@apache.org
Subject svn commit: r572959 - in /commons/proper/el/trunk: ./ src/java/org/apache/commons/el/ src/test/org/apache/commons/el/
Date Wed, 05 Sep 2007 14:35:22 GMT
Author: bayard
Date: Wed Sep  5 07:35:21 2007
New Revision: 572959

URL: http://svn.apache.org/viewvc?rev=572959&view=rev
Log:
Applying Jamie Taylor's patch from EL-8 - EL now correctly implements the spec and is not
affected when the function map is later modified

Added:
    commons/proper/el/trunk/src/java/org/apache/commons/el/BoundFunctionInvocation.java  
(with props)
    commons/proper/el/trunk/src/test/org/apache/commons/el/FunctionBindingTest.java   (with
props)
Modified:
    commons/proper/el/trunk/NOTICE.txt
    commons/proper/el/trunk/src/java/org/apache/commons/el/ArraySuffix.java
    commons/proper/el/trunk/src/java/org/apache/commons/el/BinaryOperatorExpression.java
    commons/proper/el/trunk/src/java/org/apache/commons/el/ComplexValue.java
    commons/proper/el/trunk/src/java/org/apache/commons/el/ConditionalExpression.java
    commons/proper/el/trunk/src/java/org/apache/commons/el/Expression.java
    commons/proper/el/trunk/src/java/org/apache/commons/el/ExpressionEvaluatorImpl.java
    commons/proper/el/trunk/src/java/org/apache/commons/el/ExpressionString.java
    commons/proper/el/trunk/src/java/org/apache/commons/el/FunctionInvocation.java
    commons/proper/el/trunk/src/java/org/apache/commons/el/Literal.java
    commons/proper/el/trunk/src/java/org/apache/commons/el/NamedValue.java
    commons/proper/el/trunk/src/java/org/apache/commons/el/UnaryOperatorExpression.java
    commons/proper/el/trunk/src/java/org/apache/commons/el/ValueSuffix.java

Modified: commons/proper/el/trunk/NOTICE.txt
URL: http://svn.apache.org/viewvc/commons/proper/el/trunk/NOTICE.txt?rev=572959&r1=572958&r2=572959&view=diff
==============================================================================
--- commons/proper/el/trunk/NOTICE.txt (original)
+++ commons/proper/el/trunk/NOTICE.txt Wed Sep  5 07:35:21 2007
@@ -3,3 +3,6 @@
 
 This product includes software developed by
 The Apache Software Foundation (http://www.apache.org/).
+
+EL-8 patch - Copyright 2004-2007 Jamie Taylor
+http://issues.apache.org/jira/browse/EL-8

Modified: commons/proper/el/trunk/src/java/org/apache/commons/el/ArraySuffix.java
URL: http://svn.apache.org/viewvc/commons/proper/el/trunk/src/java/org/apache/commons/el/ArraySuffix.java?rev=572959&r1=572958&r2=572959&view=diff
==============================================================================
--- commons/proper/el/trunk/src/java/org/apache/commons/el/ArraySuffix.java (original)
+++ commons/proper/el/trunk/src/java/org/apache/commons/el/ArraySuffix.java Wed Sep  5 07:35:21
2007
@@ -296,5 +296,8 @@
         return null;
     }
 
+    public ValueSuffix bindFunctions(final FunctionMapper functions) throws ELException {
+        return new ArraySuffix(mIndex.bindFunctions(functions));
+    }
     //-------------------------------------
 }

Modified: commons/proper/el/trunk/src/java/org/apache/commons/el/BinaryOperatorExpression.java
URL: http://svn.apache.org/viewvc/commons/proper/el/trunk/src/java/org/apache/commons/el/BinaryOperatorExpression.java?rev=572959&r1=572958&r2=572959&view=diff
==============================================================================
--- commons/proper/el/trunk/src/java/org/apache/commons/el/BinaryOperatorExpression.java (original)
+++ commons/proper/el/trunk/src/java/org/apache/commons/el/BinaryOperatorExpression.java Wed
Sep  5 07:35:21 2007
@@ -17,6 +17,8 @@
 package org.apache.commons.el;
 
 import java.util.List;
+import java.util.Iterator;
+import java.util.ArrayList;
 
 import javax.servlet.jsp.el.ELException;
 import javax.servlet.jsp.el.FunctionMapper;
@@ -131,6 +133,19 @@
     }
     return value;
   }
+
+    public Expression bindFunctions(final FunctionMapper functions) throws ELException {
+        final List args = new ArrayList(mExpressions.size());
+        for (Iterator argIter = mExpressions.iterator(); argIter.hasNext();) {
+            args.add(((Expression)argIter.next()).bindFunctions(functions));
+        }
+        // it would be nice if we knew for sure that the operators list
+        // was immutable, but we'll just assume so for now.
+        return new BinaryOperatorExpression(
+                mExpression.bindFunctions(functions),
+                mOperators,
+                args);
+    }
 
   //-------------------------------------
 }

Added: commons/proper/el/trunk/src/java/org/apache/commons/el/BoundFunctionInvocation.java
URL: http://svn.apache.org/viewvc/commons/proper/el/trunk/src/java/org/apache/commons/el/BoundFunctionInvocation.java?rev=572959&view=auto
==============================================================================
--- commons/proper/el/trunk/src/java/org/apache/commons/el/BoundFunctionInvocation.java (added)
+++ commons/proper/el/trunk/src/java/org/apache/commons/el/BoundFunctionInvocation.java Wed
Sep  5 07:35:21 2007
@@ -0,0 +1,57 @@
+/* $Id$ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+package org.apache.commons.el;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import javax.servlet.jsp.el.ELException;
+import javax.servlet.jsp.el.FunctionMapper;
+
+/**
+ * A subclass of <code>FunctionInvocation</code> which is bound
+ * to a particular <code>Method</code>.  A bound function does
+ * not require a <code>FunctionMapper</code> to be evaluated.
+ * 
+ * @author Jamie Taylor
+ */
+public class BoundFunctionInvocation extends FunctionInvocation {
+    private final Method method;
+    
+    /**
+     * @param functionName
+     * @param argumentList
+     */
+    public BoundFunctionInvocation(
+            final Method method,
+            final String functionName, 
+            final List argumentList) 
+    {
+        super(functionName, argumentList);
+        this.method = method;
+    }
+
+    /**
+     * Returns the <code>Method</code>supplied to the constructor.
+     * @param functions unused
+     */
+    protected Method resolveFunction(FunctionMapper functions)
+            throws ELException {
+        return method;
+    }
+}

Propchange: commons/proper/el/trunk/src/java/org/apache/commons/el/BoundFunctionInvocation.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: commons/proper/el/trunk/src/java/org/apache/commons/el/ComplexValue.java
URL: http://svn.apache.org/viewvc/commons/proper/el/trunk/src/java/org/apache/commons/el/ComplexValue.java?rev=572959&r1=572958&r2=572959&view=diff
==============================================================================
--- commons/proper/el/trunk/src/java/org/apache/commons/el/ComplexValue.java (original)
+++ commons/proper/el/trunk/src/java/org/apache/commons/el/ComplexValue.java Wed Sep  5 07:35:21
2007
@@ -17,6 +17,7 @@
 package org.apache.commons.el;
 
 import java.util.List;
+import java.util.ArrayList;
 
 import javax.servlet.jsp.el.ELException;
 import javax.servlet.jsp.el.FunctionMapper;
@@ -107,6 +108,15 @@
     }
 
     return ret;
+  }
+
+  public Expression bindFunctions(final FunctionMapper functions) throws ELException {
+      final List suffixes = new ArrayList(mSuffixes.size());
+      for (int i = 0; mSuffixes != null && i < mSuffixes.size (); i++) {
+          ValueSuffix suffix = (ValueSuffix) mSuffixes.get (i);
+          suffixes.add(suffix.bindFunctions(functions));
+      }
+      return new ComplexValue(mPrefix.bindFunctions(functions), suffixes);
   }
 
   //-------------------------------------

Modified: commons/proper/el/trunk/src/java/org/apache/commons/el/ConditionalExpression.java
URL: http://svn.apache.org/viewvc/commons/proper/el/trunk/src/java/org/apache/commons/el/ConditionalExpression.java?rev=572959&r1=572958&r2=572959&view=diff
==============================================================================
--- commons/proper/el/trunk/src/java/org/apache/commons/el/ConditionalExpression.java (original)
+++ commons/proper/el/trunk/src/java/org/apache/commons/el/ConditionalExpression.java Wed
Sep  5 07:35:21 2007
@@ -113,5 +113,12 @@
       return mFalseBranch.evaluate(vr, f);
   }
 
+  public Expression bindFunctions(final FunctionMapper functions) throws ELException {
+       return new ConditionalExpression(
+               mCondition.bindFunctions(functions),
+               mTrueBranch.bindFunctions(functions),
+               mFalseBranch.bindFunctions(functions));
+  }
+
   //-------------------------------------
 }

Modified: commons/proper/el/trunk/src/java/org/apache/commons/el/Expression.java
URL: http://svn.apache.org/viewvc/commons/proper/el/trunk/src/java/org/apache/commons/el/Expression.java?rev=572959&r1=572958&r2=572959&view=diff
==============================================================================
--- commons/proper/el/trunk/src/java/org/apache/commons/el/Expression.java (original)
+++ commons/proper/el/trunk/src/java/org/apache/commons/el/Expression.java Wed Sep  5 07:35:21
2007
@@ -53,4 +53,17 @@
 
   //-------------------------------------
 
+  /**
+   * Returns an expression with all <code>FunctionInvocation</code>s replaced
by
+   * <code>BoundFunctionInvocation</code>s.
+   * @param functions the functions to use in this transformation
+   * @return an Expression identical to this expression except with all
+   *    <code>FunctionInvocation</code>s replaced by
+   *    <code>BoundFunctionInvocation</code>s.
+   * @throws ELException if any of the functions in this <code>Expression</code>
are
+   *    not present in <code>functions</code>
+   */
+  public abstract Expression bindFunctions(FunctionMapper functions)
+      throws ELException;
+
 }

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?rev=572959&r1=572958&r2=572959&view=diff
==============================================================================
--- 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 Wed
Sep  5 07:35:21 2007
@@ -153,11 +153,14 @@
                                                         FunctionMapper fMapper)
     throws ELException
   {
-    // Validate and then create an Expression object.
-    Object parsedExpression = parseExpressionString (expression);
-
-    // Create an Expression object that knows how to evaluate this.
-    return new JSTLExpression (parsedExpression, expectedType, fMapper);
+       // Create an Expression object that knows how to evaluate this.
+       final Object parsedExpression = parseExpressionString(expression);
+       if (parsedExpression instanceof Expression) {
+           return new JSTLExpression(this, (Expression)parsedExpression, expectedType, fMapper);
+       } else {
+           // this had better be a string
+           return new JSTLExpression(this, (String)parsedExpression, expectedType, fMapper);
+       }
   }
 
   //-------------------------------------
@@ -208,36 +211,30 @@
   public Object evaluate (Object parsedExpression, Class pExpectedType,
       VariableResolver pResolver, FunctionMapper functions) throws ELException
   {
-    // Evaluate differently based on the parsed type
-    if (parsedExpression instanceof String)
-    {
-      // Convert the String, and cache the conversion
-      String strValue = (String) parsedExpression;
-      return convertStaticValueToExpectedType (strValue, pExpectedType);
-    }
-
-    if (parsedExpression instanceof Expression)
-    {
-      // Evaluate the expression and convert
-      Object value =
-        ((Expression) parsedExpression).evaluate (pResolver,
-                                        functions);
-      return convertToExpectedType (value, pExpectedType);
-    }
-
-    if (parsedExpression instanceof ExpressionString)
-    {
-      // Evaluate the expression/string list and convert
-      String strValue =
-        ((ExpressionString) parsedExpression).evaluate (pResolver, functions);
-      return convertToExpectedType (strValue, pExpectedType);
-    }
+      return evaluateParsedValue(parsedExpression, pExpectedType, pResolver, functions);
+  }
 
-    else {
-      // This should never be reached
-      return null;
+  private Object evaluateParsedValue(Object parsedValue, Class pExpectedType, VariableResolver
pResolver, FunctionMapper functions) throws ELException {
+        // 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 {
+          // This should never be reached
+          return null;
+        }
     }
-  }
 
   //-------------------------------------
   /**
@@ -481,24 +478,40 @@
   private class JSTLExpression
     extends javax.servlet.jsp.el.Expression
   {
+    private ExpressionEvaluatorImpl evaluator;
     private Object parsedExpression;
     private Class expectedType;
-    private FunctionMapper fMapper;
 
-    private JSTLExpression(Object parsedExpression, Class expectedType,
-        FunctionMapper fMapper)
-    {
-      this.parsedExpression = parsedExpression;
+    public JSTLExpression(
+            final ExpressionEvaluatorImpl evaluator,
+            final Expression expression,
+            final Class expectedType,
+            final FunctionMapper fMapper)
+    throws ELException {
+      this.evaluator = evaluator;
+      this.parsedExpression = expression.bindFunctions(fMapper);
       this.expectedType = expectedType;
-      this.fMapper = fMapper;
     }
-
-    public Object evaluate (VariableResolver vResolver) throws ELException
-    {
-      return ExpressionEvaluatorImpl.this.evaluate
-        (parsedExpression, expectedType, vResolver, fMapper);
-    }
-  }
+    public JSTLExpression(
+            final ExpressionEvaluatorImpl evaluator,
+            final String expressionString,
+            final Class expectedType,
+            final FunctionMapper fMapper)
+    throws ELException {
+       this.evaluator = evaluator;
+       this.parsedExpression = expressionString;
+       this.expectedType = expectedType;
+     }
+    
+     public Object evaluate( VariableResolver vResolver )
+       throws ELException
+     {
+      return evaluator.evaluateParsedValue(this.parsedExpression,
+               this.expectedType,
+               vResolver,
+               null);
+     }
+   }
 
   //-------------------------------------
 

Modified: commons/proper/el/trunk/src/java/org/apache/commons/el/ExpressionString.java
URL: http://svn.apache.org/viewvc/commons/proper/el/trunk/src/java/org/apache/commons/el/ExpressionString.java?rev=572959&r1=572958&r2=572959&view=diff
==============================================================================
--- commons/proper/el/trunk/src/java/org/apache/commons/el/ExpressionString.java (original)
+++ commons/proper/el/trunk/src/java/org/apache/commons/el/ExpressionString.java Wed Sep 
5 07:35:21 2007
@@ -30,7 +30,7 @@
  * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author$
  **/
 
-public class ExpressionString
+public class ExpressionString extends Expression
 {
   //-------------------------------------
   // Properties
@@ -60,7 +60,7 @@
    * converting it to a String (using toString, or "" for null values)
    * and concatenating the results into a single String.
    **/
-  public String evaluate (VariableResolver pResolver,
+  public Object evaluate (VariableResolver pResolver,
 			  FunctionMapper functions)
     throws ELException
   {
@@ -104,4 +104,16 @@
   }
 
   //-------------------------------------
+
+  public Expression bindFunctions(FunctionMapper functions) throws ELException {
+      final Object[] boundElements = new Object[mElements.length];
+      for (int i = 0; i < mElements.length; i++) {
+          if (mElements[i] instanceof Expression) {
+              boundElements[i] = ((Expression)mElements[i]).bindFunctions(functions);
+          } else {
+              boundElements[i] = mElements[i];
+          }
+      }
+      return new ExpressionString(boundElements);
+  }
 }

Modified: commons/proper/el/trunk/src/java/org/apache/commons/el/FunctionInvocation.java
URL: http://svn.apache.org/viewvc/commons/proper/el/trunk/src/java/org/apache/commons/el/FunctionInvocation.java?rev=572959&r1=572958&r2=572959&view=diff
==============================================================================
--- commons/proper/el/trunk/src/java/org/apache/commons/el/FunctionInvocation.java (original)
+++ commons/proper/el/trunk/src/java/org/apache/commons/el/FunctionInvocation.java Wed Sep
 5 07:35:21 2007
@@ -20,6 +20,7 @@
 import java.lang.reflect.Method;
 import java.util.Iterator;
 import java.util.List;
+import java.util.ArrayList;
 
 import javax.servlet.jsp.el.ELException;
 import javax.servlet.jsp.el.FunctionMapper;
@@ -97,30 +98,7 @@
     throws ELException
   {
 
-    // if the Map is null, then the function is invalid
-    if (functions == null) {
-        if (log.isErrorEnabled()) {
-            String message = MessageUtil.getMessageWithArgs(
-                Constants.UNKNOWN_FUNCTION, functionName);
-            log.error(message);
-            throw new ELException(message);
-        }
-    }            
-
-    // normalize function name
-    String prefix = null;
-    String localName = null;
-    int index = functionName.indexOf( ':' );
-    if (index == -1) {
-      prefix = "";
-      localName = functionName;
-    } else {
-      prefix = functionName.substring( 0, index );
-      localName = functionName.substring( index + 1 );
-    }
-
-    // ensure that the function's name is mapped
-    Method target = (Method) functions.resolveFunction(prefix, localName);
+    Method target = resolveFunction(functions);
     if (target == null) {
         if (log.isErrorEnabled()) {
             String message = MessageUtil.getMessageWithArgs(
@@ -177,6 +155,50 @@
       return null;
     }
   }
+
+  /**
+   * Returns the <code>Method</code> which is mapped to the function
+   * name used by this <code>FunctionInvocation</code>.
+   * @param functions The function mappings in use for this evaluation
+   * @return the <code>Method</code> to execute 
+   * @throws ELException
+   */
+  protected Method resolveFunction(FunctionMapper functions) throws ELException {
+      // if the Map is null, then the function is invalid 
+      if (functions == null) { 
+          return null;
+      }                    
+
+      // normalize function name
+      String prefix = null; 
+      String localName = null; 
+      int index = functionName.indexOf( ':' );
+      if (index == -1) {
+        prefix = "";
+        localName = functionName;
+      } else {
+        prefix = functionName.substring( 0, index );
+        localName = functionName.substring( index + 1 );
+      }       
+  
+      // ensure that the function's name is mapped
+      Method target = (Method) functions.resolveFunction(prefix, localName);
+   
+       return target; 
+   }
+
+   public Expression bindFunctions(final FunctionMapper functions)
+           throws ELException {
+       final List argList = new ArrayList(argumentList.size());
+       for (Iterator argIter = argumentList.iterator(); argIter.hasNext();) {
+           Expression arg = (Expression) argIter.next();
+           argList.add(arg.bindFunctions(functions));
+       }
+       return new BoundFunctionInvocation(
+               resolveFunction(functions),
+               functionName,
+               argList);
+   }
 
   //-------------------------------------
 }

Modified: commons/proper/el/trunk/src/java/org/apache/commons/el/Literal.java
URL: http://svn.apache.org/viewvc/commons/proper/el/trunk/src/java/org/apache/commons/el/Literal.java?rev=572959&r1=572958&r2=572959&view=diff
==============================================================================
--- commons/proper/el/trunk/src/java/org/apache/commons/el/Literal.java (original)
+++ commons/proper/el/trunk/src/java/org/apache/commons/el/Literal.java Wed Sep  5 07:35:21
2007
@@ -66,5 +66,10 @@
     return mValue;
   }
 
+  public Expression bindFunctions(FunctionMapper functions) throws ELException {
+      return this;
+  }
+   
+
   //-------------------------------------
 }

Modified: commons/proper/el/trunk/src/java/org/apache/commons/el/NamedValue.java
URL: http://svn.apache.org/viewvc/commons/proper/el/trunk/src/java/org/apache/commons/el/NamedValue.java?rev=572959&r1=572958&r2=572959&view=diff
==============================================================================
--- commons/proper/el/trunk/src/java/org/apache/commons/el/NamedValue.java (original)
+++ commons/proper/el/trunk/src/java/org/apache/commons/el/NamedValue.java Wed Sep  5 07:35:21
2007
@@ -84,5 +84,9 @@
     }
   }
 
+  public Expression bindFunctions(FunctionMapper functions) throws ELException {
+      return this;
+  }
+
   //-------------------------------------
 }

Modified: commons/proper/el/trunk/src/java/org/apache/commons/el/UnaryOperatorExpression.java
URL: http://svn.apache.org/viewvc/commons/proper/el/trunk/src/java/org/apache/commons/el/UnaryOperatorExpression.java?rev=572959&r1=572958&r2=572959&view=diff
==============================================================================
--- commons/proper/el/trunk/src/java/org/apache/commons/el/UnaryOperatorExpression.java (original)
+++ commons/proper/el/trunk/src/java/org/apache/commons/el/UnaryOperatorExpression.java Wed
Sep  5 07:35:21 2007
@@ -126,5 +126,12 @@
     return value;
   }
 
+  public Expression bindFunctions(final FunctionMapper functions) throws ELException {
+      return new UnaryOperatorExpression(
+              mOperator,
+              mOperators,
+              mExpression.bindFunctions(functions));
+  }
+
   //-------------------------------------
 }

Modified: commons/proper/el/trunk/src/java/org/apache/commons/el/ValueSuffix.java
URL: http://svn.apache.org/viewvc/commons/proper/el/trunk/src/java/org/apache/commons/el/ValueSuffix.java?rev=572959&r1=572958&r2=572959&view=diff
==============================================================================
--- commons/proper/el/trunk/src/java/org/apache/commons/el/ValueSuffix.java (original)
+++ commons/proper/el/trunk/src/java/org/apache/commons/el/ValueSuffix.java Wed Sep  5 07:35:21
2007
@@ -51,5 +51,8 @@
 				   FunctionMapper functions)
     throws ELException;
 
+  public abstract ValueSuffix bindFunctions(FunctionMapper functions)
+  throws ELException;
+
   //-------------------------------------
 }

Added: commons/proper/el/trunk/src/test/org/apache/commons/el/FunctionBindingTest.java
URL: http://svn.apache.org/viewvc/commons/proper/el/trunk/src/test/org/apache/commons/el/FunctionBindingTest.java?rev=572959&view=auto
==============================================================================
--- commons/proper/el/trunk/src/test/org/apache/commons/el/FunctionBindingTest.java (added)
+++ commons/proper/el/trunk/src/test/org/apache/commons/el/FunctionBindingTest.java Wed Sep
 5 07:35:21 2007
@@ -0,0 +1,96 @@
+/* $Id$ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+package org.apache.commons.el;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.jsp.el.ELException;
+import javax.servlet.jsp.el.Expression;
+import javax.servlet.jsp.el.ExpressionEvaluator;
+import javax.servlet.jsp.el.FunctionMapper;
+import javax.servlet.jsp.el.VariableResolver;
+
+import org.apache.commons.el.ExpressionEvaluatorImpl;
+
+import junit.framework.TestCase;
+
+/**
+ * @author Jamie Taylor
+ *
+ */
+public class FunctionBindingTest extends TestCase {
+    public static String before() {return "before";}
+    public static String after() {return "after";}
+    public static String echo(final String s) {return s;}
+    private static class UpdatableFunctionMapper implements FunctionMapper {
+        private Map mappings = new HashMap();
+        public void setMapping(
+                final String name,
+                final Method function) 
+        {
+            mappings.put(name,function);
+        }
+        public Method resolveFunction(
+                final String prefix, 
+                final String localName) 
+        {
+            return (Method)mappings.get(localName);
+        }
+    }
+    
+    public void testFunctionBinding() throws ELException, NoSuchMethodException{
+        final String theExpression = "${theFunction()}";
+        final String nestedExpression = "${echo(theFunction())}";
+        final VariableResolver emptyVariableResolver = new VariableResolver() {
+            public Object resolveVariable(String arg0) throws ELException {
+                return null;
+            }
+        };
+        final UpdatableFunctionMapper fm = new UpdatableFunctionMapper();
+        final Method before = FunctionBindingTest.class.getDeclaredMethod("before",new Class[0]);
+        final Method after = FunctionBindingTest.class.getDeclaredMethod("after",new Class[0]);
+        final Method echo = FunctionBindingTest.class.getDeclaredMethod("echo", new Class[]{String.class});
+        final ExpressionEvaluator evaluator = new ExpressionEvaluatorImpl();
+        fm.setMapping("theFunction",before);
+        fm.setMapping("echo", echo);
+        
+        final Expression expr = evaluator.parseExpression(theExpression, String.class, fm);
+        final Expression nestedExpr = evaluator.parseExpression(nestedExpression, String.class,
fm);
+        assertEquals(
+           "before",
+           expr.evaluate(emptyVariableResolver));
+        assertEquals(
+           "before",
+           nestedExpr.evaluate(emptyVariableResolver));
+        
+        fm.setMapping("theFunction",after);
+        assertEquals(
+           "after",
+           evaluator.evaluate(theExpression, String.class, emptyVariableResolver, fm));
+        assertEquals(
+           "before",
+           expr.evaluate(emptyVariableResolver));
+        assertEquals(
+           "after",
+           evaluator.evaluate(nestedExpression, String.class, emptyVariableResolver, fm));
+        assertEquals(
+           "before",
+           nestedExpr.evaluate(emptyVariableResolver));
+    }
+}

Propchange: commons/proper/el/trunk/src/test/org/apache/commons/el/FunctionBindingTest.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message