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

import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.Vector;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;

import javax.servlet.jsp.el.ELException;
import javax.servlet.jsp.el.ELParseException;
import javax.servlet.jsp.el.FunctionMapper;

import org.apache.commons.el.ExpressionEvaluatorImpl;
import org.apache.jasper.Constants;
import org.apache.jasper.JasperException;
import org.apache.jasper.JspCompilationContext;
import org.xml.sax.Attributes;

/** 
 * This class has all the utility method(s).
 * Ideally should move all the bean containers here.
 *
 * @author Mandar Raje.
 * @author Rajiv Mordani.
 * @author Danno Ferrin
 * @author Pierre Delisle
 * @author Shawn Bayern
 * @author Mark Roth
 */
public class JspUtil {

    private static final String WEB_INF_TAGS = "/WEB-INF/tags/";
    private static final String META_INF_TAGS = "/META-INF/tags/";

    // Delimiters for request-time expressions (JSP and XML syntax)
    private static final String OPEN_EXPR  = "<%=";
    private static final String CLOSE_EXPR = "%>";
    private static final String OPEN_EXPR_XML  = "%=";
    private static final String CLOSE_EXPR_XML = "%";

    private static int tempSequenceNumber = 0;
    private static ExpressionEvaluatorImpl expressionEvaluator
	= new ExpressionEvaluatorImpl();

    private static final String javaKeywords[] = {
        "abstract", "assert", "boolean", "break", "byte", "case",
        "catch", "char", "class", "const", "continue",
        "default", "do", "double", "else", "enum", "extends",
        "final", "finally", "float", "for", "goto",
        "if", "implements", "import", "instanceof", "int",
        "interface", "long", "native", "new", "package",
        "private", "protected", "public", "return", "short",
        "static", "strictfp", "super", "switch", "synchronized",
        "this", "throws", "transient", "try", "void",
        "volatile", "while" };

    public static final int CHUNKSIZE = 1024;
        
    public static char[] removeQuotes(char []chars) {
        CharArrayWriter caw = new CharArrayWriter();
        for (int i = 0; i < chars.length; i++) {
            if (chars[i] == '%' && chars[i+1] == '\\' &&
                chars[i+2] == '>') {
                caw.write('%');
                caw.write('>');
                i = i + 2;
            } else {
                caw.write(chars[i]);
            }
        }
        return caw.toCharArray();
    }

    public static char[] escapeQuotes (char []chars) {
        // Prescan to convert %\> to %>
        String s = new String(chars);
        while (true) {
            int n = s.indexOf("%\\>");
            if (n < 0)
                break;
            StringBuffer sb = new StringBuffer(s.substring(0, n));
            sb.append("%>");
            sb.append(s.substring(n + 3));
            s = sb.toString();
        }
        chars = s.toCharArray();
        return (chars);


        // Escape all backslashes not inside a Java string literal
        /*
        CharArrayWriter caw = new CharArrayWriter();
        boolean inJavaString = false;
        for (int i = 0; i < chars.length; i++) {
            if (chars[i] == '"') inJavaString = !inJavaString;
            // escape out the escape character
            if (!inJavaString && (chars[i] == '\\')) caw.write('\\');
            caw.write(chars[i]);
        }
        return caw.toCharArray();
        */
    }

    /**
     * Checks if the token is a runtime expression.
     * In standard JSP syntax, a runtime expression starts with '<%' and
     * ends with '%>'. When the JSP document is in XML syntax, a runtime
     * expression starts with '%=' and ends with '%'.
     *
     * @param token The token to be checked
     * return whether the token is a runtime expression or not.
     */
    public static boolean isExpression(String token, boolean isXml) {
	String openExpr;
	String closeExpr;
	if (isXml) {
	    openExpr = OPEN_EXPR_XML;
	    closeExpr = CLOSE_EXPR_XML;
	} else {
	    openExpr = OPEN_EXPR;
	    closeExpr = CLOSE_EXPR;
	}
	if (token.startsWith(openExpr) && token.endsWith(closeExpr)) {
	    return true;
	} else {
	    return false;
	}
    }

