/*
 * 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.beans.PropertyEditor;
import java.beans.PropertyEditorManager;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Enumeration;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.BodyContent;

import org.apache.jasper.JasperException;
import org.apache.jasper.compiler.Localizer;

/**
 * Bunch of util methods that are used by code generated for useBean,
 * getProperty and setProperty.  
 *
 * The __begin, __end stuff is there so that the JSP engine can
 * actually parse this file and inline them if people don't want
 * runtime dependencies on this class. However, I'm not sure if that
 * works so well right now. It got forgotten at some point. -akv
 *
 * @author Mandar Raje
 * @author Shawn Bayern
 */
public class JspRuntimeLibrary {
    
    private static final String SERVLET_EXCEPTION
	= "javax.servlet.error.exception";
    private static final String JSP_EXCEPTION
	= "javax.servlet.jsp.jspException";

    protected static class PrivilegedIntrospectHelper
	implements PrivilegedExceptionAction {

	private Object bean;
	private String prop;
	private String value;
	private ServletRequest request;
	private String param;
	private boolean ignoreMethodNF;

        PrivilegedIntrospectHelper(Object bean, String prop,
                                   String value, ServletRequest request,
                                   String param, boolean ignoreMethodNF)
        {
	    this.bean = bean;
	    this.prop = prop;
	    this.value = value;
            this.request = request;
	    this.param = param;
	    this.ignoreMethodNF = ignoreMethodNF;
        }
         
        public Object run() throws JasperException {
	    internalIntrospecthelper(
                bean,prop,value,request,param,ignoreMethodNF);
            return null;
        }
    }

    /**
     * Returns the value of the javax.servlet.error.exception request
     * attribute value, if present, otherwise the value of the
     * javax.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.
     */
    public static Throwable getThrowable(ServletRequest request) {
	Throwable error = (Throwable) request.getAttribute(SERVLET_EXCEPTION);
	if (error == null) {
	    error = (Throwable) request.getAttribute(JSP_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(SERVLET_EXCEPTION, error);
	    }
	}

	return error;
    }

    public static boolean coerceToBoolean(String s) {
	if (s == null || s.length() == 0)
	    return false;
	else
	    return Boolean.valueOf(s).booleanValue();
    }

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

    public static char coerceToChar(String s) {
	if (s == null || s.length() == 0) {
	    return (char) 0;
	} else {
	    // this trick avoids escaping issues
	    return (char)(int) s.charAt(0);
	}
    }

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

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

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

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

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

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

	boolean isNullOrEmpty = (s == null || s.length() == 0);

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

