/*
 * Copyright 1999,2004 The Apache Software Foundation.
 * 
 * Licensed 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.jasper.runtime;

import java.util.HashMap;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.security.PrivilegedActionException;
import java.lang.reflect.Method;
import javax.servlet.jsp.el.FunctionMapper;

import org.apache.jasper.security.SecurityUtil;

/**
 * Maps EL functions to their Java method counterparts.  Keeps the
 * actual Method objects protected so that JSP pages can't indirectly
 * do reflection.
 *
 * @author Mark Roth
 * @author Kin-man Chung
 */
public final class ProtectedFunctionMapper implements FunctionMapper {

    /** 
     * Maps "prefix:name" to java.lang.Method objects.
     */
    private HashMap fnmap = null;

    /**
     * If there is only one function in the map, this is the Method for it.
     */
    private Method theMethod = null;

    /**
     * Constructor has protected access.
     */
    private ProtectedFunctionMapper() {
    }

    /**
     * Generated Servlet and Tag Handler implementations call this
     * method to retrieve an instance of the ProtectedFunctionMapper.
     * This is necessary since generated code does not have access to
     * create instances of classes in this package.
     *
     * @return A new protected function mapper.
     */
    public static ProtectedFunctionMapper getInstance() {
        ProtectedFunctionMapper funcMapper;
	if (SecurityUtil.isPackageProtectionEnabled()) {
	    funcMapper = (ProtectedFunctionMapper)AccessController.doPrivileged(
		new PrivilegedAction() {
		public Object run() {
		    return new ProtectedFunctionMapper();
		}
	    } );
	} else {
	    funcMapper = new ProtectedFunctionMapper();
	}
	funcMapper.fnmap = new java.util.HashMap();
	return funcMapper;
    }

    /**
     * Stores a mapping from the given EL function prefix and name to 
     * the given Java method.
     *
     * @param fnQName The EL function qualified name (including prefix)
     * @param c The class containing the Java method
     * @param methodName The name of the Java method
     * @param args The arguments of the Java method
     * @throws RuntimeException if no method with the given signature
     *     could be found.
     */
    public void mapFunction(String fnQName, final Class c,
			    final String methodName, final Class[] args ) 
    {
	java.lang.reflect.Method method;
        if (SecurityUtil.isPackageProtectionEnabled()){
            try{
                method = (java.lang.reflect.Method)AccessController.doPrivileged(new PrivilegedExceptionAction(){

                    public Object run() throws Exception{
                        return c.getDeclaredMethod(methodName, args);
                    }                
                });      
            } catch (PrivilegedActionException ex){
                throw new RuntimeException(
                    "Invalid function mapping - no such method: "
		    + ex.getException().getMessage());               
            }
        } else {
             try {
                method = c.getDeclaredMethod(methodName, args);
            } catch( NoSuchMethodException e ) {
                throw new RuntimeException(
                    "Invalid function mapping - no such method: "
		    + e.getMessage());
            }
        }

	this.fnmap.put(fnQName, method );
    }

    /**
     * Creates an instance for this class, and stores the Method for
     * the given EL function prefix and name. This method is used for
     * the case when there is only one function in the EL expression.
     *
     * @param fnQName The EL function qualified name (including prefix)
     * @param c The class containing the Java method
     * @param methodName The name of the Java method
     * @param args The arguments of the Java method
     * @throws RuntimeException if no method with the given signature
     *     could be found.
     */
    public static ProtectedFunctionMapper getMapForFunction(
		String fnQName, final Class c,
                final String methodName, final Class[] args )
    {
        java.lang.reflect.Method method;
        ProtectedFunctionMapper funcMapper;
        if (SecurityUtil.isPackageProtectionEnabled()){
            funcMapper = (ProtectedFunctionMapper)AccessController.doPrivileged(
                new PrivilegedAction(){
                public Object run() {
                    return new ProtectedFunctionMapper();
                }
            });

            try{
                method = (java.lang.reflect.Method)AccessController.doPrivileged
(new PrivilegedExceptionAction(){

                    public Object run() throws Exception{
                        return c.getDeclaredMethod(methodName, args);
                    }
                });
            } catch (PrivilegedActionException ex){
                throw new RuntimeException(
                    "Invalid function mapping - no such method: "
                    + ex.getException().getMessage());
            }
        } else {
	    funcMapper = new ProtectedFunctionMapper();
             try {
                method = c.getDeclaredMethod(methodName, args);
            } catch( NoSuchMethodException e ) {
                throw new RuntimeException(
                    "Invalid function mapping - no such method: "
                    + e.getMessage());
            }
        }
        funcMapper.theMethod = method;
	return funcMapper;
    }

    /**
     * Resolves the specified local name and prefix into a Java.lang.Method.
     * Returns null if the prefix and local name are not found.
     * 
     * @param prefix the prefix of the function
     * @param localName the short name of the function
     * @return the result of the method mapping.  Null means no entry found.
     **/
    public Method resolveFunction(String prefix, String localName) {
        if (this.fnmap != null) {
            return (Method) this.fnmap.get(prefix + ":" + localName);
        }
	return theMethod;
    }
}