    /**
     * @return the "expression" part of a runtime expression, 
     * taking the delimiters out.
     */
    public static String getExpr (String expression, boolean isXml) {
	String returnString;
	String openExpr;
	String closeExpr;
	if (isXml) {
	    openExpr = OPEN_EXPR_XML;
	    closeExpr = CLOSE_EXPR_XML;
	} else {
	    openExpr = OPEN_EXPR;
	    closeExpr = CLOSE_EXPR;
	}
	int length = expression.length();
	if (expression.startsWith(openExpr) && 
                expression.endsWith(closeExpr)) {
	    returnString = expression.substring(
                               openExpr.length(), length - closeExpr.length());
	} else {
	    returnString = "";
	}
	return returnString;
    }

    /**
     * Takes a potential expression and converts it into XML form
     */
    public static String getExprInXml(String expression) {
        String returnString;
        int length = expression.length();

        if (expression.startsWith(OPEN_EXPR) 
                && expression.endsWith(CLOSE_EXPR)) {
            returnString = expression.substring (1, length - 1);
        } else {
            returnString = expression;
        }

        return escapeXml(returnString.replace(Constants.ESC, '$'));
    }

    /**
     * Checks to see if the given scope is valid.
     *
     * @param scope The scope to be checked
     * @param n The Node containing the 'scope' attribute whose value is to be
     * checked
     * @param err error dispatcher
     *
     * @throws JasperException if scope is not null and different from
     * &quot;page&quot;, &quot;request&quot;, &quot;session&quot;, and
     * &quot;application&quot;
     */
    public static void checkScope(String scope, Node n, ErrorDispatcher err)
            throws JasperException {
	if (scope != null && !scope.equals("page") && !scope.equals("request")
		&& !scope.equals("session") && !scope.equals("application")) {
	    err.jspError(n, "jsp.error.invalid.scope", scope);
	}
    }

    /**
     * Checks if all mandatory attributes are present and if all attributes
     * present have valid names.  Checks attributes specified as XML-style
     * attributes as well as attributes specified using the jsp:attribute
     * standard action. 
     */
    public static void checkAttributes(String typeOfTag,
				       Node n,
				       ValidAttribute[] validAttributes,
				       ErrorDispatcher err)
				throws JasperException {
        Attributes attrs = n.getAttributes();
        Mark start = n.getStart();
	boolean valid = true;

        // AttributesImpl.removeAttribute is broken, so we do this...
        int tempLength = (attrs == null) ? 0 : attrs.getLength();
	Vector temp = new Vector(tempLength, 1);
        for (int i = 0; i < tempLength; i++) {
            String qName = attrs.getQName(i);
            if ((!qName.equals("xmlns")) && (!qName.startsWith("xmlns:")))
                temp.addElement(qName);
        }

        // Add names of attributes specified using jsp:attribute
        Node.Nodes tagBody = n.getBody();
        if( tagBody != null ) {
            int numSubElements = tagBody.size();
            for( int i = 0; i < numSubElements; i++ ) {
                Node node = tagBody.getNode( i );
                if( node instanceof Node.NamedAttribute ) {
                    String attrName = node.getAttributeValue( "name" );
                    temp.addElement( attrName );
		    // Check if this value appear in the attribute of the node
		    if (n.getAttributeValue(attrName) != null) {
			err.jspError(n, "jsp.error.duplicate.name.jspattribute",
					attrName);
		    }
                }
                else {
                    // Nothing can come before jsp:attribute, and only
                    // jsp:body can come after it.
                    break;
                }
            }
        }

	/*
	 * First check to see if all the mandatory attributes are present.
	 * If so only then proceed to see if the other attributes are valid
	 * for the particular tag.
	 */
	String missingAttribute = null;

	for (int i = 0; i < validAttributes.length; i++) {
	    int attrPos;    
	    if (validAttributes[i].mandatory) {
                attrPos = temp.indexOf(validAttributes[i].name);
		if (attrPos != -1) {
		    temp.remove(attrPos);
		    valid = true;
		} else {
		    valid = false;
		    missingAttribute = validAttributes[i].name;
		    break;
		}
	    }
	}

	// If mandatory attribute is missing then the exception is thrown
	if (!valid)
	    err.jspError(start, "jsp.error.mandatory.attribute", typeOfTag,
			 missingAttribute);

	// Check to see if there are any more attributes for the specified tag.
        int attrLeftLength = temp.size();
	if (attrLeftLength == 0)
	    return;

	// Now check to see if the rest of the attributes are valid too.
	String attribute = null;

	for (int j = 0; j < attrLeftLength; j++) {
	    valid = false;
	    attribute = (String) temp.elementAt(j);
	    for (int i = 0; i < validAttributes.length; i++) {
		if (attribute.equals(validAttributes[i].name)) {
		    valid = true;
		    break;
		}
	    }
	    if (!valid)
		err.jspError(start, "jsp.error.invalid.attribute", typeOfTag,
			     attribute);
	}
	// XXX *could* move EL-syntax validation here... (sb)
    }
    