   // __begin convertMethod
    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) ) {
                if (s.equalsIgnoreCase("on") || s.equalsIgnoreCase("true"))
                    s = "true";
                else
                    s = "false";
                return new Boolean(s);
            } else if ( t.equals(Byte.class) || t.equals(Byte.TYPE) ) {
                return new Byte(s);
            } else if (t.equals(Character.class) || t.equals(Character.TYPE)) {
                return s.length() > 0 ? new Character(s.charAt(0)) : null;
            } else if ( t.equals(Short.class) || t.equals(Short.TYPE) ) {
                return new Short(s);
            } else if ( t.equals(Integer.class) || t.equals(Integer.TYPE) ) {
                return new Integer(s);
            } else if ( t.equals(Float.class) || t.equals(Float.TYPE) ) {
                return new Float(s);
            } else if ( t.equals(Long.class) || t.equals(Long.TYPE) ) {
                return new Long(s);
            } else if ( t.equals(Double.class) || t.equals(Double.TYPE) ) {
                return new Double(s);
            } else if ( t.equals(String.class) ) {
                return s;
            } else if ( t.equals(java.io.File.class) ) {
                return new java.io.File(s);
            } else if (t.getName().equals("java.lang.Object")) {
                return new Object[] {s};
	    } else {
		return getValueFromPropertyEditorManager(
                                            t, propertyName, s);
            }
        } catch (Exception ex) {
            throw new JasperException(ex);
        }
    }
    // __end convertMethod

    // __begin introspectMethod
    public static void introspect(Object bean, ServletRequest request)
                                  throws JasperException
    {
	Enumeration e = request.getParameterNames();
	while ( e.hasMoreElements() ) {
	    String name  = (String) e.nextElement();
	    String value = request.getParameter(name);
	    introspecthelper(bean, name, value, request, name, true);
	}
    }
    // __end introspectMethod
    
    // __begin introspecthelperMethod
    public static void introspecthelper(Object bean, String prop,
                                        String value, ServletRequest request,
                                        String param, boolean ignoreMethodNF)
                                        throws JasperException
    {
        if( System.getSecurityManager() != null ) {
            try {
                PrivilegedIntrospectHelper dp =
		    new PrivilegedIntrospectHelper(
			bean,prop,value,request,param,ignoreMethodNF);
                AccessController.doPrivileged(dp);
            } catch( PrivilegedActionException pe) {
                Exception e = pe.getException();
                throw (JasperException)e;
            }
        } else {
            internalIntrospecthelper(
		bean,prop,value,request,param,ignoreMethodNF);
        }
    }

    private static void internalIntrospecthelper(Object bean, String prop,
					String value, ServletRequest request,
					String param, boolean ignoreMethodNF) 
					throws JasperException
    {
        Method method = null;
        Class type = null;
        Class propertyEditorClass = null;
	try {
	    java.beans.BeanInfo info
		= java.beans.Introspector.getBeanInfo(bean.getClass());
	    if ( info != null ) {
		java.beans.PropertyDescriptor pd[]
		    = info.getPropertyDescriptors();
		for (int i = 0 ; i < pd.length ; i++) {
		    if ( pd[i].getName().equals(prop) ) {
			method = pd[i].getWriteMethod();
			type   = pd[i].getPropertyType();
			propertyEditorClass = pd[i].getPropertyEditorClass();
			break;
		    }
		}
	    }
	    if ( method != 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 {
			Object tmpval = null;
			createTypedArray (prop, bean, method, values, t,
					  propertyEditorClass); 
		    }
		} else {
		    if(value == null || (param != null && value.equals(""))) return;
		    Object oval = convert(prop, value, type, propertyEditorClass);
		    if ( oval != null )
			method.invoke(bean, new Object[] { oval });
		}
	    }
	} catch (Exception ex) {
	    throw new JasperException(ex);
	}
        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()));
            }
        }
    }
    // __end introspecthelperMethod
    
    //-------------------------------------------------------------------
    // functions to convert builtin Java data types to string.
    //-------------------------------------------------------------------
    // __begin toStringMethod
    public static String toString(Object o) {
        return String.valueOf(o);
    }

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

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

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

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

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

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

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

    public static String toString(char c) {
        return new Character(c).toString();
    }
    // __end toStringMethod


    /**
     * Create a typed array.
     * This is a special case where params are passed through
     * the request and the property is indexed.
     */
    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] =  new Integer (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] = new Byte (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] = new Boolean (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] = new Short (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] = new Long (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] = new Double (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] = new Float (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] = new Character(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.valueOf(values[i])).booleanValue();
		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.valueOf(values[i]).doubleValue();
		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]).floatValue();
		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 (Exception ex) {
            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;
   
    String escString    = "";
    String shellSpChars = "&;`'\"|*?~<>^()[]{}$\\\n";
   
    for(int index=0; index<unescString.length(); index++) {
        char nextChar = unescString.charAt(index);

        if( shellSpChars.indexOf(nextChar) != -1 )
        escString += "\\";

        escString += nextChar;
    }
    return escString;
    }

    /**
     * Decode an URL formatted string.
     * @param encoded The string to decode.
     * @return The decoded string.
     */

    public static String decode(String encoded) {
        // speedily leave if we're not needed
    if (encoded == null) return null;
        if (encoded.indexOf('%') == -1 && encoded.indexOf('+') == -1)
        return encoded;

    //allocate the buffer - use byte[] to avoid calls to new.
        byte holdbuffer[] = new byte[encoded.length()];

        char holdchar;
        int bufcount = 0;

        for (int count = 0; count < encoded.length(); count++) {
        char cur = encoded.charAt(count);
            if (cur == '%') {
            holdbuffer[bufcount++] =
          (byte)Integer.parseInt(encoded.substring(count+1,count+3),16);
                if (count + 2 >= encoded.length())
                    count = encoded.length();
                else
                    count += 2;
            } else if (cur == '+') {
        holdbuffer[bufcount++] = (byte) ' ';
        } else {
            holdbuffer[bufcount++] = (byte) cur;
            }
        }
	// REVISIT -- remedy for Deprecated warning.
    //return new String(holdbuffer,0,0,bufcount);
    return new String(holdbuffer,0,bufcount);
    }

    // __begin lookupReadMethodMethod
    public static Object handleGetProperty(Object o, String prop)
    throws JasperException {
        if (o == null) {
	    throw new JasperException(
	            Localizer.getMessage("jsp.error.beans.nullbean"));
        }
	Object value = null;
        try {
            Method method = getReadMethod(o.getClass(), prop);
	    value = method.invoke(o, null);
        } catch (Exception ex) {
	    throw new JasperException (ex);
        }
        return value;
    }
    // __end lookupReadMethodMethod

    // handles <jsp:setProperty> with EL expression for 'value' attribute
