/*
 * 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.beans.PropertyEditor;
import java.beans.PropertyEditorManager;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Enumeration;

import jakarta.el.VariableMapper;
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.jsp.JspException;
import jakarta.servlet.jsp.JspWriter;
import jakarta.servlet.jsp.PageContext;
import jakarta.servlet.jsp.tagext.BodyContent;
import jakarta.servlet.jsp.tagext.BodyTag;
import jakarta.servlet.jsp.tagext.Tag;

import org.apache.jasper.JasperException;
import org.apache.jasper.compiler.Localizer;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.InstanceManager;

/**
 * Bunch of util methods that are used by code generated for useBean, getProperty and setProperty.
 */
public class JspRuntimeLibrary {

    public static final boolean GRAAL;

    static {
        boolean result = false;
        try {
            Class<?> nativeImageClazz = Class.forName("org.graalvm.nativeimage.ImageInfo");
            result = nativeImageClazz.getMethod("inImageCode").invoke(null) != null;
            // Note: This will also be true for the Graal substrate VM
        } catch (ClassNotFoundException e) {
            // Must be Graal
        } catch (ReflectiveOperationException | IllegalArgumentException e) {
            // Should never happen
        }
        GRAAL = result || System.getProperty("org.graalvm.nativeimage.imagecode") != null;
    }

    /**
     * Returns the value of the jakarta.servlet.error.exception request attribute value, if present, otherwise the value
     * of the jakarta.servlet.jsp.jspException request attribute value. This method is called at the beginning of the
     * generated servlet code for a JSP error page, when the "exception" implicit scripting language variable is
     * initialized.
     *
     * @param request The Servlet request
     *
     * @return the throwable in the error attribute if any
     */
    public static Throwable getThrowable(ServletRequest request) {
        Throwable error = (Throwable) request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
        if (error == null) {
            error = (Throwable) request.getAttribute(PageContext.EXCEPTION);
            if (error != null) {
                /*
                 * The only place that sets JSP_EXCEPTION is PageContextImpl.handlePageException(). It really should set
                 * SERVLET_EXCEPTION, but that would interfere with the ErrorReportValve. Therefore, if JSP_EXCEPTION is
                 * set, we need to set SERVLET_EXCEPTION.
                 */
                request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, error);
            }
        }