    public static String escapeQueryString(String unescString) {
	if ( unescString == null )
	    return null;
	
	String escString    = "";
	String shellSpChars = "\\\"";
	
	for(int index=0; index<unescString.length(); index++) {
	    char nextChar = unescString.charAt(index);
	    
	    if( shellSpChars.indexOf(nextChar) != -1 )
		escString += "\\";
	    
	    escString += nextChar;
	}
	return escString;
    }
 
    /**
     *  Escape the 5 entities defined by XML.
     */
    public static String escapeXml(String s) {
        if (s == null) return null;
        StringBuffer sb = new StringBuffer();
        for(int i=0; i<s.length(); i++) {
            char c = s.charAt(i);
            if (c == '<') {
                sb.append("&lt;");
            } else if (c == '>') {
                sb.append("&gt;");
            } else if (c == '\'') {
                sb.append("&apos;");
            } else if (c == '&') {
                sb.append("&amp;");
            } else if (c == '"') {
                sb.append("&quot;");
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    /**
     * Replaces any occurrences of the character <tt>replace</tt> with the
     * string <tt>with</tt>.
     */
    public static String replace(String name, char replace, String with) {
	StringBuffer buf = new StringBuffer();
	int begin = 0;
	int end;
	int last = name.length();

	while (true) {
	    end = name.indexOf(replace, begin);
	    if (end < 0) {
		end = last;
	    }
	    buf.append(name.substring(begin, end));
	    if (end == last) {
		break;
	    }
	    buf.append(with);
	    begin = end + 1;
	}
	
	return buf.toString();
    }

    public static class ValidAttribute {
	String name;
	boolean mandatory;
	boolean rtexprvalue;	// not used now

	public ValidAttribute (String name, boolean mandatory,
            boolean rtexprvalue )
        {
	    this.name = name;
	    this.mandatory = mandatory;
            this.rtexprvalue = rtexprvalue;
        }

       public ValidAttribute (String name, boolean mandatory) {
            this( name, mandatory, false );
	}

	public ValidAttribute (String name) {
	    this (name, false);
	}
    }
    
    /**
     * Convert a String value to 'boolean'.
     * Besides the standard conversions done by
     * Boolean.valueOf(s).booleanValue(), the value "yes"
     * (ignore case) is also converted to 'true'. 
     * If 's' is null, then 'false' is returned.
     *
     * @param s the string to be converted
     * @return the boolean value associated with the string s
     */
    public static boolean booleanValue(String s) {
	boolean b = false;
	if (s != null) {
	    if (s.equalsIgnoreCase("yes")) {
		b = true;
	    } else {
		b = Boolean.valueOf(s).booleanValue();
	    }
	}
	return b;
    }

    /**
     * Returns the <tt>Class</tt> object associated with the class or
     * interface with the given string name.
     *
     * <p> The <tt>Class</tt> object is determined by passing the given string
     * name to the <tt>Class.forName()</tt> method, unless the given string
     * name represents a primitive type, in which case it is converted to a
     * <tt>Class</tt> object by appending ".class" to it (e.g., "int.class").
     */
    public static Class toClass(String type, ClassLoader loader)
	    throws ClassNotFoundException {

	Class c = null;
	int i0 = type.indexOf('[');
	int dims = 0;
	if (i0 > 0) {
	    // This is an array.  Count the dimensions
	    for (int i = 0; i < type.length(); i++) {
		if (type.charAt(i) == '[')
		    dims++;
	    }
	    type = type.substring(0, i0);
	}

	if ("boolean".equals(type))
	    c = boolean.class;
	else if ("char".equals(type))
	    c = char.class;
	else if ("byte".equals(type))
	    c =  byte.class;
	else if ("short".equals(type))
	    c = short.class;
	else if ("int".equals(type))
	    c = int.class;
	else if ("long".equals(type))
	    c = long.class;
	else if ("float".equals(type))
	    c = float.class;
	else if ("double".equals(type))
	    c = double.class;
	else if (type.indexOf('[') < 0)
	    c = loader.loadClass(type);

	if (dims == 0)
	    return c;

	if (dims == 1)
	    return java.lang.reflect.Array.newInstance(c, 1).getClass();

	// Array of more than i dimension
	return java.lang.reflect.Array.newInstance(c, new int[dims]).getClass();
    }

    /**
     * Produces a String representing a call to the EL interpreter.
     * @param expression a String containing zero or more "${}" expressions
     * @param expectedType the expected type of the interpreted result
     * @param fnmapvar Variable pointing to a function map.
     * @param XmlEscape True if the result should do XML escaping
     * @return a String representing a call to the EL interpreter.
     */
    public static String interpreterCall(boolean isTagFile,
					 String expression,
                                         Class expectedType,
                                         String fnmapvar,
                                         boolean XmlEscape ) 
    {
        /*
         * Determine which context object to use.
         */
	String jspCtxt = null;
	if (isTagFile)
	    jspCtxt = "this.getJspContext()";
	else
	    jspCtxt = "_jspx_page_context";

	/*
         * Determine whether to use the expected type's textual name
	 * or, if it's a primitive, the name of its correspondent boxed
	 * type.
         */
	String targetType = expectedType.getName();
	String primitiveConverterMethod = null;
	if (expectedType.isPrimitive()) {
	    if (expectedType.equals(Boolean.TYPE)) {
		targetType = Boolean.class.getName();
		primitiveConverterMethod = "booleanValue";
	    } else if (expectedType.equals(Byte.TYPE)) {
		targetType = Byte.class.getName();
		primitiveConverterMethod = "byteValue";
	    } else if (expectedType.equals(Character.TYPE)) {
		targetType = Character.class.getName();
		primitiveConverterMethod = "charValue";
	    } else if (expectedType.equals(Short.TYPE)) {
		targetType = Short.class.getName();
		primitiveConverterMethod = "shortValue";
	    } else if (expectedType.equals(Integer.TYPE)) {
		targetType = Integer.class.getName();
		primitiveConverterMethod = "intValue";
	    } else if (expectedType.equals(Long.TYPE)) {
		targetType = Long.class.getName();
		primitiveConverterMethod = "longValue";
	    } else if (expectedType.equals(Float.TYPE)) {
		targetType = Float.class.getName();
		primitiveConverterMethod = "floatValue";
	    } else if (expectedType.equals(Double.TYPE)) { 
		targetType = Double.class.getName();
		primitiveConverterMethod = "doubleValue";
	    }
	}
 
	if (primitiveConverterMethod != null) {
	    XmlEscape = false;
	}

	/*
         * Build up the base call to the interpreter.
         */
        // XXX - We use a proprietary call to the interpreter for now
        // as the current standard machinery is inefficient and requires
        // lots of wrappers and adapters.  This should all clear up once
        // the EL interpreter moves out of JSTL and into its own project.
        // In the future, this should be replaced by code that calls
        // ExpressionEvaluator.parseExpression() and then cache the resulting
        // expression objects.  The interpreterCall would simply select
        // one of the pre-cached expressions and evaluate it.
        // Note that PageContextImpl implements VariableResolver and
        // the generated Servlet/SimpleTag implements FunctionMapper, so
        // that machinery is already in place (mroth).
	targetType = toJavaSourceType(targetType);
	StringBuffer call = new StringBuffer(
             "(" + targetType + ") "
               + "org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate"
               + "(" + Generator.quote(expression) + ", "
               +       targetType + ".class, "
	       +       "(PageContext)" + jspCtxt 
               +       ", " + fnmapvar
	       + ", " + XmlEscape
               + ")");
 
	/*
         * Add the primitive converter method if we need to.
         */
	if (primitiveConverterMethod != null) {
	    call.insert(0, "(");
	    call.append(")." + primitiveConverterMethod + "()");
	}
 
	return call.toString();
    }

    /**
     * Validates the syntax of all ${} expressions within the given string.
     * @param where the approximate location of the expressions in the JSP page
     * @param expressions a string containing zero or more "${}" expressions
     * @param err an error dispatcher to use
     */
    public static void validateExpressions(Mark where,
                                           String expressions,
                                           Class expectedType,
                                           FunctionMapper functionMapper,
                                           ErrorDispatcher err)
            throws JasperException {

        try {
            JspUtil.expressionEvaluator.parseExpression( expressions, 
                expectedType, null );
        }
        catch( ELParseException e ) {
            err.jspError(where, "jsp.error.invalid.expression", expressions,
                e.toString() );
        }
        catch( ELException e ) {
            err.jspError(where, "jsp.error.invalid.expression", expressions,
                e.toString() );
        }
    }

    /**
     * Resets the temporary variable name.
     * (not thread-safe)
     */
    public static void resetTemporaryVariableName() {
        tempSequenceNumber = 0;
    }

    /**
     * Generates a new temporary variable name.
     * (not thread-safe)
     */
    public static String nextTemporaryVariableName() {
        return Constants.TEMP_VARIABLE_NAME_PREFIX + (tempSequenceNumber++);
    }

    public static String coerceToPrimitiveBoolean(String s,
						  boolean isNamedAttribute) {
	if (isNamedAttribute) {
	    return "org.apache.jasper.runtime.JspRuntimeLibrary.coerceToBoolean(" + s + ")";
	} else {
	    if (s == null || s.length() == 0)
		return "false";
	    else
		return Boolean.valueOf(s).toString();
	}
    }

    public static String coerceToBoolean(String s, boolean isNamedAttribute) {
	if (isNamedAttribute) {
	    return "(Boolean) org.apache.jasper.runtime.JspRuntimeLibrary.coerce(" + s + ", Boolean.class)";
	} else {
	    if (s == null || s.length() == 0) {
		return "new Boolean(false)";
	    } else {
		// Detect format error at translation time
		return "new Boolean(" + Boolean.valueOf(s).toString() + ")";
	    }
	}
    }

    public static String coerceToPrimitiveByte(String s,
					       boolean isNamedAttribute) {
	if (isNamedAttribute) {
	    return "org.apache.jasper.runtime.JspRuntimeLibrary.coerceToByte(" + s + ")";
	} else {
	    if (s == null || s.length() == 0)
		return "(byte) 0";
	    else
		return "((byte)" + Byte.valueOf(s).toString() + ")";
	}
    }

    public static String coerceToByte(String s, boolean isNamedAttribute) {
	if (isNamedAttribute) {
	    return "(Byte) org.apache.jasper.runtime.JspRuntimeLibrary.coerce(" + s + ", Byte.class)";
	} else {
	    if (s == null || s.length() == 0) {
		return "new Byte((byte) 0)";
	    } else {
		// Detect format error at translation time
		return "new Byte((byte)" + Byte.valueOf(s).toString() + ")";
	    }
	}
    }

    public static String coerceToChar(String s, boolean isNamedAttribute) {
	if (isNamedAttribute) {
	    return "org.apache.jasper.runtime.JspRuntimeLibrary.coerceToChar(" + s + ")";
	} else {
	    if (s == null || s.length() == 0) {
		return "(char) 0";
	    } else {
		char ch = s.charAt(0);
		// this trick avoids escaping issues
		return "((char) " + (int) ch + ")";
	    }
	}
    }

    public static String coerceToCharacter(String s, boolean isNamedAttribute) {
	if (isNamedAttribute) {
	    return "(Character) org.apache.jasper.runtime.JspRuntimeLibrary.coerce(" + s + ", Character.class)";
	} else {
	    if (s == null || s.length() == 0) {
		return "new Character((char) 0)";
	    } else {
		char ch = s.charAt(0);
		// this trick avoids escaping issues
		return "new Character((char) " + (int) ch + ")";
	    }
	}
    }

    public static String coerceToPrimitiveDouble(String s,
						 boolean isNamedAttribute) {
	if (isNamedAttribute) {
	    return "org.apache.jasper.runtime.JspRuntimeLibrary.coerceToDouble(" + s + ")";
	} else {
	    if (s == null || s.length() == 0)
		return "(double) 0";
	    else
		return Double.valueOf(s).toString();
	}
    }

    public static String coerceToDouble(String s, boolean isNamedAttribute) {
	if (isNamedAttribute) {
	    return "(Double) org.apache.jasper.runtime.JspRuntimeLibrary.coerce(" + s + ", Double.class)";
	} else {
	    if (s == null || s.length() == 0) {
		return "new Double(0)";
	    } else {
		// Detect format error at translation time
		return "new Double(" + Double.valueOf(s).toString() + ")";
	    }
	}
    }

    public static String coerceToPrimitiveFloat(String s,
						boolean isNamedAttribute) {
	if (isNamedAttribute) {
	    return "org.apache.jasper.runtime.JspRuntimeLibrary.coerceToFloat(" + s + ")";
	} else {
	    if (s == null || s.length() == 0)
		return "(float) 0";
	    else
		return Float.valueOf(s).toString() + "f";
	}
    }

    public static String coerceToFloat(String s, boolean isNamedAttribute) {
	if (isNamedAttribute) {
	    return "(Float) org.apache.jasper.runtime.JspRuntimeLibrary.coerce(" + s + ", Float.class)";
	} else {
	    if (s == null || s.length() == 0) {
		return "new Float(0)";
	    } else {
		// Detect format error at translation time
		return "new Float(" + Float.valueOf(s).toString() + "f)";
	    }
	}
    }

    public static String coerceToInt(String s, boolean isNamedAttribute) {
	if (isNamedAttribute) {
	    return "org.apache.jasper.runtime.JspRuntimeLibrary.coerceToInt(" + s + ")";
	} else {
	    if (s == null || s.length() == 0)
		return "0";
	    else
		return Integer.valueOf(s).toString();
	}
    }

    public static String coerceToInteger(String s, boolean isNamedAttribute) {
	if (isNamedAttribute) {
	    return "(Integer) org.apache.jasper.runtime.JspRuntimeLibrary.coerce(" + s + ", Integer.class)";
	} else {
	    if (s == null || s.length() == 0) {
		return "new Integer(0)";
	    } else {
		// Detect format error at translation time
		return "new Integer(" + Integer.valueOf(s).toString() + ")";
	    }
	}
    }

    public static String coerceToPrimitiveShort(String s,
						boolean isNamedAttribute) {
	if (isNamedAttribute) {
	    return "org.apache.jasper.runtime.JspRuntimeLibrary.coerceToShort(" + s + ")";
	} else {
	    if (s == null || s.length() == 0)
		return "(short) 0";
	    else
		return "((short) " + Short.valueOf(s).toString() + ")";
	}
    }
    
    public static String coerceToShort(String s, boolean isNamedAttribute) {
	if (isNamedAttribute) {
	    return "(Short) org.apache.jasper.runtime.JspRuntimeLibrary.coerce(" + s + ", Short.class)";
	} else {
	    if (s == null || s.length() == 0) {
		return "new Short((short) 0)";
	    } else {
		// Detect format error at translation time
		return "new Short(\"" + Short.valueOf(s).toString() + "\")";
	    }
	}
    }
    
    public static String coerceToPrimitiveLong(String s,
					       boolean isNamedAttribute) {
	if (isNamedAttribute) {
	    return "org.apache.jasper.runtime.JspRuntimeLibrary.coerceToLong(" + s + ")";
	} else {
	    if (s == null || s.length() == 0)
		return "(long) 0";
	    else
		return Long.valueOf(s).toString() + "l";
	}
    }

    public static String coerceToLong(String s, boolean isNamedAttribute) {
	if (isNamedAttribute) {
	    return "(Long) org.apache.jasper.runtime.JspRuntimeLibrary.coerce(" + s + ", Long.class)";
	} else {
	    if (s == null || s.length() == 0) {
		return "new Long(0)";
	    } else {
		// Detect format error at translation time
		return "new Long(" + Long.valueOf(s).toString() + "l)";
	    }
	}
    }

    public static InputStream getInputStream(String fname, JarFile jarFile,
					     JspCompilationContext ctxt,
					     ErrorDispatcher err)
		throws JasperException, IOException {

        InputStream in = null;

	if (jarFile != null) {
	    String jarEntryName = fname.substring(1, fname.length());
	    ZipEntry jarEntry = jarFile.getEntry(jarEntryName);
	    if (jarEntry == null) {
		err.jspError("jsp.error.file.not.found", fname);
	    }
	    in = jarFile.getInputStream(jarEntry);
	} else {
	    in = ctxt.getResourceAsStream(fname);
	}

	if (in == null) {
	    err.jspError("jsp.error.file.not.found", fname);
	}

	return in;
    }

    /**
     * Gets the fully-qualified class name of the tag handler corresponding to
     * the given tag file path.
     *
     * @param path Tag file path
     * @param err Error dispatcher
     *
     * @return Fully-qualified class name of the tag handler corresponding to 
     * the given tag file path
     */
    public static String getTagHandlerClassName(String path,
						ErrorDispatcher err)
                throws JasperException {

        String className = null;
        int begin = 0;
        int index;
        
        index = path.lastIndexOf(".tag");
        if (index == -1) {
            err.jspError("jsp.error.tagfile.badSuffix", path);
        }

        //It's tempting to remove the ".tag" suffix here, but we can't.
        //If we remove it, the fully-qualified class name of this tag
        //could conflict with the package name of other tags.
        //For instance, the tag file
        //    /WEB-INF/tags/foo.tag
        //would have fully-qualified class name
        //    org.apache.jsp.tag.web.foo
        //which would conflict with the package name of the tag file
        //    /WEB-INF/tags/foo/bar.tag

        index = path.indexOf(WEB_INF_TAGS);
        if (index != -1) {
            className = "org.apache.jsp.tag.web.";
            begin = index + WEB_INF_TAGS.length();
        } else {
	    index = path.indexOf(META_INF_TAGS);
	    if (index != -1) {
		className = "org.apache.jsp.tag.meta.";
		begin = index + META_INF_TAGS.length();
	    } else {
		err.jspError("jsp.error.tagfile.illegalPath", path);
	    }
	}

        className += makeJavaPackage(path.substring(begin));
  
       return className;
    }

    /**
     * Converts the given path to a Java package or fully-qualified class name
     *
     * @param path Path to convert
     *
     * @return Java package corresponding to the given path
     */
    public static final String makeJavaPackage(String path) {
        String classNameComponents[] = split(path,"/");
        StringBuffer legalClassNames = new StringBuffer();
        for (int i = 0; i < classNameComponents.length; i++) {
            legalClassNames.append(makeJavaIdentifier(classNameComponents[i]));
            if (i < classNameComponents.length - 1) {
                legalClassNames.append('.');
            }
        }
        return legalClassNames.toString();
    }

    /**
     * Splits a string into it's components.
     * @param path String to split
     * @param pat Pattern to split at
     * @return the components of the path
     */
    private static final String [] split(String path, String pat) {
        Vector comps = new Vector();
        int pos = path.indexOf(pat);
        int start = 0;
        while( pos >= 0 ) {
            if(pos > start ) {
                String comp = path.substring(start,pos);
                comps.add(comp);
            }
            start = pos + pat.length();
            pos = path.indexOf(pat,start);
        }
        if( start < path.length()) {
            comps.add(path.substring(start));
        }
        String [] result = new String[comps.size()];
        for(int i=0; i < comps.size(); i++) {
            result[i] = (String)comps.elementAt(i);
        }
        return result;
    }
            
    /**
     * Converts the given identifier to a legal Java identifier
     *
     * @param identifier Identifier to convert
     *
     * @return Legal Java identifier corresponding to the given identifier
     */
    public static final String makeJavaIdentifier(String identifier) {
        StringBuffer modifiedIdentifier = 
            new StringBuffer(identifier.length());
        if (!Character.isJavaIdentifierStart(identifier.charAt(0))) {
            modifiedIdentifier.append('_');
        }
        for (int i = 0; i < identifier.length(); i++) {
            char ch = identifier.charAt(i);
            if (Character.isJavaIdentifierPart(ch) && ch != '_') {
                modifiedIdentifier.append(ch);
            } else if (ch == '.') {
                modifiedIdentifier.append('_');
            } else {
                modifiedIdentifier.append(mangleChar(ch));
            }
        }
        if (isJavaKeyword(modifiedIdentifier.toString())) {
            modifiedIdentifier.append('_');
        }
        return modifiedIdentifier.toString();
    }
    
    /**
     * Mangle the specified character to create a legal Java class name.
     */
    public static final String mangleChar(char ch) {
        char[] result = new char[5];
        result[0] = '_';
        result[1] = Character.forDigit((ch >> 12) & 0xf, 16);
        result[2] = Character.forDigit((ch >> 8) & 0xf, 16);
        result[3] = Character.forDigit((ch >> 4) & 0xf, 16);
        result[4] = Character.forDigit(ch & 0xf, 16);
        return new String(result);
    }

    /**
     * Test whether the argument is a Java keyword
     */
    public static boolean isJavaKeyword(String key) {
        int i = 0;
        int j = javaKeywords.length;
        while (i < j) {
            int k = (i+j)/2;
            int result = javaKeywords[k].compareTo(key);
            if (result == 0) {
                return true;
            }
            if (result < 0) {
                i = k+1;
            } else {
                j = k;
            }
        }
        return false;
    }

    /**
     * Converts the given Xml name to a legal Java identifier.  This is
     * slightly more efficient than makeJavaIdentifier in that we only need
     * to worry about '.', '-', and ':' in the string.  We also assume that
     * the resultant string is further concatenated with some prefix string
     * so that we don't have to worry about it being a Java key word.
     *
     * @param name Identifier to convert
     *
     * @return Legal Java identifier corresponding to the given identifier
     */
    public static final String makeXmlJavaIdentifier(String name) {
        if (name.indexOf('-') >= 0)
            name = replace(name, '-', "$1");
        if (name.indexOf('.') >= 0)
            name = replace(name, '.', "$2");
        if (name.indexOf(':') >= 0)
            name = replace(name, ':', "$3");
        return name;
    }

    static InputStreamReader getReader(String fname, String encoding,
				       JarFile jarFile,
				       JspCompilationContext ctxt,
				       ErrorDispatcher err)
		throws JasperException, IOException {

        InputStreamReader reader = null;
	InputStream in = getInputStream(fname, jarFile, ctxt, err);

	try {
            reader = new InputStreamReader(in, encoding);
	} catch (UnsupportedEncodingException ex) {
	    err.jspError("jsp.error.unsupported.encoding", encoding);
	}

	return reader;
    }

    /**
     * Class.getName() return arrays in the form "[[[<et>", where et,
     * the element type can be one of ZBCDFIJS or L<classname>;
     * It is converted into forms that can be understood by javac.
     */
    public static String toJavaSourceType(String type) {

	if (type.charAt(0) != '[') {
	    return type;
 	}

	int dims = 1;
	String t = null;
	for (int i = 1; i < type.length(); i++) {
	    if (type.charAt(i) == '[') {
		dims++;
	    } else {
		switch (type.charAt(i)) {
		case 'Z': t = "boolean"; break;
		case 'B': t = "byte"; break;
		case 'C': t = "char"; break;
		case 'D': t = "double"; break;
		case 'F': t = "float"; break;
		case 'I': t = "int"; break;
		case 'J': t = "long"; break;
		case 'S': t = "short"; break;
		case 'L': t = type.substring(i+1, type.indexOf(';')); break;
		}
		break;
	    }
	}
	StringBuffer resultType = new StringBuffer(t);
	for (; dims > 0; dims--) {
	    resultType.append("[]");
	}
	return resultType.toString();
    }

    /**
     * Compute the canonical name from a Class instance.  Note that a
     * simple replacment of '$' with '.' of a binary name would not work,
     * as '$' is a legal Java Identifier character.
     * @param c A instance of java.lang.Class
     * @return  The canonical name of c.
     */
    public static String getCanonicalName(Class c) {

        String binaryName = c.getName();
        c = c.getDeclaringClass();

        if (c == null) {
            return binaryName;
        }

        StringBuffer buf = new StringBuffer(binaryName);
        do {
            buf.setCharAt(c.getName().length(), '.');
            c = c.getDeclaringClass();
        } while ( c != null);

        return buf.toString();
    }
}