/** Use proprietaryEvaluate
    public static void handleSetPropertyExpression(Object bean,
        String prop, String expression, PageContext pageContext,
        VariableResolver variableResolver, FunctionMapper functionMapper )
	throws JasperException
    {
	try {
            Method method = getWriteMethod(bean.getClass(), prop);
	    method.invoke(bean, new Object[] { 
		pageContext.getExpressionEvaluator().evaluate(
		    expression,
		    method.getParameterTypes()[0],
                    variableResolver,
                    functionMapper,
                    null )
	    });
	} catch (Exception ex) {
	    throw new JasperException(ex);
	}
    }
**/
    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, new Object[] {
                PageContextImpl.proprietaryEvaluate(
                    expression,
                    method.getParameterTypes()[0],
		    pageContext,
                    functionMapper,
                    false )
            });
        } catch (Exception ex) {
            throw new JasperException(ex);
        }
    }

    public static void handleSetProperty(Object bean, String prop,
					 Object value)
	throws JasperException
    {
	try {
            Method method = getWriteMethod(bean.getClass(), prop);
	    method.invoke(bean, new Object[] { value });
	} catch (Exception ex) {
	    throw new JasperException(ex);
	}
    }
    
    public static void handleSetProperty(Object bean, String prop,
					 int value)
	throws JasperException
    {
	try {
            Method method = getWriteMethod(bean.getClass(), prop);
	    method.invoke(bean, new Object[] { new Integer(value) });
	} catch (Exception ex) {
	    throw new JasperException(ex);
	}	
    }
    
    public static void handleSetProperty(Object bean, String prop,
					 short value)
	throws JasperException
    {
	try {
            Method method = getWriteMethod(bean.getClass(), prop);
	    method.invoke(bean, new Object[] { new Short(value) });
	} catch (Exception ex) {
	    throw new JasperException(ex);
	}	
    }
    
    public static void handleSetProperty(Object bean, String prop,
					 long value)
	throws JasperException
    {
	try {
            Method method = getWriteMethod(bean.getClass(), prop);
	    method.invoke(bean, new Object[] { new Long(value) });
	} catch (Exception ex) {
	    throw new JasperException(ex);
	}	
    } 
    
    public static void handleSetProperty(Object bean, String prop,
					 double value)
	throws JasperException
    {
	try {
            Method method = getWriteMethod(bean.getClass(), prop);
	    method.invoke(bean, new Object[] { new Double(value) });
	} catch (Exception ex) {
	    throw new JasperException(ex);
	}	
    }
    
    public static void handleSetProperty(Object bean, String prop,
					 float value)
	throws JasperException
    {
	try {
            Method method = getWriteMethod(bean.getClass(), prop);
	    method.invoke(bean, new Object[] { new Float(value) });
	} catch (Exception ex) {
	    throw new JasperException(ex);
	}	
    }
    
    public static void handleSetProperty(Object bean, String prop,
					 char value)
	throws JasperException
    {
	try {
            Method method = getWriteMethod(bean.getClass(), prop);
	    method.invoke(bean, new Object[] { new Character(value) });
	} catch (Exception ex) {
	    throw new JasperException(ex);
	}	
    }

    public static void handleSetProperty(Object bean, String prop,
					 byte value)
	throws JasperException
    {
	try {
            Method method = getWriteMethod(bean.getClass(), prop);
	    method.invoke(bean, new Object[] { new Byte(value) });
	} catch (Exception ex) {
	    throw new JasperException(ex);
	}	
    }
    
    public static void handleSetProperty(Object bean, String prop,
					 boolean value)
	throws JasperException
    {
	try {
            Method method = getWriteMethod(bean.getClass(), prop);
	    method.invoke(bean, new Object[] { new Boolean(value) });
	} catch (Exception ex) {
	    throw new JasperException(ex);
	}	
    }
    
    public static Method getWriteMethod(Class beanClass, String prop)
    throws JasperException {
	Method method = null;	
        Class type = null;
	try {
	    java.beans.BeanInfo info
                = java.beans.Introspector.getBeanInfo(beanClass);
	    if ( info != null ) {
		java.beans.PropertyDescriptor pd[]
		    = info.getPropertyDescriptors();
		for (int i = 0 ; i < pd.length ; i++) {
		    if ( pd[i].getName().equals(prop) ) {
			method = pd[i].getWriteMethod();
			type   = pd[i].getPropertyType();
			break;
		    }
		}
            } else {        
                // just in case introspection silently fails.
                throw new JasperException(
                    Localizer.getMessage("jsp.error.beans.nobeaninfo",
					 beanClass.getName()));
            }
        } catch (Exception ex) {
            throw new JasperException (ex);
        }
        if (method == 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 method;
    }

    public static Method getReadMethod(Class beanClass, String prop)
	    throws JasperException {

        Method method = null;        
        Class type = null;
        try {
            java.beans.BeanInfo info
                = java.beans.Introspector.getBeanInfo(beanClass);
            if ( info != null ) {
                java.beans.PropertyDescriptor pd[]
                    = info.getPropertyDescriptors();
                for (int i = 0 ; i < pd.length ; i++) {
                    if ( pd[i].getName().equals(prop) ) {
                        method = pd[i].getReadMethod();
                        type   = pd[i].getPropertyType();
                        break;
                    }
                }
            } else {        
                // just in case introspection silently fails.
		throw new JasperException(
                    Localizer.getMessage("jsp.error.beans.nobeaninfo",
					 beanClass.getName()));
	    }
	} catch (Exception ex) {
	    throw new JasperException (ex);
	}
        if (method == 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 method;
    }

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

    public static Object getValueFromBeanInfoPropertyEditor(
		           Class attrClass, String attrName, String attrValue,
			   Class propertyEditorClass) 
	throws JasperException 
    {
	try {
	    PropertyEditor pe = (PropertyEditor)propertyEditorClass.newInstance();
	    pe.setAsText(attrValue);
	    return pe.getValue();
	} catch (Exception ex) {
	    throw new JasperException(
                Localizer.getMessage("jsp.error.beans.property.conversion",
				     attrValue, attrClass.getName(), attrName,
				     ex.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 {
		throw new IllegalArgumentException(
                    Localizer.getMessage("jsp.error.beans.propertyeditor.notregistered"));
	    }
	} catch (IllegalArgumentException ex) {
	    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
     */
    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("javax.servlet.include.servlet_path");
        if (uri != null) {
            String pathInfo = (String)
                request.getAttribute("javax.servlet.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);

        rd.include(request,
                   new ServletResponseWrapperInclude(response, out));

    }

    /**
     * URL encodes a string, based on the supplied character encoding.
     * This performs the same function as java.next.URLEncode.encode
     * in J2SDK1.4, and should be removed if the only platform supported
     * is 1.4 or higher.
     * @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 
	}

	StringBuffer out = new StringBuffer(s.length());
	ByteArrayOutputStream buf = new ByteArrayOutputStream();
	OutputStreamWriter writer = null;
	try {
	    writer = new OutputStreamWriter(buf, enc);
	} catch (java.io.UnsupportedEncodingException ex) {
	    // Use the default encoding?
	    writer = new OutputStreamWriter(buf);
	}
	
	for (int i = 0; i < s.length(); i++) {
	    int c = s.charAt(i);
	    if (c == ' ') {
		out.append('+');
	    } else if (isSafeChar(c)) {
		out.append((char)c);
	    } else {
		// convert to external encoding before hex conversion
		try {
		    writer.write(c);
		    writer.flush();
		} catch(IOException e) {
		    buf.reset();
		    continue;
		}
		byte[] ba = buf.toByteArray();
		for (int j = 0; j < ba.length; j++) {
		    out.append('%');
		    // Converting each byte in the buffer
		    out.append(Character.forDigit((ba[j]>>4) & 0xf, 16));
		    out.append(Character.forDigit(ba[j] & 0xf, 16));
		}
		buf.reset();
	    }
	}
	return out.toString();
    }

    private static boolean isSafeChar(int c) {
	if (c >= 'a' && c <= 'z') {
	    return true;
	}
	if (c >= 'A' && c <= 'Z') {
	    return true;
	}
	if (c >= '0' && c <= '9') {
	    return true;
	}
	if (c == '-' || c == '_' || c == '.' || c == '!' ||
	    c == '~' || c == '*' || c == '\'' || c == '(' || c == ')') {
	    return true;
	}
	return false;
    }

}
