/*
 * 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.Array;
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 {

    /**
     * Indicates whether the code is running under GraalVM native image.
     */
    public static final boolean GRAAL;


    /**
     * Private constructor to prevent instantiation.
     */
    private JspRuntimeLibrary() {
    }

    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;
    }

    /**
     * Coerces a string to a boolean value.
     *
     * @param s The string to coerce
     * @return the boolean value, or false if the string is null/empty
     */
    public static boolean coerceToBoolean(String s) {
        if (s == null || s.isEmpty()) {
            return false;
        } else {
            return Boolean.parseBoolean(s);
        }
    }

    /**
     * Coerces a string to a byte value.
     *
     * @param s The string to coerce
     * @return the byte value, or 0 if the string is null/empty
     */
    public static byte coerceToByte(String s) {
        if (s == null || s.isEmpty()) {
            return (byte) 0;
        } else {
            return Byte.parseByte(s);
        }
    }

    /**
     * Coerces a string to a char value.
     *
     * @param s The string to coerce
     * @return the char value, or 0 if the string is null/empty
     */
    public static char coerceToChar(String s) {
        if (s == null || s.isEmpty()) {
            return (char) 0;
        } else {
            return s.charAt(0);
        }
    }

    /**
     * Coerces a string to a double value.
     *
     * @param s The string to coerce
     * @return the double value, or 0 if the string is null/empty
     */
    public static double coerceToDouble(String s) {
        if (s == null || s.isEmpty()) {
            return 0;
        } else {
            return Double.parseDouble(s);
        }
    }

    /**
     * Coerces a string to a float value.
     *
     * @param s The string to coerce
     * @return the float value, or 0 if the string is null/empty
     */
    public static float coerceToFloat(String s) {
        if (s == null || s.isEmpty()) {
            return 0;
        } else {
            return Float.parseFloat(s);
        }
    }

    /**
     * Coerces a string to an int value.
     *
     * @param s The string to coerce
     * @return the int value, or 0 if the string is null/empty
     */
    public static int coerceToInt(String s) {
        if (s == null || s.isEmpty()) {
            return 0;
        } else {
            return Integer.parseInt(s);
        }
    }

    /**
     * Coerces a string to a short value.
     *
     * @param s The string to coerce
     * @return the short value, or 0 if the string is null/empty
     */
    public static short coerceToShort(String s) {
        if (s == null || s.isEmpty()) {
            return (short) 0;
        } else {
            return Short.parseShort(s);
        }
    }

    /**
     * Coerces a string to a long value.
     *
     * @param s The string to coerce
     * @return the long value, or 0 if the string is null/empty
     */
    public static long coerceToLong(String s) {
        if (s == null || s.isEmpty()) {
            return 0;
        } else {
            return Long.parseLong(s);
        }
    }

    /**
     * Coerces a string to the target type.
     *
     * @param s The string to coerce
     * @param target The target class
     * @return the coerced value
     */
    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;
        }
    }


    /**
     * Converts a string value to the target type, using a property editor if specified.
     *
     * @param propertyName The property name
     * @param s The string value to convert
     * @param t The target class
     * @param propertyEditorClass The property editor class, or {@code null}
     * @return the converted value
     * @throws JasperException if conversion fails
     */
    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);
        }
    }


    /**
     * Sets bean properties from request parameters.
     *
     * @param bean The bean
     * @param request The servlet request
     * @throws JasperException if setting a property fails
     */
    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);
        }
    }


    /**
     * Sets a single bean property from a string value.
     *
     * @param bean The bean
     * @param prop The property name
     * @param value The string value
     * @param request The servlet request
     * @param param The parameter name
     * @param ignoreMethodNF Whether to ignore missing methods
     * @throws JasperException if setting the property fails
     */
    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.
    // -------------------------------------------------------------------
    /**
     * Converts an object to its string representation.
     *
     * @param o The object
     * @return the string representation
     */
    public static String toString(Object o) {
        return String.valueOf(o);
    }

    /**
     * Converts a byte to its string representation.
     *
     * @param b The byte value
     * @return the string representation
     */
    public static String toString(byte b) {
        return Byte.toString(b);
    }

    /**
     * Converts a boolean to its string representation.
     *
     * @param b The boolean value
     * @return the string representation
     */
    public static String toString(boolean b) {
        return Boolean.toString(b);
    }

    /**
     * Converts a short to its string representation.
     *
     * @param s The short value
     * @return the string representation
     */
    public static String toString(short s) {
        return Short.toString(s);
    }

    /**
     * Converts an int to its string representation.
     *
     * @param i The int value
     * @return the string representation
     */
    public static String toString(int i) {
        return Integer.toString(i);
    }

    /**
     * Converts a float to its string representation.
     *
     * @param f The float value
     * @return the string representation
     */
    public static String toString(float f) {
        return Float.toString(f);
    }

    /**
     * Converts a long to its string representation.
     *
     * @param l The long value
     * @return the string representation
     */
    public static String toString(long l) {
        return Long.toString(l);
    }

    /**
     * Converts a double to its string representation.
     *
     * @param d The double value
     * @return the string representation
     */
    public static String toString(double d) {
        return Double.toString(d);
    }

    /**
     * Converts a char to its string representation.
     *
     * @param c The char value
     * @return the string representation
     */
    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 = Array.newInstance(t, values.length);
                for (int i = 0; i < values.length; i++) {
                    Array.set(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 = (Object[]) Array.newInstance(t, 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();
    }


    /**
     * Gets the value of a bean property.
     *
     * @param o The bean
     * @param prop The property name
     * @return the property value
     * @throws JasperException if getting the property fails
     */
    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;
    }

    /**
     * Sets a bean property from an EL expression.
     *
     * @param bean The bean
     * @param prop The property name
     * @param expression The EL expression
     * @param pageContext The page context
     * @param functionMapper The function mapper
     * @throws JasperException if setting the property fails
     */
    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);
        }
    }

    /**
     * Sets a bean property to the given value.
     *
     * @param bean The bean
     * @param prop The property name
     * @param value The value to set
     * @throws JasperException if setting the property fails
     */
    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);
        }
    }

    /**
     * Sets a bean property to the given int value.
     *
     * @param bean The bean
     * @param prop The property name
     * @param value The value to set
     * @throws JasperException if setting the property fails
     */
    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);
        }
    }

    /**
     * Sets a bean property to the given short value.
     *
     * @param bean The bean
     * @param prop The property name
     * @param value The value to set
     * @throws JasperException if setting the property fails
     */
    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);
        }
    }

    /**
     * Sets a bean property to the given long value.
     *
     * @param bean The bean
     * @param prop The property name
     * @param value The value to set
     * @throws JasperException if setting the property fails
     */
    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);
        }
    }

    /**
     * Sets a bean property to the given double value.
     *
     * @param bean The bean
     * @param prop The property name
     * @param value The value to set
     * @throws JasperException if setting the property fails
     */
    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);
        }
    }

    /**
     * Sets a bean property to the given float value.
     *
     * @param bean The bean
     * @param prop The property name
     * @param value The value to set
     * @throws JasperException if setting the property fails
     */
    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);
        }
    }

    /**
     * Sets a bean property to the given char value.
     *
     * @param bean The bean
     * @param prop The property name
     * @param value The value to set
     * @throws JasperException if setting the property fails
     */
    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);
        }
    }

    /**
     * Sets a bean property to the given byte value.
     *
     * @param bean The bean
     * @param prop The property name
     * @param value The value to set
     * @throws JasperException if setting the property fails
     */
    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);
        }
    }

    /**
     * Sets a bean property to the given boolean value.
     *
     * @param bean The bean
     * @param prop The property name
     * @param value The value to set
     * @throws JasperException if setting the property fails
     */
    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);
    }

    /**
     * Gets the write method (setter) for a bean property.
     *
     * @param beanClass The bean class
     * @param prop The property name
     * @return the write method
     * @throws JasperException if the property or write method cannot be found
     */
    public static Method getWriteMethod(Class<?> beanClass, String prop) throws JasperException {
        Method result = null;
        Class<?> type = null;
        if (GRAAL) {
            // BeanInfo is approximated with 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;
    }

    /**
     * Gets the read method (getter) for a bean property.
     *
     * @param beanClass The bean class
     * @param prop The property name
     * @return the read method
     * @throws JasperException if the property or read method cannot be found
     */
    public static Method getReadMethod(Class<?> beanClass, String prop) throws JasperException {
        Method result = null;
        Class<?> type = null;
        if (GRAAL) {
            // BeanInfo is approximated with Graal
            String getter = "get" + capitalize(prop);
            Method[] methods = beanClass.getMethods();
            for (Method method : methods) {
                if (getter.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

    /**
     * Gets a value using a bean info property editor.
     *
     * @param attrClass The attribute class
     * @param attrName The attribute name
     * @param attrValue The attribute value as a string
     * @param propertyEditorClass The property editor class
     * @return the converted value
     * @throws JasperException if conversion fails
     */
    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()));
            }
        }
    }

    /**
     * Gets a value using the property editor manager.
     *
     * @param attrClass The attribute class
     * @param attrName The attribute name
     * @param attrValue The attribute value as a string
     * @return the converted value
     * @throws JasperException if conversion fails
     */
    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);
    }


    /**
     * Starts a buffered body for a tag that supports body content.
     *
     * @param pageContext The page context
     * @param tag The body tag
     * @return the JspWriter for the body content
     * @throws JspException if starting the buffered body fails
     */
    public static JspWriter startBufferedBody(PageContext pageContext, BodyTag tag) throws JspException {
        BodyContent out = pageContext.pushBody();
        tag.setBodyContent(out);
        tag.doInitBody();
        return out;
    }


    /**
     * Releases a tag and destroys its instance if it has not been re-used.
     *
     * @param tag The tag to release
     * @param instanceManager The instance manager
     * @param reused Has the tag successfully been re-used
     */
    public static void releaseTag(Tag tag, InstanceManager instanceManager, boolean reused) {
        // Caller ensures pool is non-null if reuse is true
        if (!reused) {
            releaseTag(tag, instanceManager);
        }
    }


    /**
     * Releases a tag and destroys its instance.
     *
     * @param tag The tag to release
     * @param instanceManager The instance manager
     */
    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);
        }
    }
}
