001/* $Id$ */
002/*
003 * Licensed to the Apache Software Foundation (ASF) under one or more
004 * contributor license agreements.  See the NOTICE file distributed with
005 * this work for additional information regarding copyright ownership.
006 * The ASF licenses this file to You under the Apache License, Version 2.0
007 * (the "License"); you may not use this file except in compliance with
008 * the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017*/
018package org.apache.commons.el;
019import java.lang.reflect.Method;
020import java.util.HashMap;
021import java.util.Map;
022
023import javax.servlet.jsp.el.ELException;
024import javax.servlet.jsp.el.Expression;
025import javax.servlet.jsp.el.ExpressionEvaluator;
026import javax.servlet.jsp.el.FunctionMapper;
027import javax.servlet.jsp.el.VariableResolver;
028
029import org.apache.commons.el.ExpressionEvaluatorImpl;
030
031import junit.framework.TestCase;
032
033/**
034 * @author Jamie Taylor
035 *
036 */
037public class FunctionBindingTest extends TestCase {
038    public static String before() {return "before";}
039    public static String after() {return "after";}
040    public static String echo(final String s) {return s;}
041    private static class UpdatableFunctionMapper implements FunctionMapper {
042        private Map mappings = new HashMap();
043        public void setMapping(
044                final String name,
045                final Method function) 
046        {
047            mappings.put(name,function);
048        }
049        public Method resolveFunction(
050                final String prefix, 
051                final String localName) 
052        {
053            return (Method)mappings.get(localName);
054        }
055    }
056    
057    public void testFunctionBinding() throws ELException, NoSuchMethodException{
058        final String theExpression = "${theFunction()}";
059        final String nestedExpression = "${echo(theFunction())}";
060        final VariableResolver emptyVariableResolver = new VariableResolver() {
061            public Object resolveVariable(String arg0) throws ELException {
062                return null;
063            }
064        };
065        final UpdatableFunctionMapper fm = new UpdatableFunctionMapper();
066        final Method before = FunctionBindingTest.class.getDeclaredMethod("before",new Class[0]);
067        final Method after = FunctionBindingTest.class.getDeclaredMethod("after",new Class[0]);
068        final Method echo = FunctionBindingTest.class.getDeclaredMethod("echo", new Class[]{String.class});
069        final ExpressionEvaluator evaluator = new ExpressionEvaluatorImpl();
070        fm.setMapping("theFunction",before);
071        fm.setMapping("echo", echo);
072        
073        final Expression expr = evaluator.parseExpression(theExpression, String.class, fm);
074        final Expression nestedExpr = evaluator.parseExpression(nestedExpression, String.class, fm);
075        assertEquals(
076           "before",
077           expr.evaluate(emptyVariableResolver));
078        assertEquals(
079           "before",
080           nestedExpr.evaluate(emptyVariableResolver));
081        
082        fm.setMapping("theFunction",after);
083        assertEquals(
084           "after",
085           evaluator.evaluate(theExpression, String.class, emptyVariableResolver, fm));
086        assertEquals(
087           "before",
088           expr.evaluate(emptyVariableResolver));
089        assertEquals(
090           "after",
091           evaluator.evaluate(nestedExpression, String.class, emptyVariableResolver, fm));
092        assertEquals(
093           "before",
094           nestedExpr.evaluate(emptyVariableResolver));
095    }
096}