        return error;
    }

    public static boolean coerceToBoolean(String s) {
        if (s == null || s.isEmpty()) {
            return false;
        } else {
            return Boolean.parseBoolean(s);
        }
    }

    public static byte coerceToByte(String s) {
        if (s == null || s.isEmpty()) {
            return (byte) 0;
        } else {
            return Byte.parseByte(s);
        }
    }

    public static char coerceToChar(String s) {
        if (s == null || s.isEmpty()) {
            return (char) 0;
        } else {
            return s.charAt(0);
        }
    }

    public static double coerceToDouble(String s) {
        if (s == null || s.isEmpty()) {
            return 0;
        } else {
            return Double.parseDouble(s);
        }
    }

    public static float coerceToFloat(String s) {
        if (s == null || s.isEmpty()) {
            return 0;
        } else {
            return Float.parseFloat(s);
        }
    }

    public static int coerceToInt(String s) {
        if (s == null || s.isEmpty()) {
            return 0;
        } else {
            return Integer.parseInt(s);
        }
    }

    public static short coerceToShort(String s) {
        if (s == null || s.isEmpty()) {
            return (short) 0;
        } else {
            return Short.parseShort(s);
        }
    }

    public static long coerceToLong(String s) {
        if (s == null || s.isEmpty()) {
            return 0;
        } else {
            return Long.parseLong(s);
        }
    }

    public static Object coerce(String s, Class<?> target) {

        boolean isNullOrEmpty = (s == null || s.isEmpty());

        if (target == Boolean.class) {
            if (isNullOrEmpty) {
                s = "false";
            }
            return Boolean.valueOf(s);
        } else if (target == Byte.class) {
            if (isNullOrEmpty) {
                return Byte.valueOf((byte) 0);
            } else {
                return Byte.valueOf(s);
            }
        } else if (target == Character.class) {
            if (isNullOrEmpty) {
                return Character.valueOf((char) 0);
            } else {
                @SuppressWarnings("null")
                Character result = Character.valueOf(s.charAt(0));
                return result;
            }
        } else if (target == Double.class) {
            if (isNullOrEmpty) {
                return Double.valueOf(0);
            } else {
                return Double.valueOf(s);
            }
        } else if (target == Float.class) {
            if (isNullOrEmpty) {
                return Float.valueOf(0);
            } else {
                return Float.valueOf(s);
            }
        } else if (target == Integer.class) {
            if (isNullOrEmpty) {
                return Integer.valueOf(0);
            } else {
                return Integer.valueOf(s);
            }
        } else if (target == Short.class) {
            if (isNullOrEmpty) {
                return Short.valueOf((short) 0);
            } else {
                return Short.valueOf(s);
            }
        } else if (target == Long.class) {
            if (isNullOrEmpty) {
                return Long.valueOf(0);
            } else {
                return Long.valueOf(s);
            }
        } else {
            return null;
        }
    }


    public static Object convert(String propertyName, String s, Class<?> t, Class<?> propertyEditorClass)
            throws JasperException {
        try {
            if (s == null) {
                if (t.equals(Boolean.class) || t.equals(Boolean.TYPE)) {
                    s = "false";
                } else {
                    return null;
                }
            }
            if (propertyEditorClass != null) {
                return getValueFromBeanInfoPropertyEditor(t, propertyName, s, propertyEditorClass);
            } else if (t.equals(Boolean.class) || t.equals(Boolean.TYPE)) {
                return Boolean.valueOf(s);
            } else if (t.equals(Byte.class) || t.equals(Byte.TYPE)) {
                if (s.isEmpty()) {
                    return Byte.valueOf((byte) 0);
                } else {
                    return Byte.valueOf(s);
                }
            } else if (t.equals(Character.class) || t.equals(Character.TYPE)) {
                if (s.isEmpty()) {
                    return Character.valueOf((char) 0);
                } else {
                    return Character.valueOf(s.charAt(0));
                }
            } else if (t.equals(Double.class) || t.equals(Double.TYPE)) {
                if (s.isEmpty()) {
                    return Double.valueOf(0);
                } else {
                    return Double.valueOf(s);
                }
            } else if (t.equals(Integer.class) || t.equals(Integer.TYPE)) {
                if (s.isEmpty()) {
                    return Integer.valueOf(0);
                } else {
                    return Integer.valueOf(s);
                }
            } else if (t.equals(Float.class) || t.equals(Float.TYPE)) {
                if (s.isEmpty()) {
                    return Float.valueOf(0);
                } else {
                    return Float.valueOf(s);
                }
            } else if (t.equals(Long.class) || t.equals(Long.TYPE)) {
                if (s.isEmpty()) {
                    return Long.valueOf(0);
                } else {
                    return Long.valueOf(s);
                }
            } else if (t.equals(Short.class) || t.equals(Short.TYPE)) {
                if (s.isEmpty()) {
                    return Short.valueOf((short) 0);
                } else {
                    return Short.valueOf(s);
                }
            } else if (t.equals(String.class)) {
                return s;
            } else if (t.getName().equals("java.lang.Object")) {
                return new String(s);
            } else {
                return getValueFromPropertyEditorManager(t, propertyName, s);
            }
        } catch (Exception e) {
            throw new JasperException(e);
        }
    }


    public static void introspect(Object bean, ServletRequest request) throws JasperException {
        Enumeration<String> e = request.getParameterNames();
        while (e.hasMoreElements()) {
            String name = e.nextElement();
            String value = request.getParameter(name);
            introspecthelper(bean, name, value, request, name, true);
        }
    }


    public static void introspecthelper(Object bean, String prop, String value, ServletRequest request, String param,
            boolean ignoreMethodNF) throws JasperException {
        Method method = null;
        Class<?> type = null;
        Class<?> propertyEditorClass = null;
        try {
            if (GRAAL) {
                method = getWriteMethod(bean.getClass(), prop);
                if (method.getParameterTypes().length > 0) {
                    type = method.getParameterTypes()[0];
                }
            } else {
                java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(bean.getClass());
                if (info != null) {
                    java.beans.PropertyDescriptor[] pd = info.getPropertyDescriptors();
                    for (java.beans.PropertyDescriptor propertyDescriptor : pd) {
                        if (propertyDescriptor.getName().equals(prop)) {
                            method = propertyDescriptor.getWriteMethod();
                            type = propertyDescriptor.getPropertyType();
                            propertyEditorClass = propertyDescriptor.getPropertyEditorClass();
                            break;
                        }
                    }
                }
            }
            if (method != null && type != null) {
                if (type.isArray()) {
                    if (request == null) {
                        throw new JasperException(Localizer.getMessage("jsp.error.beans.setproperty.noindexset"));
                    }
                    Class<?> t = type.getComponentType();
                    String[] values = request.getParameterValues(param);
                    // XXX Please check.
                    if (values == null) {
                        return;
                    }
                    if (t.equals(String.class)) {
                        method.invoke(bean, new Object[] { values });
                    } else {
                        createTypedArray(prop, bean, method, values, t, propertyEditorClass);
                    }
                } else {
                    if (value == null || (param != null && value.isEmpty())) {
                        return;
                    }
                    Object oval = convert(prop, value, type, propertyEditorClass);
                    if (oval != null) {
                        method.invoke(bean, oval);
                    }
                }
            }
        } catch (Exception e) {
            Throwable thr = ExceptionUtils.unwrapInvocationTargetException(e);
            ExceptionUtils.handleThrowable(thr);
            throw new JasperException(e);
        }
        if (!ignoreMethodNF && (method == null)) {
            if (type == null) {
                throw new JasperException(
                        Localizer.getMessage("jsp.error.beans.noproperty", prop, bean.getClass().getName()));
            } else {
                throw new JasperException(Localizer.getMessage("jsp.error.beans.nomethod.setproperty", prop,
                        type.getName(), bean.getClass().getName()));
            }
        }
    }


    // -------------------------------------------------------------------
    // functions to convert builtin Java data types to string.
    // -------------------------------------------------------------------
    public static String toString(Object o) {
        return String.valueOf(o);
    }

    public static String toString(byte b) {
        return Byte.toString(b);
    }

    public static String toString(boolean b) {
        return Boolean.toString(b);
    }

    public static String toString(short s) {
        return Short.toString(s);
    }

    public static String toString(int i) {
        return Integer.toString(i);
    }

    public static String toString(float f) {
        return Float.toString(f);
    }

    public static String toString(long l) {
        return Long.toString(l);
    }

    public static String toString(double d) {
        return Double.toString(d);
    }

    public static String toString(char c) {
        return Character.toString(c);
    }


    /**
     * Create a typed array. This is a special case where params are passed through the request and the property is
     * indexed.
     *
     * @param propertyName        The property name
     * @param bean                The bean
     * @param method              The method
     * @param values              Array values
     * @param t                   The class
     * @param propertyEditorClass The editor for the property
     *
     * @throws JasperException An error occurred
     */
    public static void createTypedArray(String propertyName, Object bean, Method method, String[] values, Class<?> t,
            Class<?> propertyEditorClass) throws JasperException {

        try {
            if (propertyEditorClass != null) {
                Object[] tmpval = new Integer[values.length];
                for (int i = 0; i < values.length; i++) {
                    tmpval[i] = getValueFromBeanInfoPropertyEditor(t, propertyName, values[i], propertyEditorClass);
                }
                method.invoke(bean, new Object[] { tmpval });
            } else if (t.equals(Integer.class)) {
                Integer[] tmpval = new Integer[values.length];
                for (int i = 0; i < values.length; i++) {
                    tmpval[i] = Integer.valueOf(values[i]);
                }
                method.invoke(bean, new Object[] { tmpval });
            } else if (t.equals(Byte.class)) {
                Byte[] tmpval = new Byte[values.length];
                for (int i = 0; i < values.length; i++) {
                    tmpval[i] = Byte.valueOf(values[i]);
                }
                method.invoke(bean, new Object[] { tmpval });
            } else if (t.equals(Boolean.class)) {
                Boolean[] tmpval = new Boolean[values.length];
                for (int i = 0; i < values.length; i++) {
                    tmpval[i] = Boolean.valueOf(values[i]);
                }
                method.invoke(bean, new Object[] { tmpval });
            } else if (t.equals(Short.class)) {
                Short[] tmpval = new Short[values.length];
                for (int i = 0; i < values.length; i++) {
                    tmpval[i] = Short.valueOf(values[i]);
                }
                method.invoke(bean, new Object[] { tmpval });
            } else if (t.equals(Long.class)) {
                Long[] tmpval = new Long[values.length];
                for (int i = 0; i < values.length; i++) {
                    tmpval[i] = Long.valueOf(values[i]);
                }
                method.invoke(bean, new Object[] { tmpval });
            } else if (t.equals(Double.class)) {
                Double[] tmpval = new Double[values.length];
                for (int i = 0; i < values.length; i++) {
                    tmpval[i] = Double.valueOf(values[i]);
                }
                method.invoke(bean, new Object[] { tmpval });
            } else if (t.equals(Float.class)) {
                Float[] tmpval = new Float[values.length];
                for (int i = 0; i < values.length; i++) {
                    tmpval[i] = Float.valueOf(values[i]);
                }
                method.invoke(bean, new Object[] { tmpval });
            } else if (t.equals(Character.class)) {
                Character[] tmpval = new Character[values.length];
                for (int i = 0; i < values.length; i++) {
                    tmpval[i] = Character.valueOf(values[i].charAt(0));
                }
                method.invoke(bean, new Object[] { tmpval });
            } else if (t.equals(int.class)) {
                int[] tmpval = new int[values.length];
                for (int i = 0; i < values.length; i++) {
                    tmpval[i] = Integer.parseInt(values[i]);
                }
                method.invoke(bean, new Object[] { tmpval });
            } else if (t.equals(byte.class)) {
                byte[] tmpval = new byte[values.length];
                for (int i = 0; i < values.length; i++) {
                    tmpval[i] = Byte.parseByte(values[i]);
                }
                method.invoke(bean, new Object[] { tmpval });
            } else if (t.equals(boolean.class)) {
                boolean[] tmpval = new boolean[values.length];
                for (int i = 0; i < values.length; i++) {
                    tmpval[i] = Boolean.parseBoolean(values[i]);
                }
                method.invoke(bean, new Object[] { tmpval });
            } else if (t.equals(short.class)) {
                short[] tmpval = new short[values.length];
                for (int i = 0; i < values.length; i++) {
                    tmpval[i] = Short.parseShort(values[i]);
                }
                method.invoke(bean, new Object[] { tmpval });
            } else if (t.equals(long.class)) {
                long[] tmpval = new long[values.length];
                for (int i = 0; i < values.length; i++) {
                    tmpval[i] = Long.parseLong(values[i]);
                }
                method.invoke(bean, new Object[] { tmpval });
            } else if (t.equals(double.class)) {
                double[] tmpval = new double[values.length];
                for (int i = 0; i < values.length; i++) {
                    tmpval[i] = Double.parseDouble(values[i]);
                }
                method.invoke(bean, new Object[] { tmpval });
            } else if (t.equals(float.class)) {
                float[] tmpval = new float[values.length];
                for (int i = 0; i < values.length; i++) {
                    tmpval[i] = Float.parseFloat(values[i]);
                }
                method.invoke(bean, new Object[] { tmpval });
            } else if (t.equals(char.class)) {
                char[] tmpval = new char[values.length];
                for (int i = 0; i < values.length; i++) {
                    tmpval[i] = values[i].charAt(0);
                }
                method.invoke(bean, new Object[] { tmpval });
            } else {
                Object[] tmpval = new Integer[values.length];
                for (int i = 0; i < values.length; i++) {
                    tmpval[i] = getValueFromPropertyEditorManager(t, propertyName, values[i]);
                }
                method.invoke(bean, new Object[] { tmpval });
            }
        } catch (RuntimeException | ReflectiveOperationException ex) {
            Throwable thr = ExceptionUtils.unwrapInvocationTargetException(ex);
            ExceptionUtils.handleThrowable(thr);
            throw new JasperException("error in invoking method", ex);
        }
    }

    /**
     * Escape special shell characters.
     *
     * @param unescString The string to shell-escape
     *
     * @return The escaped shell string.
     */
    public static String escapeQueryString(String unescString) {
        if (unescString == null) {
            return null;
        }

        StringBuilder escStringBuilder = new StringBuilder();
        String shellSpChars = "&;`'\"|*?~<>^()[]{}$\\\n";

        for (int index = 0; index < unescString.length(); index++) {
            char nextChar = unescString.charAt(index);

            if (shellSpChars.indexOf(nextChar) != -1) {
                escStringBuilder.append('\\');
            }

            escStringBuilder.append(nextChar);
        }
        return escStringBuilder.toString();
    }


    public static Object handleGetProperty(Object o, String prop) throws JasperException {
        if (o == null) {
            throw new JasperException(Localizer.getMessage("jsp.error.beans.nullbean"));
        }
        Object value;
        try {
            Method method = getReadMethod(o.getClass(), prop);
            value = method.invoke(o, (Object[]) null);
        } catch (Exception e) {
            Throwable thr = ExceptionUtils.unwrapInvocationTargetException(e);
            ExceptionUtils.handleThrowable(thr);
            throw new JasperException(e);
        }
        return value;
    }

    // handles <jsp:setProperty> with EL expression for 'value' attribute
    public static void handleSetPropertyExpression(Object bean, String prop, String expression, PageContext pageContext,
            ProtectedFunctionMapper functionMapper) throws JasperException {
        try {
            Method method = getWriteMethod(bean.getClass(), prop);
            method.invoke(bean, PageContextImpl.proprietaryEvaluate(expression, method.getParameterTypes()[0],
                    pageContext, functionMapper));
        } catch (Exception e) {
            Throwable thr = ExceptionUtils.unwrapInvocationTargetException(e);
            ExceptionUtils.handleThrowable(thr);
            throw new JasperException(e);
        }
    }

    public static void handleSetProperty(Object bean, String prop, Object value) throws JasperException {
        try {
            Method method = getWriteMethod(bean.getClass(), prop);
            method.invoke(bean, value);
        } catch (Exception e) {
            Throwable thr = ExceptionUtils.unwrapInvocationTargetException(e);
            ExceptionUtils.handleThrowable(thr);
            throw new JasperException(e);
        }
    }

    public static void handleSetProperty(Object bean, String prop, int value) throws JasperException {
        try {
            Method method = getWriteMethod(bean.getClass(), prop);
            method.invoke(bean, Integer.valueOf(value));
        } catch (Exception e) {
            Throwable thr = ExceptionUtils.unwrapInvocationTargetException(e);
            ExceptionUtils.handleThrowable(thr);
            throw new JasperException(e);
        }
    }

    public static void handleSetProperty(Object bean, String prop, short value) throws JasperException {
        try {
            Method method = getWriteMethod(bean.getClass(), prop);
            method.invoke(bean, Short.valueOf(value));
        } catch (Exception e) {
            Throwable thr = ExceptionUtils.unwrapInvocationTargetException(e);
            ExceptionUtils.handleThrowable(thr);
            throw new JasperException(e);
        }
    }

    public static void handleSetProperty(Object bean, String prop, long value) throws JasperException {
        try {
            Method method = getWriteMethod(bean.getClass(), prop);
            method.invoke(bean, Long.valueOf(value));
        } catch (Exception e) {
            Throwable thr = ExceptionUtils.unwrapInvocationTargetException(e);
            ExceptionUtils.handleThrowable(thr);
            throw new JasperException(e);
        }
    }

    public static void handleSetProperty(Object bean, String prop, double value) throws JasperException {
        try {
            Method method = getWriteMethod(bean.getClass(), prop);
            method.invoke(bean, Double.valueOf(value));
        } catch (Exception e) {
            Throwable thr = ExceptionUtils.unwrapInvocationTargetException(e);
            ExceptionUtils.handleThrowable(thr);
            throw new JasperException(e);
        }
    }

    public static void handleSetProperty(Object bean, String prop, float value) throws JasperException {
        try {
            Method method = getWriteMethod(bean.getClass(), prop);
            method.invoke(bean, Float.valueOf(value));
        } catch (Exception e) {
            Throwable thr = ExceptionUtils.unwrapInvocationTargetException(e);
            ExceptionUtils.handleThrowable(thr);
            throw new JasperException(e);
        }
    }

    public static void handleSetProperty(Object bean, String prop, char value) throws JasperException {
        try {
            Method method = getWriteMethod(bean.getClass(), prop);
            method.invoke(bean, Character.valueOf(value));
        } catch (Exception e) {
            Throwable thr = ExceptionUtils.unwrapInvocationTargetException(e);
            ExceptionUtils.handleThrowable(thr);
            throw new JasperException(e);
        }
    }

    public static void handleSetProperty(Object bean, String prop, byte value) throws JasperException {
        try {
            Method method = getWriteMethod(bean.getClass(), prop);
            method.invoke(bean, Byte.valueOf(value));
        } catch (Exception e) {
            Throwable thr = ExceptionUtils.unwrapInvocationTargetException(e);
            ExceptionUtils.handleThrowable(thr);
            throw new JasperException(e);
        }
    }

    public static void handleSetProperty(Object bean, String prop, boolean value) throws JasperException {
        try {
            Method method = getWriteMethod(bean.getClass(), prop);
            method.invoke(bean, Boolean.valueOf(value));
        } catch (Exception e) {
            Throwable thr = ExceptionUtils.unwrapInvocationTargetException(e);
            ExceptionUtils.handleThrowable(thr);
            throw new JasperException(e);
        }
    }

    /**
     * Reverse of Introspector.decapitalize.
     *
     * @param name The name
     *
     * @return the capitalized string
     */
    public static String capitalize(String name) {
        if (name == null || name.isEmpty()) {
            return name;
        }
        char[] chars = name.toCharArray();
        chars[0] = Character.toUpperCase(chars[0]);
        return new String(chars);
    }

    public static Method getWriteMethod(Class<?> beanClass, String prop) throws JasperException {
        Method result = null;
        Class<?> type = null;
        if (GRAAL) {
            String setter = "set" + capitalize(prop);
            Method[] methods = beanClass.getMethods();
            for (Method method : methods) {
                if (setter.equals(method.getName())) {
                    return method;
                }
            }
        } else {
            try {
                java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(beanClass);
                java.beans.PropertyDescriptor[] pd = info.getPropertyDescriptors();
                for (java.beans.PropertyDescriptor propertyDescriptor : pd) {
                    if (propertyDescriptor.getName().equals(prop)) {
                        result = propertyDescriptor.getWriteMethod();
                        type = propertyDescriptor.getPropertyType();
                        break;
                    }
                }
            } catch (Exception e) {
                throw new JasperException(e);
            }
        }
        if (result == null) {
            if (type == null) {
                throw new JasperException(
                        Localizer.getMessage("jsp.error.beans.noproperty", prop, beanClass.getName()));
            } else {
                throw new JasperException(Localizer.getMessage("jsp.error.beans.nomethod.setproperty", prop,
                        type.getName(), beanClass.getName()));
            }
        }
        return result;
    }

    public static Method getReadMethod(Class<?> beanClass, String prop) throws JasperException {
        Method result = null;
        Class<?> type = null;
        if (GRAAL) {
            String setter = "get" + capitalize(prop);
            Method[] methods = beanClass.getMethods();
            for (Method method : methods) {
                if (setter.equals(method.getName())) {
                    return method;
                }
            }
        } else {
            try {
                java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(beanClass);
                java.beans.PropertyDescriptor[] pd = info.getPropertyDescriptors();
                for (java.beans.PropertyDescriptor propertyDescriptor : pd) {
                    if (propertyDescriptor.getName().equals(prop)) {
                        result = propertyDescriptor.getReadMethod();
                        type = propertyDescriptor.getPropertyType();
                        break;
                    }
                }
            } catch (Exception e) {
                throw new JasperException(e);
            }
        }
        if (result == null) {
            if (type == null) {
                throw new JasperException(
                        Localizer.getMessage("jsp.error.beans.noproperty", prop, beanClass.getName()));
            } else {
                throw new JasperException(Localizer.getMessage("jsp.error.beans.nomethod", prop, beanClass.getName()));
            }
        }
        return result;
    }

    // *********************************************************************
    // PropertyEditor Support

    public static Object getValueFromBeanInfoPropertyEditor(Class<?> attrClass, String attrName, String attrValue,
            Class<?> propertyEditorClass) throws JasperException {
        try {
            PropertyEditor pe = (PropertyEditor) propertyEditorClass.getConstructor().newInstance();
            pe.setAsText(attrValue);
            return pe.getValue();
        } catch (Exception e) {
            if (attrValue.isEmpty()) {
                return null;
            } else {
                throw new JasperException(Localizer.getMessage("jsp.error.beans.property.conversion", attrValue,
                        attrClass.getName(), attrName, e.getMessage()));
            }
        }
    }

    public static Object getValueFromPropertyEditorManager(Class<?> attrClass, String attrName, String attrValue)
            throws JasperException {
        try {
            PropertyEditor propEditor = PropertyEditorManager.findEditor(attrClass);
            if (propEditor != null) {
                propEditor.setAsText(attrValue);
                return propEditor.getValue();
            } else if (attrValue.isEmpty()) {
                return null;
            } else {
                throw new IllegalArgumentException(
                        Localizer.getMessage("jsp.error.beans.propertyeditor.notregistered"));
            }
        } catch (IllegalArgumentException ex) {
            if (attrValue.isEmpty()) {
                return null;
            } else {
                throw new JasperException(Localizer.getMessage("jsp.error.beans.property.conversion", attrValue,
                        attrClass.getName(), attrName, ex.getMessage()));
            }
        }
    }


    // ************************************************************************
    // General Purpose Runtime Methods
    // ************************************************************************


    /**
     * Convert a possibly relative resource path into a context-relative resource path that starts with a '/'.
     *
     * @param request      The servlet request we are processing
     * @param relativePath The possibly relative resource path
     *
     * @return an absolute path
     */
    public static String getContextRelativePath(ServletRequest request, String relativePath) {

        if (relativePath.startsWith("/")) {
            return relativePath;
        }
        if (!(request instanceof HttpServletRequest)) {
            return relativePath;
        }
        HttpServletRequest hrequest = (HttpServletRequest) request;
        String uri = (String) request.getAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH);
        if (uri != null) {
            String pathInfo = (String) request.getAttribute(RequestDispatcher.INCLUDE_PATH_INFO);
            if (pathInfo == null) {
                if (uri.lastIndexOf('/') >= 0) {
                    uri = uri.substring(0, uri.lastIndexOf('/'));
                }
            }
        } else {
            uri = hrequest.getServletPath();
            if (uri.lastIndexOf('/') >= 0) {
                uri = uri.substring(0, uri.lastIndexOf('/'));
            }
        }
        return uri + '/' + relativePath;

    }


    /**
     * Perform a RequestDispatcher.include() operation, with optional flushing of the response beforehand.
     *
     * @param request      The servlet request we are processing
     * @param response     The servlet response we are processing
     * @param relativePath The relative path of the resource to be included
     * @param out          The Writer to whom we are currently writing
     * @param flush        Should we flush before the include is processed?
     *
     * @exception IOException      if thrown by the included servlet
     * @exception ServletException if thrown by the included servlet
     */
    public static void include(ServletRequest request, ServletResponse response, String relativePath, JspWriter out,
            boolean flush) throws IOException, ServletException {

        if (flush && !(out instanceof BodyContent)) {
            out.flush();
        }

        // FIXME - It is tempting to use request.getRequestDispatcher() to
        // resolve a relative path directly, but Catalina currently does not
        // take into account whether the caller is inside a RequestDispatcher
        // include or not. Whether Catalina *should* take that into account
        // is a spec issue currently under review. In the mean time,
        // replicate Jasper's previous behavior

        String resourcePath = getContextRelativePath(request, relativePath);
        RequestDispatcher rd = request.getRequestDispatcher(resourcePath);
        if (rd != null) {
            rd.include(request, new ServletResponseWrapperInclude(response, out));
        } else {
            throw new JasperException(Localizer.getMessage("jsp.error.include.exception", resourcePath));
        }

    }

    /**
     * URL encodes a string, based on the supplied character encoding.
     *
     * @param s   The String to be URL encoded.
     * @param enc The character encoding
     *
     * @return The URL encoded String
     */
    public static String URLEncode(String s, String enc) {
        if (s == null) {
            return "null";
        }
        if (enc == null) {
            enc = "ISO-8859-1"; // The default request encoding
        }
        Charset cs;
        try {
            cs = Charset.forName(enc);
        } catch (Throwable t) {
            ExceptionUtils.handleThrowable(t);
            cs = StandardCharsets.ISO_8859_1;
        }
        return URLEncoder.encode(s, cs);
    }


    public static JspWriter startBufferedBody(PageContext pageContext, BodyTag tag) throws JspException {
        BodyContent out = pageContext.pushBody();
        tag.setBodyContent(out);
        tag.doInitBody();
        return out;
    }


    public static void releaseTag(Tag tag, InstanceManager instanceManager) {
        try {
            tag.release();
        } catch (Throwable t) {
            ExceptionUtils.handleThrowable(t);
            Log log = LogFactory.getLog(JspRuntimeLibrary.class);
            log.warn(Localizer.getMessage("jsp.warning.tagRelease", tag.getClass().getName()), t);
        }
        try {
            instanceManager.destroyInstance(tag);
        } catch (Exception e) {
            Throwable t = ExceptionUtils.unwrapInvocationTargetException(e);
            ExceptionUtils.handleThrowable(t);
            Log log = LogFactory.getLog(JspRuntimeLibrary.class);
            log.warn(Localizer.getMessage("jsp.warning.tagPreDestroy", tag.getClass().getName()), t);
        }

    }

    /**
     * This method parallels the logic of {@code SetSupport.doEndTag()}.
     *
     * @param pageContext pageContext
     * @param var         name of the variable
     * @param value       value to store
     * @param scope       scope
     */
    public static void nonstandardSetTag(jakarta.servlet.jsp.PageContext pageContext, String var, Object value,
            int scope) {
        if (value == null) {
            // matches SetTag and removes the key from the specified scope
            pageContext.removeAttribute(var, scope);
        } else {
            if (scope == PageContext.PAGE_SCOPE) {
                // matches SetTag and cleans up the VariableMapper
                VariableMapper vm = pageContext.getELContext().getVariableMapper();
                if (vm != null) {
                    vm.setVariable(var, null);
                }
            }
            // does the all-important set of the correct scope
            pageContext.setAttribute(var, value, scope);
        }
    }
}
