/*
 * 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.jasper.runtime;

import java.lang.reflect.Method;
import java.util.HashMap;

import javax.servlet.jsp.el.FunctionMapper;

/**
 * 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
 */
@SuppressWarnings("deprecation") // Have to support old JSP EL API
public final class ProtectedFunctionMapper extends javax.el.FunctionMapper
        implements FunctionMapper {

    /**
     * Maps "prefix:name" to java.lang.Method objects.
     */
    private HashMap<String,Method> 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.
     *
     * @return A new protected function mapper.
     */
    public static ProtectedFunctionMapper getInstance() {
        ProtectedFunctionMapper funcMapper = new ProtectedFunctionMapper();
        funcMapper.fnmap = new 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) {
        // Skip if null values were passed in. They indicate a function
        // added via a lambda or ImportHandler; nether of which need to be
        // placed in the Map.
        if (fnQName == null) {
            return;
        }
        java.lang.reflect.Method method;
        try {
            method = c.getMethod(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 = null;
        ProtectedFunctionMapper funcMapper = new ProtectedFunctionMapper();
        // Skip if null values were passed in. They indicate a function
        // added via a lambda or ImportHandler; nether of which need to be
        // placed in the Map.
        if (fnQName != null) {
            try {
                method = c.getMethod(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.
     */
    @Override
    public Method resolveFunction(String prefix, String localName) {
        if (this.fnmap != null) {
            return this.fnmap.get(prefix + ":" + localName);
        }
        return theMethod;
    }
}
