[jboss-svn-commits] JBL Code SVN: r6740 - in labs/jbossweb/trunk/src/share/classes/org/apache: catalina/core catalina/servlets jasper/compiler

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Wed Oct 11 06:36:21 EDT 2006


Author: remy.maucherat at jboss.com
Date: 2006-10-11 06:36:07 -0400 (Wed, 11 Oct 2006)
New Revision: 6740

Modified:
   labs/jbossweb/trunk/src/share/classes/org/apache/catalina/core/StandardPipeline.java
   labs/jbossweb/trunk/src/share/classes/org/apache/catalina/servlets/CGIServlet.java
   labs/jbossweb/trunk/src/share/classes/org/apache/catalina/servlets/DefaultServlet.java
   labs/jbossweb/trunk/src/share/classes/org/apache/jasper/compiler/ELParser.java
   labs/jbossweb/trunk/src/share/classes/org/apache/jasper/compiler/Generator.java
   labs/jbossweb/trunk/src/share/classes/org/apache/jasper/compiler/Parser.java
Log:
- Port a few Jasper fixes and 3 very minor Catalina fixes.

Modified: labs/jbossweb/trunk/src/share/classes/org/apache/catalina/core/StandardPipeline.java
===================================================================
--- labs/jbossweb/trunk/src/share/classes/org/apache/catalina/core/StandardPipeline.java	2006-10-11 09:52:46 UTC (rev 6739)
+++ labs/jbossweb/trunk/src/share/classes/org/apache/catalina/core/StandardPipeline.java	2006-10-11 10:36:07 UTC (rev 6740)
@@ -530,6 +530,8 @@
             current = current.getNext();
         }
 
+        if (first == basic) first = null;
+        
         if (valve instanceof Contained)
             ((Contained) valve).setContainer(null);
 

Modified: labs/jbossweb/trunk/src/share/classes/org/apache/catalina/servlets/CGIServlet.java
===================================================================
--- labs/jbossweb/trunk/src/share/classes/org/apache/catalina/servlets/CGIServlet.java	2006-10-11 09:52:46 UTC (rev 6739)
+++ labs/jbossweb/trunk/src/share/classes/org/apache/catalina/servlets/CGIServlet.java	2006-10-11 10:36:07 UTC (rev 6740)
@@ -1786,7 +1786,7 @@
             }
             catch (IOException e){
                 log ("Caught exception " + e);
-                throw new IOException (e.toString());
+                throw e;
             }
             finally{
                 if (debug > 4) {

Modified: labs/jbossweb/trunk/src/share/classes/org/apache/catalina/servlets/DefaultServlet.java
===================================================================
--- labs/jbossweb/trunk/src/share/classes/org/apache/catalina/servlets/DefaultServlet.java	2006-10-11 09:52:46 UTC (rev 6739)
+++ labs/jbossweb/trunk/src/share/classes/org/apache/catalina/servlets/DefaultServlet.java	2006-10-11 10:36:07 UTC (rev 6740)
@@ -788,7 +788,8 @@
                 // If it fails, we try to get a Writer instead if we're
                 // trying to serve a text file
                 if ( (contentType == null)
-                     || (contentType.startsWith("text")) ) {
+                     || (contentType.startsWith("text"))
+                     || (contentType.endsWith("xml")) ) {
                     writer = response.getWriter();
                 } else {
                     throw e;

Modified: labs/jbossweb/trunk/src/share/classes/org/apache/jasper/compiler/ELParser.java
===================================================================
--- labs/jbossweb/trunk/src/share/classes/org/apache/jasper/compiler/ELParser.java	2006-10-11 09:52:46 UTC (rev 6739)
+++ labs/jbossweb/trunk/src/share/classes/org/apache/jasper/compiler/ELParser.java	2006-10-11 10:36:07 UTC (rev 6740)
@@ -29,12 +29,12 @@
 
 public class ELParser {
 
-    private Token curToken;	// current token
+    private Token curToken;        // current token
     private ELNode.Nodes expr;
     private ELNode.Nodes ELexpr;
-    private int index;		// Current index of the expression
-    private String expression;	// The EL expression
-    private boolean escapeBS;	// is '\' an escape char in text outside EL?
+    private int index;                // Current index of the expression
+    private String expression;        // The EL expression
+    private boolean escapeBS;        // is '\' an escape char in text outside EL?
 
     private static final String reservedWords[] = {
         "and", "div", "empty", "eq", "false",
@@ -42,9 +42,9 @@
         "ne", "not", "null", "or", "true"};
 
     public ELParser(String expression) {
-	index = 0;
-	this.expression = expression;
-	expr = new ELNode.Nodes();
+        index = 0;
+        this.expression = expression;
+        expr = new ELNode.Nodes();
     }
 
     /**
@@ -54,18 +54,18 @@
      * @return Parsed EL expression in ELNode.Nodes
      */
     public static ELNode.Nodes parse(String expression) {
-	ELParser parser = new ELParser(expression);
-	while (parser.hasNextChar()) {
-	    String text = parser.skipUntilEL();
-	    if (text.length() > 0) {
-		parser.expr.add(new ELNode.Text(text));
-	    }
-	    ELNode.Nodes elexpr = parser.parseEL();
-	    if (! elexpr.isEmpty()) {
-		parser.expr.add(new ELNode.Root(elexpr));
-	    }
-	}
-	return parser.expr;
+        ELParser parser = new ELParser(expression);
+        while (parser.hasNextChar()) {
+            String text = parser.skipUntilEL();
+            if (text.length() > 0) {
+                parser.expr.add(new ELNode.Text(text));
+            }
+            ELNode.Nodes elexpr = parser.parseEL();
+            if (! elexpr.isEmpty()) {
+                parser.expr.add(new ELNode.Root(elexpr));
+            }
+        }
+        return parser.expr;
     }
 
     /**
@@ -76,66 +76,66 @@
      */
     private ELNode.Nodes parseEL() {
 
-	StringBuffer buf = new StringBuffer();
-	ELexpr = new ELNode.Nodes();
-	while (hasNext()) {
-	    curToken = nextToken();
-	    if (curToken instanceof Char) {
-		if (curToken.toChar() == '}') {
-		    break;
-		}
-		buf.append(curToken.toChar());
-	    } else {
-		// Output whatever is in buffer
-		if (buf.length() > 0) {
-		    ELexpr.add(new ELNode.ELText(buf.toString()));
-		}
-		if (!parseFunction()) {
-		    ELexpr.add(new ELNode.ELText(curToken.toString()));
-		}
-	    }
-	}
-	if (buf.length() > 0) {
-	    ELexpr.add(new ELNode.ELText(buf.toString()));
-	}
+        StringBuffer buf = new StringBuffer();
+        ELexpr = new ELNode.Nodes();
+        while (hasNext()) {
+            curToken = nextToken();
+            if (curToken instanceof Char) {
+                if (curToken.toChar() == '}') {
+                    break;
+                }
+                buf.append(curToken.toChar());
+            } else {
+                // Output whatever is in buffer
+                if (buf.length() > 0) {
+                    ELexpr.add(new ELNode.ELText(buf.toString()));
+                }
+                if (!parseFunction()) {
+                    ELexpr.add(new ELNode.ELText(curToken.toString()));
+                }
+            }
+        }
+        if (buf.length() > 0) {
+            ELexpr.add(new ELNode.ELText(buf.toString()));
+        }
 
-	return ELexpr;
+        return ELexpr;
     }
 
     /**
      * Parse for a function
      * FunctionInvokation ::= (identifier ':')? identifier '('
-     *			      (Expression (,Expression)*)? ')'
+     *                              (Expression (,Expression)*)? ')'
      * Note: currently we don't parse arguments
      */
     private boolean parseFunction() {
-	if (! (curToken instanceof Id) || isELReserved(curToken.toString())) {
-	    return false;
-	}
-	String s1 = null;                 // Function prefix
-	String s2 = curToken.toString();  // Function name
-	int mark = getIndex();
-	if (hasNext()) {
-	    Token t = nextToken();
-	    if (t.toChar() == ':') {
-		if (hasNext()) {
-		    Token t2 = nextToken();
-		    if (t2 instanceof Id) {
-			s1 = s2;
-			s2 = t2.toString();
-			if (hasNext()) {
-			    t = nextToken();
-			}
-		    }
-		}
-	    }
-	    if (t.toChar() == '(') {
-		ELexpr.add(new ELNode.Function(s1, s2));
-		return true;
-	    }
-	}
-	setIndex(mark);
-	return false;
+        if (! (curToken instanceof Id) || isELReserved(curToken.toString())) {
+            return false;
+        }
+        String s1 = null;                 // Function prefix
+        String s2 = curToken.toString();  // Function name
+        int mark = getIndex();
+        if (hasNext()) {
+            Token t = nextToken();
+            if (t.toChar() == ':') {
+                if (hasNext()) {
+                    Token t2 = nextToken();
+                    if (t2 instanceof Id) {
+                        s1 = s2;
+                        s2 = t2.toString();
+                        if (hasNext()) {
+                            t = nextToken();
+                        }
+                    }
+                }
+            }
+            if (t.toChar() == '(') {
+                ELexpr.add(new ELNode.Function(s1, s2));
+                return true;
+            }
+        }
+        setIndex(mark);
+        return false;
     }
 
     /**
@@ -165,37 +165,38 @@
      * @return The text string up to the EL expression
      */
     private String skipUntilEL() {
-	char prev = 0;
-	StringBuffer buf = new StringBuffer();
-	while (hasNextChar()) {
-	    char ch = nextChar();
-	    if (prev == '\\') {
-		prev = 0;
-		if (ch == '\\') {
-		    buf.append('\\');
-		    if (!escapeBS)
-			prev = '\\';
-		} else if (ch == '$') {
-		    buf.append('$');
-		}
-		// else error!
-	    } else if (prev == '$') {
-		if (ch == '{') {
-		    prev = 0;
-		    break;
-		} 
-		buf.append('$');
-		buf.append(ch);
-	    } else if (ch == '\\' || ch == '$') {
-		prev = ch;
-	    } else {
-		buf.append(ch);
-	    }
-	}
-	if (prev != 0) {
-	    buf.append(prev);
-	}
-	return buf.toString();
+        char prev = 0;
+        StringBuffer buf = new StringBuffer();
+        while (hasNextChar()) {
+            char ch = nextChar();
+            if (prev == '\\') {
+                prev = 0;
+                if (ch == '\\') {
+                    buf.append('\\');
+                    if (!escapeBS)
+                        prev = '\\';
+                } else if (ch == '$') {
+                    buf.append('$');
+                }
+                // else error!
+            } else if (prev == '$') {
+                if (ch == '{') {
+                    prev = 0;
+                    break;
+                } 
+                buf.append('$');
+                buf.append(ch);
+                prev = 0;
+            } else if (ch == '\\' || ch == '$') {
+                prev = ch;
+            } else {
+                buf.append(ch);
+            }
+        }
+        if (prev != 0) {
+            buf.append(prev);
+        }
+        return buf.toString();
     }
 
     /*
@@ -203,36 +204,36 @@
      *         than white spaces.
      */
     private boolean hasNext() {
-	skipSpaces();
-	return hasNextChar();
+        skipSpaces();
+        return hasNextChar();
     }
 
     /*
      * @return The next token in the EL expression buffer.
      */
     private Token nextToken() {
-	skipSpaces();
-	if (hasNextChar()) {
-	    char ch = nextChar();
-	    if (Character.isJavaIdentifierStart(ch)) {
-		StringBuffer buf = new StringBuffer();
-		buf.append(ch);
-		while ((ch = peekChar()) != -1 &&
-				Character.isJavaIdentifierPart(ch)) {
-		    buf.append(ch);
-		    nextChar();
-		}
-		return new Id(buf.toString());
-	    }
+        skipSpaces();
+        if (hasNextChar()) {
+            char ch = nextChar();
+            if (Character.isJavaIdentifierStart(ch)) {
+                StringBuffer buf = new StringBuffer();
+                buf.append(ch);
+                while ((ch = peekChar()) != -1 &&
+                                Character.isJavaIdentifierPart(ch)) {
+                    buf.append(ch);
+                    nextChar();
+                }
+                return new Id(buf.toString());
+            }
 
-	    if (ch == '\'' || ch == '"') {
-		return parseQuotedChars(ch);
-	    } else {
-		// For now...
-		return new Char(ch);
-	    }
-	}
-	return null;
+            if (ch == '\'' || ch == '"') {
+                return parseQuotedChars(ch);
+            } else {
+                // For now...
+                return new Char(ch);
+            }
+        }
+        return null;
     }
 
     /*
@@ -240,24 +241,24 @@
      * '\\', and ('\"', or "\'")
      */
     private Token parseQuotedChars(char quote) {
-	StringBuffer buf = new StringBuffer();
-	buf.append(quote);
-	while (hasNextChar()) {
-	    char ch = nextChar();
-	    if (ch == '\\') {
-		ch = nextChar();
-		if (ch == '\\' || ch == quote) {
-		    buf.append(ch);
-		}
-		// else error!
-	    } else if (ch == quote) {
-		buf.append(ch);
-		break;
-	    } else {
-		buf.append(ch);
-	    }
-	}
-	return new QuotedString(buf.toString());
+        StringBuffer buf = new StringBuffer();
+        buf.append(quote);
+        while (hasNextChar()) {
+            char ch = nextChar();
+            if (ch == '\\') {
+                ch = nextChar();
+                if (ch == '\\' || ch == quote) {
+                    buf.append(ch);
+                }
+                // else error!
+            } else if (ch == quote) {
+                buf.append(ch);
+                break;
+            } else {
+                buf.append(ch);
+            }
+        }
+        return new QuotedString(buf.toString());
     }
 
     /*
@@ -266,37 +267,37 @@
      */
 
     private void skipSpaces() {
-	while (hasNextChar()) {
-	    if (expression.charAt(index) > ' ')
-		break;
-	    index++;
-	}
+        while (hasNextChar()) {
+            if (expression.charAt(index) > ' ')
+                break;
+            index++;
+        }
     }
 
     private boolean hasNextChar() {
-	return index < expression.length();
+        return index < expression.length();
     }
 
     private char nextChar() {
-	if (index >= expression.length()) {
-	    return (char)-1;
-	}
-	return expression.charAt(index++);
+        if (index >= expression.length()) {
+            return (char)-1;
+        }
+        return expression.charAt(index++);
     }
 
     private char peekChar() {
-	if (index >= expression.length()) {
-	    return (char)-1;
-	}
-	return expression.charAt(index);
+        if (index >= expression.length()) {
+            return (char)-1;
+        }
+        return expression.charAt(index);
     }
 
     private int getIndex() {
-	return index;
+        return index;
     }
 
     private void setIndex(int i) {
-	index = i;
+        index = i;
     }
 
     /*
@@ -304,28 +305,28 @@
      */
     private static class Token {
 
-	char toChar() {
-	    return 0;
-	}
+        char toChar() {
+            return 0;
+        }
 
-	public String toString() {
-	    return "";
-	}
+        public String toString() {
+            return "";
+        }
     }
 
     /*
      * Represents an ID token in EL
      */
     private static class Id extends Token {
-	String id;
+        String id;
 
-	Id(String id) {
-	    this.id = id;
-	}
+        Id(String id) {
+            this.id = id;
+        }
 
-	public String toString() {
-	    return id;
-	}
+        public String toString() {
+            return id;
+        }
     }
 
     /*
@@ -333,19 +334,19 @@
      */
     private static class Char extends Token {
 
-	private char ch;
+        private char ch;
 
-	Char(char ch) {
-	    this.ch = ch;
-	}
+        Char(char ch) {
+            this.ch = ch;
+        }
 
-	char toChar() {
-	    return ch;
-	}
+        char toChar() {
+            return ch;
+        }
 
-	public String toString() {
-	    return (new Character(ch)).toString();
-	}
+        public String toString() {
+            return (new Character(ch)).toString();
+        }
     }
 
     /*
@@ -353,15 +354,15 @@
      */
     private static class QuotedString extends Token {
 
-	private String value;
+        private String value;
 
-	QuotedString(String v) {
-	    this.value = v;
-	}
+        QuotedString(String v) {
+            this.value = v;
+        }
 
-	public String toString() {
-	    return value;
-	}
+        public String toString() {
+            return value;
+        }
     }
 }
 

Modified: labs/jbossweb/trunk/src/share/classes/org/apache/jasper/compiler/Generator.java
===================================================================
--- labs/jbossweb/trunk/src/share/classes/org/apache/jasper/compiler/Generator.java	2006-10-11 09:52:46 UTC (rev 6739)
+++ labs/jbossweb/trunk/src/share/classes/org/apache/jasper/compiler/Generator.java	2006-10-11 10:36:07 UTC (rev 6740)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999,2004 The Apache Software Foundation.
+ * Copyright 1999,2004-2006 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.
@@ -268,7 +268,7 @@
                 if (hasEmptyBody) {
                     poolName = poolName + "_nobody";
                 }
-                return JspUtil.makeXmlJavaIdentifier(poolName);
+                return JspUtil.makeJavaIdentifier(poolName);
             }
         }
 
@@ -1886,6 +1886,16 @@
                 return;
             }
 
+            // Replace marker for \$ sequence with correct sequence
+            if (text.indexOf(Constants.ESC) > 0) {
+                if (pageInfo.isELIgnored()) {
+                    text = text.replaceAll(String.valueOf(Constants.ESC), "\\\\\\$");
+                    textSize++;
+                } else {
+                    text = text.replace(Constants.ESC, '$');
+                }
+            }
+
             if (textSize <= 3) {
                // Special case small text strings
                n.setBeginJavaLine(out.getJavaLine());
@@ -2278,7 +2288,7 @@
                     out.printin("if (");
                     out.print(tagEvalVar);
                     out.println(
-                        " != javax.servlet.jsp.tagext.Tag.EVAL_BODY_INCLUDE)");
+                        " != javax.servlet.jsp.tagext.Tag.EVAL_BODY_INCLUDE) {");
                     out.pushIndent();
                     out.printil("out = _jspx_page_context.popBody();");
                     if (n.implementsTryCatchFinally()) {
@@ -2289,6 +2299,7 @@
                         out.println("[0]--;");
                     }
                     out.popIndent();
+                    out.printil("}");
                 }
 
                 out.popIndent(); // EVAL_BODY
@@ -2668,7 +2679,7 @@
                     varName = varName + "0";
                 }
             }
-            return JspUtil.makeXmlJavaIdentifier(varName);
+            return JspUtil.makeJavaIdentifier(varName);
         }
 
         private String evaluateAttribute(
@@ -2824,9 +2835,14 @@
             }
 
             // Set parent
-            if (!simpleTag) {
+            if (isTagFile && parent == null) {
                 out.printin(tagHandlerVar);
                 out.print(".setParent(");
+                out.print("new javax.servlet.jsp.tagext.TagAdapter(");
+                out.print("(javax.servlet.jsp.tagext.SimpleTag) this ));");
+            } else if (!simpleTag) {
+                out.printin(tagHandlerVar);
+                out.print(".setParent(");
                 if (parent != null) {
                     if (isSimpleTagParent) {
                         out.print("new javax.servlet.jsp.tagext.TagAdapter(");

Modified: labs/jbossweb/trunk/src/share/classes/org/apache/jasper/compiler/Parser.java
===================================================================
--- labs/jbossweb/trunk/src/share/classes/org/apache/jasper/compiler/Parser.java	2006-10-11 09:52:46 UTC (rev 6739)
+++ labs/jbossweb/trunk/src/share/classes/org/apache/jasper/compiler/Parser.java	2006-10-11 10:36:07 UTC (rev 6740)
@@ -70,17 +70,17 @@
      * The constructor
      */
     private Parser(ParserController pc, JspReader reader, boolean isTagFile,
-		   boolean directivesOnly, URL jarFileUrl) {
-	this.parserController = pc;
-	this.ctxt = pc.getJspCompilationContext();
-	this.pageInfo = pc.getCompiler().getPageInfo();
-	this.err = pc.getCompiler().getErrorDispatcher();
-	this.reader = reader;
-	this.currentFile = reader.mark().getFile();
+                   boolean directivesOnly, URL jarFileUrl) {
+        this.parserController = pc;
+        this.ctxt = pc.getJspCompilationContext();
+        this.pageInfo = pc.getCompiler().getPageInfo();
+        this.err = pc.getCompiler().getErrorDispatcher();
+        this.reader = reader;
+        this.currentFile = reader.mark().getFile();
         this.scriptlessCount = 0;
-	this.isTagFile = isTagFile;
-	this.directivesOnly = directivesOnly;
-	this.jarFileUrl = jarFileUrl;
+        this.isTagFile = isTagFile;
+        this.directivesOnly = directivesOnly;
+        this.jarFileUrl = jarFileUrl;
         start = reader.mark();
     }
 
@@ -88,72 +88,72 @@
      * The main entry for Parser
      * 
      * @param pc The ParseController, use for getting other objects in compiler
-     *		 and for parsing included pages
+     *                 and for parsing included pages
      * @param reader To read the page
      * @param parent The parent node to this page, null for top level page
      * @return list of nodes representing the parsed page
      */
     public static Node.Nodes parse(ParserController pc,
-				   JspReader reader,
-				   Node parent,
-				   boolean isTagFile,
-				   boolean directivesOnly,
-				   URL jarFileUrl,
-				   String pageEnc,
-				   String jspConfigPageEnc,
-				   boolean isDefaultPageEncoding)
-		throws JasperException {
+                                   JspReader reader,
+                                   Node parent,
+                                   boolean isTagFile,
+                                   boolean directivesOnly,
+                                   URL jarFileUrl,
+                                   String pageEnc,
+                                   String jspConfigPageEnc,
+                                   boolean isDefaultPageEncoding)
+                throws JasperException {
 
-	Parser parser = new Parser(pc, reader, isTagFile, directivesOnly,
-				   jarFileUrl);
+        Parser parser = new Parser(pc, reader, isTagFile, directivesOnly,
+                                   jarFileUrl);
 
-	Node.Root root = new Node.Root(reader.mark(), parent, false);
-	root.setPageEncoding(pageEnc);
-	root.setJspConfigPageEncoding(jspConfigPageEnc);
-	root.setIsDefaultPageEncoding(isDefaultPageEncoding);
+        Node.Root root = new Node.Root(reader.mark(), parent, false);
+        root.setPageEncoding(pageEnc);
+        root.setJspConfigPageEncoding(jspConfigPageEnc);
+        root.setIsDefaultPageEncoding(isDefaultPageEncoding);
 
-	if (directivesOnly) {
-	    parser.parseTagFileDirectives(root);
-	    return new Node.Nodes(root);
-	}
+        if (directivesOnly) {
+            parser.parseTagFileDirectives(root);
+            return new Node.Nodes(root);
+        }
 
-	// For the Top level page, add inlcude-prelude and include-coda
-	PageInfo pageInfo = pc.getCompiler().getPageInfo();
-	if (parent == null) {
-	    parser.addInclude(root, pageInfo.getIncludePrelude());
-	}
-	while (reader.hasMoreInput()) {
-	    parser.parseElements(root);
-	}
-	if (parent == null) {
-	    parser.addInclude(root, pageInfo.getIncludeCoda());
-	}
+        // For the Top level page, add inlcude-prelude and include-coda
+        PageInfo pageInfo = pc.getCompiler().getPageInfo();
+        if (parent == null) {
+            parser.addInclude(root, pageInfo.getIncludePrelude());
+        }
+        while (reader.hasMoreInput()) {
+            parser.parseElements(root);
+        }
+        if (parent == null) {
+            parser.addInclude(root, pageInfo.getIncludeCoda());
+        }
 
-	Node.Nodes page = new Node.Nodes(root);
-	return page;
+        Node.Nodes page = new Node.Nodes(root);
+        return page;
     }
 
     /**
      * Attributes ::= (S Attribute)* S?
      */
     Attributes parseAttributes() throws JasperException {
-	AttributesImpl attrs = new AttributesImpl();
+        AttributesImpl attrs = new AttributesImpl();
 
-	reader.skipSpaces();
-	while (parseAttribute(attrs))
-	    reader.skipSpaces();
+        reader.skipSpaces();
+        while (parseAttribute(attrs))
+            reader.skipSpaces();
 
-	return attrs;
+        return attrs;
     }
 
     /**
      * Parse Attributes for a reader, provided for external use
      */
     public static Attributes parseAttributes(ParserController pc,
-					     JspReader reader)
-		throws JasperException {
-	Parser tmpParser = new Parser(pc, reader, false, false, null);
-	return tmpParser.parseAttributes();
+                                             JspReader reader)
+                throws JasperException {
+        Parser tmpParser = new Parser(pc, reader, false, false, null);
+        return tmpParser.parseAttributes();
     }
 
     /**
@@ -167,92 +167,92 @@
      * added to be backward compatible with Tomcat, and with other xml parsers.
      */
     private boolean parseAttribute(AttributesImpl attrs)
-	        throws JasperException {
+                throws JasperException {
 
-	// Get the qualified name
-	String qName = parseName();
-	if (qName == null)
-	    return false;
+        // Get the qualified name
+        String qName = parseName();
+        if (qName == null)
+            return false;
 
-	// Determine prefix and local name components
-	String localName = qName;
-	String uri = "";
-	int index = qName.indexOf(':');
-	if (index != -1) {
-	    String prefix = qName.substring(0, index);
-	    uri = pageInfo.getURI(prefix);
-	    if (uri == null) {
-		err.jspError(reader.mark(),
-			     "jsp.error.attribute.invalidPrefix", prefix);
-	    }
-	    localName = qName.substring(index+1);
-	}
+        // Determine prefix and local name components
+        String localName = qName;
+        String uri = "";
+        int index = qName.indexOf(':');
+        if (index != -1) {
+            String prefix = qName.substring(0, index);
+            uri = pageInfo.getURI(prefix);
+            if (uri == null) {
+                err.jspError(reader.mark(),
+                             "jsp.error.attribute.invalidPrefix", prefix);
+            }
+            localName = qName.substring(index+1);
+        }
 
- 	reader.skipSpaces();
-	if (!reader.matches("="))
-	    err.jspError(reader.mark(), "jsp.error.attribute.noequal");
+         reader.skipSpaces();
+        if (!reader.matches("="))
+            err.jspError(reader.mark(), "jsp.error.attribute.noequal");
 
- 	reader.skipSpaces();
-	char quote = (char) reader.nextChar();
-	if (quote != '\'' && quote != '"')
-	    err.jspError(reader.mark(), "jsp.error.attribute.noquote");
+         reader.skipSpaces();
+        char quote = (char) reader.nextChar();
+        if (quote != '\'' && quote != '"')
+            err.jspError(reader.mark(), "jsp.error.attribute.noquote");
 
- 	String watchString = "";
-	if (reader.matches("<%="))
-	    watchString = "%>";
-	watchString = watchString + quote;
-	
-	String attrValue = parseAttributeValue(watchString);
-	attrs.addAttribute(uri, localName, qName, "CDATA", attrValue);
-	return true;
+         String watchString = "";
+        if (reader.matches("<%="))
+            watchString = "%>";
+        watchString = watchString + quote;
+        
+        String attrValue = parseAttributeValue(watchString);
+        attrs.addAttribute(uri, localName, qName, "CDATA", attrValue);
+        return true;
     }
 
     /**
      * Name ::= (Letter | '_' | ':') (Letter | Digit | '.' | '_' | '-' | ':')*
      */
     private String parseName() throws JasperException {
-	char ch = (char)reader.peekChar();
-	if (Character.isLetter(ch) || ch == '_' || ch == ':') {
-	    StringBuffer buf = new StringBuffer();
-	    buf.append(ch);
-	    reader.nextChar();
-	    ch = (char)reader.peekChar();
-	    while (Character.isLetter(ch) || Character.isDigit(ch) ||
-			ch == '.' || ch == '_' || ch == '-' || ch == ':') {
-		buf.append(ch);
-		reader.nextChar();
-		ch = (char) reader.peekChar();
-	    }
-	    return buf.toString();
-	}
-	return null;
+        char ch = (char)reader.peekChar();
+        if (Character.isLetter(ch) || ch == '_' || ch == ':') {
+            StringBuffer buf = new StringBuffer();
+            buf.append(ch);
+            reader.nextChar();
+            ch = (char)reader.peekChar();
+            while (Character.isLetter(ch) || Character.isDigit(ch) ||
+                        ch == '.' || ch == '_' || ch == '-' || ch == ':') {
+                buf.append(ch);
+                reader.nextChar();
+                ch = (char) reader.peekChar();
+            }
+            return buf.toString();
+        }
+        return null;
     }
 
     /**
      * AttributeValueDouble ::= (QuotedChar - '"')*
-     *				('"' | <TRANSLATION_ERROR>)
+     *                                ('"' | <TRANSLATION_ERROR>)
      * RTAttributeValueDouble ::= ((QuotedChar - '"')* - ((QuotedChar-'"')'%>"')
-     *				  ('%>"' | TRANSLATION_ERROR)
+     *                                  ('%>"' | TRANSLATION_ERROR)
      */
     private String parseAttributeValue(String watch) throws JasperException {
-	Mark start = reader.mark();
-	Mark stop = reader.skipUntilIgnoreEsc(watch);
-	if (stop == null) {
-	    err.jspError(start, "jsp.error.attribute.unterminated", watch);
-	}
+        Mark start = reader.mark();
+        Mark stop = reader.skipUntilIgnoreEsc(watch);
+        if (stop == null) {
+            err.jspError(start, "jsp.error.attribute.unterminated", watch);
+        }
 
-	String ret = parseQuoted(reader.getText(start, stop));
-	if (watch.length() == 1)	// quote
-	    return ret;
+        String ret = parseQuoted(reader.getText(start, stop));
+        if (watch.length() == 1)        // quote
+            return ret;
 
-	// putback delimiter '<%=' and '%>', since they are needed if the
-	// attribute does not allow RTexpression.
-	return "<%=" + ret + "%>";
+        // putback delimiter '<%=' and '%>', since they are needed if the
+        // attribute does not allow RTexpression.
+        return "<%=" + ret + "%>";
     }
 
     /**
      * QuotedChar ::=   '&apos;'
-     *	              | '&quot;'
+     *                      | '&quot;'
      *                | '\\'
      *                | '\"'
      *                | "\'"
@@ -261,83 +261,83 @@
      *                | Char
      */
     private String parseQuoted(String tx) {
-	StringBuffer buf = new StringBuffer();
-	int size = tx.length();
-	int i = 0;
-	while (i < size) {
-	    char ch = tx.charAt(i);
-	    if (ch == '&') {
-		if (i+5 < size && tx.charAt(i+1) == 'a'
-		        && tx.charAt(i+2) == 'p' && tx.charAt(i+3) == 'o'
-		        && tx.charAt(i+4) == 's' && tx.charAt(i+5) == ';') {
-		    buf.append('\'');
-		    i += 6;
-		} else if (i+5 < size && tx.charAt(i+1) == 'q'
-			   && tx.charAt(i+2) == 'u' && tx.charAt(i+3) == 'o'
-			   && tx.charAt(i+4) == 't' && tx.charAt(i+5) == ';') {
-		    buf.append('"');
-		    i += 6;
-		} else {
-		    buf.append(ch);
-		    ++i;
-		}
-	    } else if (ch == '\\' && i+1 < size) {
-		ch = tx.charAt(i+1);
-		if (ch == '\\' || ch == '\"' || ch == '\'' || ch == '>') {
-		    buf.append(ch);
-		    i += 2;
-		} else if (ch == '$') {
-		    // Replace "\$" with some special char.  XXX hack!
-		    buf.append(Constants.ESC);
-		    i += 2;
-		} else {
-		    buf.append('\\');
-		    ++i;
-		}
-	    } else {
-		buf.append(ch);
-		++i;
-	    }
-	}
-	return buf.toString();
+        StringBuffer buf = new StringBuffer();
+        int size = tx.length();
+        int i = 0;
+        while (i < size) {
+            char ch = tx.charAt(i);
+            if (ch == '&') {
+                if (i+5 < size && tx.charAt(i+1) == 'a'
+                        && tx.charAt(i+2) == 'p' && tx.charAt(i+3) == 'o'
+                        && tx.charAt(i+4) == 's' && tx.charAt(i+5) == ';') {
+                    buf.append('\'');
+                    i += 6;
+                } else if (i+5 < size && tx.charAt(i+1) == 'q'
+                           && tx.charAt(i+2) == 'u' && tx.charAt(i+3) == 'o'
+                           && tx.charAt(i+4) == 't' && tx.charAt(i+5) == ';') {
+                    buf.append('"');
+                    i += 6;
+                } else {
+                    buf.append(ch);
+                    ++i;
+                }
+            } else if (ch == '\\' && i+1 < size) {
+                ch = tx.charAt(i+1);
+                if (ch == '\\' || ch == '\"' || ch == '\'' || ch == '>') {
+                    buf.append(ch);
+                    i += 2;
+                } else if (ch == '$') {
+                    // Replace "\$" with some special char.  XXX hack!
+                    buf.append(Constants.ESC);
+                    i += 2;
+                } else {
+                    buf.append('\\');
+                    ++i;
+                }
+            } else {
+                buf.append(ch);
+                ++i;
+            }
+        }
+        return buf.toString();
     }
 
     private String parseScriptText(String tx) {
-	CharArrayWriter cw = new CharArrayWriter();
-	int size = tx.length();
-	int i = 0;
-	while (i < size) {
-	    char ch = tx.charAt(i);
-	    if (i+2 < size && ch == '%' && tx.charAt(i+1) == '\\'
-		    && tx.charAt(i+2) == '>') {
-		cw.write('%');
-		cw.write('>');
-		i += 3;
-	    } else {
-		cw.write(ch);
-		++i;
-	    }
-	}
-	cw.close();
-	return cw.toString();
+        CharArrayWriter cw = new CharArrayWriter();
+        int size = tx.length();
+        int i = 0;
+        while (i < size) {
+            char ch = tx.charAt(i);
+            if (i+2 < size && ch == '%' && tx.charAt(i+1) == '\\'
+                    && tx.charAt(i+2) == '>') {
+                cw.write('%');
+                cw.write('>');
+                i += 3;
+            } else {
+                cw.write(ch);
+                ++i;
+            }
+        }
+        cw.close();
+        return cw.toString();
     }
 
     /*
      * Invokes parserController to parse the included page
      */
     private void processIncludeDirective(String file, Node parent) 
-		throws JasperException {
-	if (file == null) {
-	    return;
-	}
+                throws JasperException {
+        if (file == null) {
+            return;
+        }
 
-	try {
-	    parserController.parse(file, parent, jarFileUrl);
-	} catch (FileNotFoundException ex) {
-	    err.jspError(start, "jsp.error.file.not.found", file);
-	} catch (Exception ex) {
-	    err.jspError(start, ex.getMessage());
-	}
+        try {
+            parserController.parse(file, parent, jarFileUrl);
+        } catch (FileNotFoundException ex) {
+            err.jspError(start, "jsp.error.file.not.found", file);
+        } catch (Exception ex) {
+            err.jspError(start, ex.getMessage());
+        }
     }
 
     /*
@@ -345,19 +345,19 @@
      *   PageDirective ::= ( S Attribute)*
      */
     private void parsePageDirective(Node parent) throws JasperException {
-	Attributes attrs = parseAttributes();
-	Node.PageDirective n = new Node.PageDirective(attrs, start, parent);
+        Attributes attrs = parseAttributes();
+        Node.PageDirective n = new Node.PageDirective(attrs, start, parent);
 
-	/*
-	 * A page directive may contain multiple 'import' attributes, each of
-	 * which consists of a comma-separated list of package names.
-	 * Store each list with the node, where it is parsed.
-	 */
-	for (int i = 0; i < attrs.getLength(); i++) {
-	    if ("import".equals(attrs.getQName(i))) {
-		n.addImport(attrs.getValue(i));
-	    }
-	}
+        /*
+         * A page directive may contain multiple 'import' attributes, each of
+         * which consists of a comma-separated list of package names.
+         * Store each list with the node, where it is parsed.
+         */
+        for (int i = 0; i < attrs.getLength(); i++) {
+            if ("import".equals(attrs.getQName(i))) {
+                n.addImport(attrs.getValue(i));
+            }
+        }
     }
 
     /*
@@ -365,11 +365,11 @@
      *   IncludeDirective ::= ( S Attribute)*
      */
     private void parseIncludeDirective(Node parent) throws JasperException {
-	Attributes attrs = parseAttributes();
+        Attributes attrs = parseAttributes();
 
-	// Included file expanded here
-	Node includeNode = new Node.IncludeDirective(attrs, start, parent);
-	processIncludeDirective(attrs.getValue("file"), includeNode);
+        // Included file expanded here
+        Node includeNode = new Node.IncludeDirective(attrs, start, parent);
+        processIncludeDirective(attrs.getValue("file"), includeNode);
     }
 
     /**
@@ -398,22 +398,22 @@
      */
     private void parseTaglibDirective(Node parent) throws JasperException {
 
-	Attributes attrs = parseAttributes();
-	String uri = attrs.getValue("uri");
-	String prefix = attrs.getValue("prefix");
-	if (prefix != null) {
+        Attributes attrs = parseAttributes();
+        String uri = attrs.getValue("uri");
+        String prefix = attrs.getValue("prefix");
+        if (prefix != null) {
             Mark prevMark = pageInfo.getNonCustomTagPrefix(prefix);
             if (prevMark != null) {
                 err.jspError(reader.mark(), "jsp.error.prefix.use_before_dcl",
                     prefix, prevMark.getFile(), "" + prevMark.getLineNumber());
             }
-	    if (uri != null) {
-		String uriPrev = pageInfo.getURI(prefix);
-		if (uriPrev != null && !uriPrev.equals(uri)) {
-		    err.jspError(reader.mark(), "jsp.error.prefix.refined",
-			prefix, uri, uriPrev);
-		}
-		if (pageInfo.getTaglib(uri) == null) {
+            if (uri != null) {
+                String uriPrev = pageInfo.getURI(prefix);
+                if (uriPrev != null && !uriPrev.equals(uri)) {
+                    err.jspError(reader.mark(), "jsp.error.prefix.refined",
+                        prefix, uri, uriPrev);
+                }
+                if (pageInfo.getTaglib(uri) == null) {
             TagLibraryInfoImpl impl = null;
             if (ctxt.getOptions().isCaching()) {
                 impl = (TagLibraryInfoImpl) ctxt.getOptions().getCache().get(uri);
@@ -430,97 +430,97 @@
                     ctxt.getOptions().getCache().put(uri, impl);
                 }
             }
-		    pageInfo.addTaglib(uri, impl);
-		}
-		pageInfo.addPrefixMapping(prefix, uri);
-	    } else {
-		String tagdir = attrs.getValue("tagdir");
-		if (tagdir != null) {
-		    String urnTagdir = URN_JSPTAGDIR + tagdir;
-		    if (pageInfo.getTaglib(urnTagdir) == null) {
-			pageInfo.addTaglib(urnTagdir,
-					   new ImplicitTagLibraryInfo(
+                    pageInfo.addTaglib(uri, impl);
+                }
+                pageInfo.addPrefixMapping(prefix, uri);
+            } else {
+                String tagdir = attrs.getValue("tagdir");
+                if (tagdir != null) {
+                    String urnTagdir = URN_JSPTAGDIR + tagdir;
+                    if (pageInfo.getTaglib(urnTagdir) == null) {
+                        pageInfo.addTaglib(urnTagdir,
+                                           new ImplicitTagLibraryInfo(
                                                    ctxt,
-						   parserController,
-						   prefix, 
-						   tagdir,
-						   err));
-		    }
-		    pageInfo.addPrefixMapping(prefix, urnTagdir);
-		}
-	    }
-	}
+                                                   parserController,
+                                                   prefix, 
+                                                   tagdir,
+                                                   err));
+                    }
+                    pageInfo.addPrefixMapping(prefix, urnTagdir);
+                }
+            }
+        }
 
-	new Node.TaglibDirective(attrs, start, parent);
+        new Node.TaglibDirective(attrs, start, parent);
     }
 
     /*
      * Parses a directive with the following syntax:
      *   Directive ::= S? (   'page' PageDirective
-     *			    | 'include' IncludeDirective
-     *			    | 'taglib' TagLibDirective)
-     *		       S? '%>'
+     *                            | 'include' IncludeDirective
+     *                            | 'taglib' TagLibDirective)
+     *                       S? '%>'
      *
      *   TagDirective ::= S? ('tag' PageDirective
-     *			    | 'include' IncludeDirective
-     *			    | 'taglib' TagLibDirective)
+     *                            | 'include' IncludeDirective
+     *                            | 'taglib' TagLibDirective)
      *                      | 'attribute AttributeDirective
      *                      | 'variable VariableDirective
-     *		       S? '%>'
+     *                       S? '%>'
      */
     private void parseDirective(Node parent) throws JasperException {
-	reader.skipSpaces();
+        reader.skipSpaces();
 
-	String directive = null;
-	if (reader.matches("page")) {
-	    directive = "&lt;%@ page";
-	    if (isTagFile) {
-		err.jspError(reader.mark(), "jsp.error.directive.istagfile",
-					    directive);
-	    }
-	    parsePageDirective(parent);
-	} else if (reader.matches("include")) {
-	    directive = "&lt;%@ include";
-	    parseIncludeDirective(parent);
-	} else if (reader.matches("taglib")) {
-	    if (directivesOnly) {
-	        // No need to get the tagLibInfo objects.  This alos suppresses
-	        // parsing of any tag files used in this tag file.
-	        return;
-	    }
-	    directive = "&lt;%@ taglib";
-	    parseTaglibDirective(parent);
-	} else if (reader.matches("tag")) {
-	    directive = "&lt;%@ tag";
-	    if (!isTagFile) {
-		err.jspError(reader.mark(), "jsp.error.directive.isnottagfile",
-					    directive);
-	    }
-	    parseTagDirective(parent);
-	} else if (reader.matches("attribute")) {
-	    directive = "&lt;%@ attribute";
-	    if (!isTagFile) {
-		err.jspError(reader.mark(), "jsp.error.directive.isnottagfile",
-					    directive);
-	    }
-	    parseAttributeDirective(parent);
-	} else if (reader.matches("variable")) {
-	    directive = "&lt;%@ variable";
-	    if (!isTagFile) {
-		err.jspError(reader.mark(), "jsp.error.directive.isnottagfile",
-					    directive);
-	    }
-	    parseVariableDirective(parent);
-	} else {
-	    err.jspError(reader.mark(), "jsp.error.invalid.directive");
-	}
+        String directive = null;
+        if (reader.matches("page")) {
+            directive = "&lt;%@ page";
+            if (isTagFile) {
+                err.jspError(reader.mark(), "jsp.error.directive.istagfile",
+                                            directive);
+            }
+            parsePageDirective(parent);
+        } else if (reader.matches("include")) {
+            directive = "&lt;%@ include";
+            parseIncludeDirective(parent);
+        } else if (reader.matches("taglib")) {
+            if (directivesOnly) {
+                // No need to get the tagLibInfo objects.  This alos suppresses
+                // parsing of any tag files used in this tag file.
+                return;
+            }
+            directive = "&lt;%@ taglib";
+            parseTaglibDirective(parent);
+        } else if (reader.matches("tag")) {
+            directive = "&lt;%@ tag";
+            if (!isTagFile) {
+                err.jspError(reader.mark(), "jsp.error.directive.isnottagfile",
+                                            directive);
+            }
+            parseTagDirective(parent);
+        } else if (reader.matches("attribute")) {
+            directive = "&lt;%@ attribute";
+            if (!isTagFile) {
+                err.jspError(reader.mark(), "jsp.error.directive.isnottagfile",
+                                            directive);
+            }
+            parseAttributeDirective(parent);
+        } else if (reader.matches("variable")) {
+            directive = "&lt;%@ variable";
+            if (!isTagFile) {
+                err.jspError(reader.mark(), "jsp.error.directive.isnottagfile",
+                                            directive);
+            }
+            parseVariableDirective(parent);
+        } else {
+            err.jspError(reader.mark(), "jsp.error.invalid.directive");
+        }
 
-	reader.skipSpaces();
-	if (!reader.matches("%>")) {
-	    err.jspError(start, "jsp.error.unterminated", directive);
-	}
+        reader.skipSpaces();
+        if (!reader.matches("%>")) {
+            err.jspError(start, "jsp.error.unterminated", directive);
+        }
     }
-	
+        
     /*
      * Parses a directive with the following syntax:
      *
@@ -597,8 +597,8 @@
      *   PageDirective ::= ( S Attribute)*
      */
     private void parseTagDirective(Node parent) throws JasperException {
-	Attributes attrs = parseAttributes();
-	Node.TagDirective n = new Node.TagDirective(attrs, start, parent);
+        Attributes attrs = parseAttributes();
+        Node.TagDirective n = new Node.TagDirective(attrs, start, parent);
 
         /*
          * A page directive may contain multiple 'import' attributes, each of
@@ -617,9 +617,9 @@
      *   AttributeDirective ::= ( S Attribute)*
      */
     private void parseAttributeDirective(Node parent) throws JasperException {
-	Attributes attrs = parseAttributes();
-	Node.AttributeDirective n =
-		new Node.AttributeDirective(attrs, start, parent);
+        Attributes attrs = parseAttributes();
+        Node.AttributeDirective n =
+                new Node.AttributeDirective(attrs, start, parent);
     }
 
     /*
@@ -627,36 +627,36 @@
      *   PageDirective ::= ( S Attribute)*
      */
     private void parseVariableDirective(Node parent) throws JasperException {
-	Attributes attrs = parseAttributes();
-	Node.VariableDirective n =
-		new Node.VariableDirective(attrs, start, parent);
+        Attributes attrs = parseAttributes();
+        Node.VariableDirective n =
+                new Node.VariableDirective(attrs, start, parent);
     }
 
     /*
      * JSPCommentBody ::= (Char* - (Char* '--%>')) '--%>'
      */
-    private void parseComment(Node parent) throws JasperException {	
-	start = reader.mark();
-	Mark stop = reader.skipUntil("--%>");
-	if (stop == null) {
-	    err.jspError(start, "jsp.error.unterminated", "&lt;%--");
-	}
+    private void parseComment(Node parent) throws JasperException {        
+        start = reader.mark();
+        Mark stop = reader.skipUntil("--%>");
+        if (stop == null) {
+            err.jspError(start, "jsp.error.unterminated", "&lt;%--");
+        }
 
-	new Node.Comment(reader.getText(start, stop), start, parent);
+        new Node.Comment(reader.getText(start, stop), start, parent);
     }
 
     /*
      * DeclarationBody ::= (Char* - (char* '%>')) '%>'
      */
     private void parseDeclaration(Node parent) throws JasperException {
-	start = reader.mark();
-	Mark stop = reader.skipUntil("%>");
-	if (stop == null) {
-	    err.jspError(start, "jsp.error.unterminated", "&lt;%!");
-	}
+        start = reader.mark();
+        Mark stop = reader.skipUntil("%>");
+        if (stop == null) {
+            err.jspError(start, "jsp.error.unterminated", "&lt;%!");
+        }
 
-	new Node.Declaration(parseScriptText(reader.getText(start, stop)),
-			     start, parent);
+        new Node.Declaration(parseScriptText(reader.getText(start, stop)),
+                             start, parent);
     }
 
     /*
@@ -675,7 +675,7 @@
                 err.jspError(start, "jsp.error.unterminated",
                         "&lt;jsp:declaration&gt;");
             }
-	    Mark stop;
+            Mark stop;
             String text;
             while (true) {
                 start = reader.mark();
@@ -684,7 +684,7 @@
                     err.jspError(start, "jsp.error.unterminated",
                         "&lt;jsp:declaration&gt;");
                 }
-		text = parseScriptText(reader.getText(start, stop));
+                text = parseScriptText(reader.getText(start, stop));
                 new Node.Declaration(text, start, parent);
                 if (reader.matches("![CDATA[")) {
                     start = reader.mark();
@@ -692,14 +692,14 @@
                     if (stop == null) {
                         err.jspError(start, "jsp.error.unterminated", "CDATA");
                     }
-		    text = parseScriptText(reader.getText(start, stop));
+                    text = parseScriptText(reader.getText(start, stop));
                     new Node.Declaration(text, start, parent);
                 }
                 else {
                     break;
                 }
-	    }
-		
+            }
+                
             if (!reader.matchesETagWithoutLessThan( "jsp:declaration" ) ) {
                 err.jspError(start, "jsp.error.unterminated",
                         "&lt;jsp:declaration&gt;");
@@ -711,14 +711,14 @@
      * ExpressionBody ::= (Char* - (char* '%>')) '%>'
      */
     private void parseExpression(Node parent) throws JasperException {
-	start = reader.mark();
-	Mark stop = reader.skipUntil("%>");
-	if (stop == null) {
-	    err.jspError(start, "jsp.error.unterminated", "&lt;%=");
-	}
+        start = reader.mark();
+        Mark stop = reader.skipUntil("%>");
+        if (stop == null) {
+            err.jspError(start, "jsp.error.unterminated", "&lt;%=");
+        }
 
-	new Node.Expression(parseScriptText(reader.getText(start, stop)),
-			    start, parent);
+        new Node.Expression(parseScriptText(reader.getText(start, stop)),
+                            start, parent);
     }
 
     /*
@@ -799,14 +799,14 @@
      * ScriptletBody ::= (Char* - (char* '%>')) '%>'
      */
     private void parseScriptlet(Node parent) throws JasperException {
-	start = reader.mark();
-	Mark stop = reader.skipUntil("%>");
-	if (stop == null) {
-	    err.jspError(start, "jsp.error.unterminated", "&lt;%");
-	}
+        start = reader.mark();
+        Mark stop = reader.skipUntil("%>");
+        if (stop == null) {
+            err.jspError(start, "jsp.error.unterminated", "&lt;%");
+        }
 
-	new Node.Scriptlet(parseScriptText(reader.getText(start, stop)),
-			   start, parent);
+        new Node.Scriptlet(parseScriptText(reader.getText(start, stop)),
+                           start, parent);
     }
 
     /*
@@ -852,16 +852,16 @@
             }
         }
     }
-	
+        
     /**
      * Param ::= '<jsp:param' S Attributes S? EmptyBody S?
      */
     private void parseParam(Node parent) throws JasperException {
-	if (!reader.matches("<jsp:param")) {
-	    err.jspError(reader.mark(), "jsp.error.paramexpected");
-	}
-	Attributes attrs = parseAttributes();
-	reader.skipSpaces();
+        if (!reader.matches("<jsp:param")) {
+            err.jspError(reader.mark(), "jsp.error.paramexpected");
+        }
+        Attributes attrs = parseAttributes();
+        reader.skipSpaces();
         
         Node paramActionNode = new Node.ParamAction( attrs, start, parent );
         
@@ -889,13 +889,13 @@
      * JspBodyParam ::= S? '>' Param* '</jsp:body>'
      */
     private void parseInclude(Node parent) throws JasperException {
-	Attributes attrs = parseAttributes();
-	reader.skipSpaces();
+        Attributes attrs = parseAttributes();
+        reader.skipSpaces();
 
         Node includeNode = new Node.IncludeAction( attrs, start, parent );
         
         parseOptionalBody(includeNode, "jsp:include", 
-			  JAVAX_BODY_CONTENT_PARAM);
+                          JAVAX_BODY_CONTENT_PARAM);
     }
 
     /*
@@ -903,18 +903,18 @@
      * StdActionContent ::= Attributes ParamBody
      */
     private void parseForward(Node parent) throws JasperException {
-	Attributes attrs = parseAttributes();
-	reader.skipSpaces();
+        Attributes attrs = parseAttributes();
+        reader.skipSpaces();
 
         Node forwardNode = new Node.ForwardAction( attrs, start, parent );
         
         parseOptionalBody(forwardNode, "jsp:forward",
-			  JAVAX_BODY_CONTENT_PARAM);
+                          JAVAX_BODY_CONTENT_PARAM);
     }
 
     private void parseInvoke(Node parent) throws JasperException {
-	Attributes attrs = parseAttributes();
-	reader.skipSpaces();
+        Attributes attrs = parseAttributes();
+        reader.skipSpaces();
 
         Node invokeNode = new Node.InvokeAction(attrs, start, parent);
         
@@ -922,8 +922,8 @@
     }
 
     private void parseDoBody(Node parent) throws JasperException {
-	Attributes attrs = parseAttributes();
-	reader.skipSpaces();
+        Attributes attrs = parseAttributes();
+        reader.skipSpaces();
 
         Node doBodyNode = new Node.DoBodyAction(attrs, start, parent);
         
@@ -931,8 +931,8 @@
     }
 
     private void parseElement(Node parent) throws JasperException {
-	Attributes attrs = parseAttributes();
-	reader.skipSpaces();
+        Attributes attrs = parseAttributes();
+        reader.skipSpaces();
 
         Node elementNode = new Node.JspElement(attrs, start, parent);
         
@@ -945,13 +945,13 @@
      * StdActionContent ::= Attributes EmptyBody
      */
     private void parseGetProperty(Node parent) throws JasperException {
-	Attributes attrs = parseAttributes();
-	reader.skipSpaces();
+        Attributes attrs = parseAttributes();
+        reader.skipSpaces();
 
         Node getPropertyNode = new Node.GetProperty( attrs, start, parent );
         
         parseOptionalBody(getPropertyNode, "jsp:getProperty",
-			  TagInfo.BODY_CONTENT_EMPTY);
+                          TagInfo.BODY_CONTENT_EMPTY);
     }
 
     /*
@@ -959,13 +959,13 @@
      * StdActionContent ::= Attributes EmptyBody
      */
     private void parseSetProperty(Node parent) throws JasperException {
-	Attributes attrs = parseAttributes();
-	reader.skipSpaces();
+        Attributes attrs = parseAttributes();
+        reader.skipSpaces();
 
         Node setPropertyNode = new Node.SetProperty( attrs, start, parent );
         
         parseOptionalBody(setPropertyNode, "jsp:setProperty",
-			  TagInfo.BODY_CONTENT_EMPTY);
+                          TagInfo.BODY_CONTENT_EMPTY);
     }
 
     /*
@@ -976,7 +976,7 @@
     private void parseEmptyBody( Node parent, String tag ) 
         throws JasperException
     {
-	if( reader.matches("/>") ) {
+        if( reader.matches("/>") ) {
             // Done
         }
         else if( reader.matches( ">" ) ) {
@@ -1001,7 +1001,7 @@
             }
         }
         else {
-	    err.jspError(reader.mark(), "jsp.error.unterminated",
+            err.jspError(reader.mark(), "jsp.error.unterminated",
                 "&lt;" + tag );
         }
     }
@@ -1011,8 +1011,8 @@
      * StdActionContent ::= Attributes OptionalBody
      */
     private void parseUseBean(Node parent) throws JasperException {
-	Attributes attrs = parseAttributes();
-	reader.skipSpaces();
+        Attributes attrs = parseAttributes();
+        reader.skipSpaces();
         
         Node useBeanNode = new Node.UseBean( attrs, start, parent );
         
@@ -1049,15 +1049,15 @@
     private void parseOptionalBody( Node parent, String tag, String bodyType ) 
         throws JasperException 
     {
-	if (reader.matches("/>")) {
-	    // EmptyBody
-	    return;
-	}
+        if (reader.matches("/>")) {
+            // EmptyBody
+            return;
+        }
 
-	if (!reader.matches(">")) {
-	    err.jspError(reader.mark(), "jsp.error.unterminated",
-			 "&lt;" + tag );
-	}
+        if (!reader.matches(">")) {
+            err.jspError(reader.mark(), "jsp.error.unterminated",
+                         "&lt;" + tag );
+        }
         
         if( reader.matchesETag( tag ) ) {
             // EmptyBody
@@ -1130,9 +1130,9 @@
      *              '</jsp:params>'
      */
     private void parseJspParams(Node parent) throws JasperException {
-	Node jspParamsNode = new Node.ParamsAction(start, parent);
-	parseOptionalBody(jspParamsNode, "jsp:params",
-			  JAVAX_BODY_CONTENT_PARAM );
+        Node jspParamsNode = new Node.ParamsAction(start, parent);
+        parseOptionalBody(jspParamsNode, "jsp:params",
+                          JAVAX_BODY_CONTENT_PARAM );
     }
 
     /*
@@ -1152,9 +1152,9 @@
      *                 )
      */
     private void parseFallBack(Node parent) throws JasperException {
-	Node fallBackNode = new Node.FallBackAction(start, parent);
-	parseOptionalBody(fallBackNode, "jsp:fallback", 
-			  JAVAX_BODY_CONTENT_TEMPLATE_TEXT);
+        Node fallBackNode = new Node.FallBackAction(start, parent);
+        parseOptionalBody(fallBackNode, "jsp:fallback", 
+                          JAVAX_BODY_CONTENT_TEMPLATE_TEXT);
     }
 
     /*
@@ -1175,10 +1175,10 @@
      *
      */
     private void parsePlugin(Node parent) throws JasperException {
-	Attributes attrs = parseAttributes();
-	reader.skipSpaces();
+        Attributes attrs = parseAttributes();
+        reader.skipSpaces();
         
-	Node pluginNode = new Node.PlugIn(attrs, start, parent);
+        Node pluginNode = new Node.PlugIn(attrs, start, parent);
         
         parseOptionalBody( pluginNode, "jsp:plugin", 
             JAVAX_BODY_CONTENT_PLUGIN );
@@ -1214,49 +1214,49 @@
      *                    | 'element'       StdActionContent
      */
     private void parseStandardAction(Node parent) throws JasperException {
-	Mark start = reader.mark();
+        Mark start = reader.mark();
 
-	if (reader.matches(INCLUDE_ACTION)) {
-	    parseInclude(parent);
-	} else if (reader.matches(FORWARD_ACTION)) {
-	    parseForward(parent);
-	} else if (reader.matches(INVOKE_ACTION)) {
-	    if (!isTagFile) {
-		err.jspError(reader.mark(), "jsp.error.action.isnottagfile",
-			     "&lt;jsp:invoke");
-	    }
-	    parseInvoke(parent);
-	} else if (reader.matches(DOBODY_ACTION)) {
-	    if (!isTagFile) {
-		err.jspError(reader.mark(), "jsp.error.action.isnottagfile",
-			     "&lt;jsp:doBody");
-	    }
-	    parseDoBody(parent);
-	} else if (reader.matches(GET_PROPERTY_ACTION)) {
-	    parseGetProperty(parent);
-	} else if (reader.matches(SET_PROPERTY_ACTION)) {
-	    parseSetProperty(parent);
-	} else if (reader.matches(USE_BEAN_ACTION)) {
-	    parseUseBean(parent);
-	} else if (reader.matches(PLUGIN_ACTION)) {
-	    parsePlugin(parent);
-	} else if (reader.matches(ELEMENT_ACTION)) {
-	    parseElement(parent);
-	} else if (reader.matches(ATTRIBUTE_ACTION)) {
-	    err.jspError(start, "jsp.error.namedAttribute.invalidUse");
-	} else if (reader.matches(BODY_ACTION)) {
-	    err.jspError(start, "jsp.error.jspbody.invalidUse");
-	} else if (reader.matches(FALLBACK_ACTION)) {
-	    err.jspError(start, "jsp.error.fallback.invalidUse");
-	} else if (reader.matches(PARAMS_ACTION)) {
-	    err.jspError(start, "jsp.error.params.invalidUse");
-	} else if (reader.matches(PARAM_ACTION)) {
-	    err.jspError(start, "jsp.error.param.invalidUse");
-	} else if (reader.matches(OUTPUT_ACTION)) {
-	    err.jspError(start, "jsp.error.jspoutput.invalidUse");
-	} else {
-	    err.jspError(start, "jsp.error.badStandardAction");
-	}
+        if (reader.matches(INCLUDE_ACTION)) {
+            parseInclude(parent);
+        } else if (reader.matches(FORWARD_ACTION)) {
+            parseForward(parent);
+        } else if (reader.matches(INVOKE_ACTION)) {
+            if (!isTagFile) {
+                err.jspError(reader.mark(), "jsp.error.action.isnottagfile",
+                             "&lt;jsp:invoke");
+            }
+            parseInvoke(parent);
+        } else if (reader.matches(DOBODY_ACTION)) {
+            if (!isTagFile) {
+                err.jspError(reader.mark(), "jsp.error.action.isnottagfile",
+                             "&lt;jsp:doBody");
+            }
+            parseDoBody(parent);
+        } else if (reader.matches(GET_PROPERTY_ACTION)) {
+            parseGetProperty(parent);
+        } else if (reader.matches(SET_PROPERTY_ACTION)) {
+            parseSetProperty(parent);
+        } else if (reader.matches(USE_BEAN_ACTION)) {
+            parseUseBean(parent);
+        } else if (reader.matches(PLUGIN_ACTION)) {
+            parsePlugin(parent);
+        } else if (reader.matches(ELEMENT_ACTION)) {
+            parseElement(parent);
+        } else if (reader.matches(ATTRIBUTE_ACTION)) {
+            err.jspError(start, "jsp.error.namedAttribute.invalidUse");
+        } else if (reader.matches(BODY_ACTION)) {
+            err.jspError(start, "jsp.error.jspbody.invalidUse");
+        } else if (reader.matches(FALLBACK_ACTION)) {
+            err.jspError(start, "jsp.error.fallback.invalidUse");
+        } else if (reader.matches(PARAMS_ACTION)) {
+            err.jspError(start, "jsp.error.params.invalidUse");
+        } else if (reader.matches(PARAM_ACTION)) {
+            err.jspError(start, "jsp.error.param.invalidUse");
+        } else if (reader.matches(OUTPUT_ACTION)) {
+            err.jspError(start, "jsp.error.jspoutput.invalidUse");
+        } else {
+            err.jspError(start, "jsp.error.badStandardAction");
+        }
     }
 
     /*
@@ -1285,97 +1285,98 @@
      */
     private boolean parseCustomTag(Node parent) throws JasperException {
 
-	if (reader.peekChar() != '<') {
-	    return false;
-	}
+        if (reader.peekChar() != '<') {
+            return false;
+        }
 
         // Parse 'CustomAction' production (tag prefix and custom action name)
-	reader.nextChar();	// skip '<'
-	String tagName = reader.parseToken(false);
-	int i = tagName.indexOf(':');
-	if (i == -1) {
-	    reader.reset(start);
-	    return false;
-	}
+        reader.nextChar();        // skip '<'
+        String tagName = reader.parseToken(false);
+        int i = tagName.indexOf(':');
+        if (i == -1) {
+            reader.reset(start);
+            return false;
+        }
 
-	String prefix = tagName.substring(0, i);
-	String shortTagName = tagName.substring(i+1);
+        String prefix = tagName.substring(0, i);
+        String shortTagName = tagName.substring(i+1);
 
-	// Check if this is a user-defined tag.
-	String uri = pageInfo.getURI(prefix);
+        // Check if this is a user-defined tag.
+        String uri = pageInfo.getURI(prefix);
         if (uri == null) {
-	    reader.reset(start);
+            reader.reset(start);
             // Remember the prefix for later error checking
             pageInfo.putNonCustomTagPrefix(prefix, reader.mark());
-	    return false;
-	}
+            return false;
+        }
 
         TagLibraryInfo tagLibInfo = pageInfo.getTaglib(uri);
-	TagInfo tagInfo = tagLibInfo.getTag(shortTagName);
-	TagFileInfo tagFileInfo = tagLibInfo.getTagFile(shortTagName);
-	if (tagInfo == null && tagFileInfo == null) {
-	    err.jspError(start, "jsp.error.bad_tag", shortTagName, prefix);
-	}
-	Class tagHandlerClass = null;
-	if (tagInfo != null) {
-	    // Must be a classic tag, load it here.
-	    // tag files will be loaded later, in TagFileProcessor
-	    String handlerClassName = tagInfo.getTagClassName();
-	    try {
-	        tagHandlerClass = ctxt.getClassLoader().loadClass(handlerClassName);
-	    } catch (Exception e) {
-	        err.jspError(start, "jsp.error.loadclass.taghandler",
-			     handlerClassName, tagName);
-	    }
-	}
+        TagInfo tagInfo = tagLibInfo.getTag(shortTagName);
+        TagFileInfo tagFileInfo = tagLibInfo.getTagFile(shortTagName);
+        if (tagInfo == null && tagFileInfo == null) {
+            err.jspError(start, "jsp.error.bad_tag", shortTagName, prefix);
+        }
+        Class tagHandlerClass = null;
+        if (tagInfo != null) {
+            // Must be a classic tag, load it here.
+            // tag files will be loaded later, in TagFileProcessor
+            String handlerClassName = tagInfo.getTagClassName();
+            try {
+                tagHandlerClass =
+                    ctxt.getClassLoader().loadClass(handlerClassName);
+            } catch (Exception e) {
+                err.jspError(start, "jsp.error.loadclass.taghandler",
+                             handlerClassName, tagName);
+            }
+        }
 
         // Parse 'CustomActionBody' production:
         // At this point we are committed - if anything fails, we produce
         // a translation error.
 
         // Parse 'Attributes' production:
-	Attributes attrs = parseAttributes();
-	reader.skipSpaces();
-	
+        Attributes attrs = parseAttributes();
+        reader.skipSpaces();
+        
         // Parse 'CustomActionEnd' production:
-	if (reader.matches("/>")) {
-	    if (tagInfo != null) {
-		new Node.CustomTag(tagName, prefix, shortTagName, uri, attrs,
-				   start, parent, tagInfo, tagHandlerClass);
-	    } else {
-		new Node.CustomTag(tagName, prefix, shortTagName, uri, attrs,
-				   start, parent, tagFileInfo);
-	    }
-	    return true;
-	}
-	
+        if (reader.matches("/>")) {
+            if (tagInfo != null) {
+                new Node.CustomTag(tagName, prefix, shortTagName, uri, attrs,
+                                   start, parent, tagInfo, tagHandlerClass);
+            } else {
+                new Node.CustomTag(tagName, prefix, shortTagName, uri, attrs,
+                                   start, parent, tagFileInfo);
+            }
+            return true;
+        }
+        
         // Now we parse one of 'CustomActionTagDependent', 
         // 'CustomActionJSPContent', or 'CustomActionScriptlessContent'.
         // depending on body-content in TLD.
 
-	// Looking for a body, it still can be empty; but if there is a
-	// a tag body, its syntax would be dependent on the type of
-	// body content declared in the TLD.
-	String bc;
-	if (tagInfo != null) {
-	    bc = tagInfo.getBodyContent();
-	} else {
-	    bc = tagFileInfo.getTagInfo().getBodyContent();
-	}
+        // Looking for a body, it still can be empty; but if there is a
+        // a tag body, its syntax would be dependent on the type of
+        // body content declared in the TLD.
+        String bc;
+        if (tagInfo != null) {
+            bc = tagInfo.getBodyContent();
+        } else {
+            bc = tagFileInfo.getTagInfo().getBodyContent();
+        }
 
-	Node tagNode = null;
-	if (tagInfo != null) {
-	    tagNode = new Node.CustomTag(tagName, prefix, shortTagName, uri,
-					 attrs, start, parent, tagInfo,
-					 tagHandlerClass);
-	} else {
-	    tagNode = new Node.CustomTag(tagName, prefix, shortTagName, uri,
-					 attrs, start, parent, tagFileInfo);
-	}
+        Node tagNode = null;
+        if (tagInfo != null) {
+            tagNode = new Node.CustomTag(tagName, prefix, shortTagName, uri,
+                                         attrs, start, parent, tagInfo,
+                                         tagHandlerClass);
+        } else {
+            tagNode = new Node.CustomTag(tagName, prefix, shortTagName, uri,
+                                         attrs, start, parent, tagFileInfo);
+        }
 
-	parseOptionalBody( tagNode, tagName, bc );
+        parseOptionalBody( tagNode, tagName, bc );
 
-	return true;
+        return true;
     }
 
     /*
@@ -1384,56 +1385,59 @@
      */
     private void parseTemplateText(Node parent) throws JasperException {
 
-	if (!reader.hasMoreInput())
-	    return;
+        if (!reader.hasMoreInput())
+            return;
 
-	CharArrayWriter ttext = new CharArrayWriter();
-	// Output the first character
-	int ch = reader.nextChar();
+        CharArrayWriter ttext = new CharArrayWriter();
+        // Output the first character
+        int ch = reader.nextChar();
         if (ch == '\\') {
             reader.pushChar();
         } else {
             ttext.write(ch);
         }
 
-	while (reader.hasMoreInput()) {
-	    ch = reader.nextChar();
-	    if (ch == '<') {
+        while (reader.hasMoreInput()) {
+            ch = reader.nextChar();
+            if (ch == '<') {
                 reader.pushChar();
                 break;
             }
-	    else if( ch == '$' ) {
-		if (!reader.hasMoreInput()) {
-		    ttext.write('$');
-		    break;
+            else if( ch == '$' ) {
+                if (!reader.hasMoreInput()) {
+                    ttext.write('$');
+                    break;
                 }
-		ch = reader.nextChar();
-		if (ch == '{') {
-		    reader.pushChar();
-		    reader.pushChar();
-		    break;
-		}
-		ttext.write('$');
-		reader.pushChar();
-		continue;
-	    }
-	    else if (ch == '\\') {
-		if (!reader.hasMoreInput()) {
-		    ttext.write('\\');
-		    break;
-		}
+                ch = reader.nextChar();
+                if (ch == '{') {
+                    reader.pushChar();
+                    reader.pushChar();
+                    break;
+                }
+                ttext.write('$');
+                reader.pushChar();
+                continue;
+            }
+            else if (ch == '\\') {
+                if (!reader.hasMoreInput()) {
+                    ttext.write('\\');
+                    break;
+                }
+                // Look for \% or \$
+                // Only recognize \$ if isELIgnored is false, but since it can
+                // be set in a page directive, it cannot be determined yet.
                 char next = (char)reader.peekChar();
-                // Looking for \% or \$
-                // TODO: only recognize \$ if isELIgnored is false, but since
-                // it can be set in a page directive, it cannot be determined
-                // here.  Argh!
-                if (next == '%' || next == '$') {
+                if (next == '%') {
                     ch = reader.nextChar();
+                } else if(next == '$') {
+                    // Skip the $ and use a hack to flag this sequence
+                    reader.nextChar();
+                    ch = Constants.ESC;
                 }
-	    }
-	    ttext.write(ch);
-	}
-	new Node.TemplateText(ttext.toString(), start, parent);
+            }
+            ttext.write(ch);
+        }
+        new Node.TemplateText(ttext.toString(), start, parent);
     }
     
     /*
@@ -1455,7 +1459,7 @@
             }
             CharArrayWriter ttext = new CharArrayWriter();
             while (reader.hasMoreInput()) {
-        	int ch = reader.nextChar();
+                int ch = reader.nextChar();
                 if( ch == '<' ) {
                     // Check for <![CDATA[
                     if (!reader.matches("![CDATA[")) {
@@ -1473,7 +1477,7 @@
                     if (!reader.hasMoreInput()) {
                         ttext.write('\\');
                         break;
-		    }
+                    }
                     ch = reader.nextChar();
                     if (ch != '$' ) {
                         ttext.write('\\');
@@ -1508,10 +1512,10 @@
 
             new Node.TemplateText( ttext.toString(), start, parent );
 
-	    if (! reader.hasMoreInput()) {
+            if (! reader.hasMoreInput()) {
                 err.jspError( start, "jsp.error.unterminated",
                     "&lt;jsp:text&gt;" );
-	    } else if( !reader.matchesETagWithoutLessThan( "jsp:text" ) ) {
+            } else if( !reader.matchesETagWithoutLessThan( "jsp:text" ) ) {
                 err.jspError( start, "jsp.error.jsptext.badcontent");
             }
         }
@@ -1532,7 +1536,7 @@
      *                 | ( '<jsp:'             StandardAction     )
      *                 | ( '<'                 CustomAction
      *                                         CustomActionBody   )
-     *	               | TemplateText
+     *                       | TemplateText
      */
     private void parseElements(Node parent) 
         throws JasperException 
@@ -1545,35 +1549,35 @@
             return;
         }
         
-	start = reader.mark();
-	if (reader.matches("<%--")) {
-	    parseComment(parent);
-	} else if (reader.matches("<%@")) {
-	    parseDirective(parent);
+        start = reader.mark();
+        if (reader.matches("<%--")) {
+            parseComment(parent);
+        } else if (reader.matches("<%@")) {
+            parseDirective(parent);
         } else if (reader.matches("<jsp:directive.")) {
             parseXMLDirective(parent);
-	} else if (reader.matches("<%!")) {
-	    parseDeclaration(parent);
+        } else if (reader.matches("<%!")) {
+            parseDeclaration(parent);
         } else if (reader.matches("<jsp:declaration")) {
             parseXMLDeclaration(parent);
         } else if (reader.matches("<%=")) {
             parseExpression(parent);
         } else if (reader.matches("<jsp:expression")) {
             parseXMLExpression(parent);
-	} else if (reader.matches("<%")) {
-	    parseScriptlet(parent);
+        } else if (reader.matches("<%")) {
+            parseScriptlet(parent);
         } else if (reader.matches("<jsp:scriptlet")) {
             parseXMLScriptlet(parent);
         } else if (reader.matches("<jsp:text")) {
             parseXMLTemplateText(parent);
         } else if (reader.matches("${")) {
             parseELExpression(parent);
-	} else if (reader.matches("<jsp:")) {
-	    parseStandardAction(parent);
-	} else if (!parseCustomTag(parent)) {
+        } else if (reader.matches("<jsp:")) {
+            parseStandardAction(parent);
+        } else if (!parseCustomTag(parent)) {
             checkUnbalancedEndTag();
             parseTemplateText(parent);
-	}
+        }
     }
 
     /*
@@ -1600,35 +1604,35 @@
         // so we know whether our child nodes are forced scriptless
         scriptlessCount++;
         
-	start = reader.mark();
-	if (reader.matches("<%--")) {
-	    parseComment(parent);
-	} else if (reader.matches("<%@")) {
-	    parseDirective(parent);
+        start = reader.mark();
+        if (reader.matches("<%--")) {
+            parseComment(parent);
+        } else if (reader.matches("<%@")) {
+            parseDirective(parent);
         } else if (reader.matches("<jsp:directive.")) {
             parseXMLDirective(parent);
-	} else if (reader.matches("<%!")) {
-	    err.jspError( reader.mark(), "jsp.error.no.scriptlets" );
+        } else if (reader.matches("<%!")) {
+            err.jspError( reader.mark(), "jsp.error.no.scriptlets" );
         } else if (reader.matches("<jsp:declaration")) {
             err.jspError( reader.mark(), "jsp.error.no.scriptlets" );
-	} else if (reader.matches("<%=")) {
-	    err.jspError( reader.mark(), "jsp.error.no.scriptlets" );
+        } else if (reader.matches("<%=")) {
+            err.jspError( reader.mark(), "jsp.error.no.scriptlets" );
         } else if (reader.matches("<jsp:expression")) {
             err.jspError( reader.mark(), "jsp.error.no.scriptlets" );
-	} else if (reader.matches("<%")) {
-	    err.jspError( reader.mark(), "jsp.error.no.scriptlets" );
+        } else if (reader.matches("<%")) {
+            err.jspError( reader.mark(), "jsp.error.no.scriptlets" );
         } else if (reader.matches("<jsp:scriptlet")) {
             err.jspError( reader.mark(), "jsp.error.no.scriptlets" );
         } else if (reader.matches("<jsp:text")) {
             parseXMLTemplateText(parent);
-	} else if (reader.matches("${")) {
-	    parseELExpression(parent);
-	} else if (reader.matches("<jsp:")) {
-	    parseStandardAction(parent);
-	} else if (!parseCustomTag(parent)) {
+        } else if (reader.matches("${")) {
+            parseELExpression(parent);
+        } else if (reader.matches("<jsp:")) {
+            parseStandardAction(parent);
+        } else if (!parseCustomTag(parent)) {
             checkUnbalancedEndTag();
             parseTemplateText(parent);
-	}
+        }
         
         scriptlessCount--;
     }
@@ -1660,38 +1664,38 @@
             parseXMLDirective(parent);
         } else if (reader.matches("<%!")) {
             err.jspError( reader.mark(), "jsp.error.not.in.template",
-		"Declarations" );
+                "Declarations" );
         } else if (reader.matches("<jsp:declaration")) {
             err.jspError( reader.mark(), "jsp.error.not.in.template",
-		"Declarations" );
+                "Declarations" );
         } else if (reader.matches("<%=")) {
             err.jspError( reader.mark(), "jsp.error.not.in.template",
-		"Expressions" );
+                "Expressions" );
         } else if (reader.matches("<jsp:expression")) {
             err.jspError( reader.mark(), "jsp.error.not.in.template",
-		"Expressions" );
+                "Expressions" );
         } else if (reader.matches("<%")) {
             err.jspError( reader.mark(), "jsp.error.not.in.template",
-		"Scriptlets" );
+                "Scriptlets" );
         } else if (reader.matches("<jsp:scriptlet")) {
             err.jspError( reader.mark(), "jsp.error.not.in.template",
-		"Scriptlets" );
+                "Scriptlets" );
         } else if (reader.matches("<jsp:text")) {
             err.jspError( reader.mark(), "jsp.error.not.in.template",
-		"&lt;jsp:text" );
+                "&lt;jsp:text" );
         } else if (reader.matches("${")) {
             err.jspError( reader.mark(), "jsp.error.not.in.template",
-		"Expression language" );
+                "Expression language" );
         } else if (reader.matches("<jsp:")) {
             err.jspError( reader.mark(), "jsp.error.not.in.template",
-		"Standard actions" );
-	} else if (parseCustomTag(parent)) {
+                "Standard actions" );
+        } else if (parseCustomTag(parent)) {
             err.jspError( reader.mark(), "jsp.error.not.in.template",
-		"Custom actions" );
-	} else {
+                "Custom actions" );
+        } else {
             checkUnbalancedEndTag();
             parseTemplateText(parent);
-	}
+        }
     }
 
     /*
@@ -1723,14 +1727,14 @@
      * TagDependentBody := 
      */
     private void parseTagDependentBody(Node parent, String tag)
-		throws JasperException{
-	Mark bodyStart = reader.mark();
-	Mark bodyEnd = reader.skipUntilETag(tag);
-	if (bodyEnd == null) {
-	    err.jspError(start, "jsp.error.unterminated", "&lt;"+tag );
-	}
-	new Node.TemplateText(reader.getText(bodyStart, bodyEnd), bodyStart,
-			      parent);
+                throws JasperException{
+        Mark bodyStart = reader.mark();
+        Mark bodyEnd = reader.skipUntilETag(tag);
+        if (bodyEnd == null) {
+            err.jspError(start, "jsp.error.unterminated", "&lt;"+tag );
+        }
+        new Node.TemplateText(reader.getText(bodyStart, bodyEnd), bodyStart,
+                              parent);
     }
 
     /*
@@ -1740,16 +1744,16 @@
         throws JasperException 
     {
         Mark start = reader.mark();
-	Node bodyNode = new Node.JspBody(start, parent);
+        Node bodyNode = new Node.JspBody(start, parent);
 
-	reader.skipSpaces();
-	if (!reader.matches("/>")) {
-	    if (!reader.matches(">")) {
-		err.jspError(start, "jsp.error.unterminated",
-			     "&lt;jsp:body");
-	    }
-	    parseBody( bodyNode, "jsp:body", bodyType );
-	}
+        reader.skipSpaces();
+        if (!reader.matches("/>")) {
+            if (!reader.matches(">")) {
+                err.jspError(start, "jsp.error.unterminated",
+                             "&lt;jsp:body");
+            }
+            parseBody( bodyNode, "jsp:body", bodyType );
+        }
     }
 
     /*
@@ -1765,8 +1769,8 @@
         }
         else if( bodyType.equalsIgnoreCase( TagInfo.BODY_CONTENT_EMPTY ) ) {
             if( !reader.matchesETag( tag ) ) {
-		err.jspError(start, "jasper.error.emptybodycontent.nonempty",
-			     tag);
+                err.jspError(start, "jasper.error.emptybodycontent.nonempty",
+                             tag);
             }
         }
         else if( bodyType == JAVAX_BODY_CONTENT_PLUGIN ) {
@@ -1812,14 +1816,14 @@
                     reader.skipSpaces();
                     parseParam( parent );
                 }
-		else if (bodyType == JAVAX_BODY_CONTENT_TEMPLATE_TEXT) {
-		    parseElementsTemplateText(parent);
-		}
+                else if (bodyType == JAVAX_BODY_CONTENT_TEMPLATE_TEXT) {
+                    parseElementsTemplateText(parent);
+                }
             }
             err.jspError(start, "jsp.error.unterminated", "&lt;"+tag );
         }
         else {
-	    err.jspError(start, "jasper.error.bad.bodycontent.type");
+            err.jspError(start, "jasper.error.bad.bodycontent.type");
         }
     }
 
@@ -1834,25 +1838,25 @@
                 new Node.NamedAttribute( attrs, start, parent );
 
             reader.skipSpaces();
-	    if (!reader.matches("/>")) {
-		if (!reader.matches(">")) {
-		    err.jspError(start, "jsp.error.unterminated",
-				 "&lt;jsp:attribute");
-		}
+            if (!reader.matches("/>")) {
+                if (!reader.matches(">")) {
+                    err.jspError(start, "jsp.error.unterminated",
+                                 "&lt;jsp:attribute");
+                }
                 if (namedAttributeNode.isTrim()) {
                     reader.skipSpaces();
                 }
                 parseBody(namedAttributeNode, "jsp:attribute", 
-			  getAttributeBodyType(parent,
-					       attrs.getValue("name")));
+                          getAttributeBodyType(parent,
+                                               attrs.getValue("name")));
                 if (namedAttributeNode.isTrim()) {
                     Node.Nodes subElems = namedAttributeNode.getBody();
-		    if (subElems != null) {
-			Node lastNode = subElems.getNode(subElems.size() - 1);
-			if (lastNode instanceof Node.TemplateText) {
-			    ((Node.TemplateText)lastNode).rtrim();
-			}
-		    }
+                    if (subElems != null) {
+                        Node lastNode = subElems.getNode(subElems.size() - 1);
+                        if (lastNode instanceof Node.TemplateText) {
+                            ((Node.TemplateText)lastNode).rtrim();
+                        }
+                    }
                 }
             }
             reader.skipSpaces();
@@ -1864,58 +1868,58 @@
      */
     private String getAttributeBodyType(Node n, String name) {
 
-	if (n instanceof Node.CustomTag) {
-	    TagInfo tagInfo = ((Node.CustomTag)n).getTagInfo();
-	    TagAttributeInfo[] tldAttrs = tagInfo.getAttributes();
-	    for (int i=0; i<tldAttrs.length; i++) {
-		if (name.equals(tldAttrs[i].getName())) {
-		    if (tldAttrs[i].isFragment()) {
-		        return TagInfo.BODY_CONTENT_SCRIPTLESS;
-		    }
-		    if (tldAttrs[i].canBeRequestTime()) {
-		        return TagInfo.BODY_CONTENT_JSP;
-		    }
-		}
-	    }
-	    if (tagInfo.hasDynamicAttributes()) {
-		return TagInfo.BODY_CONTENT_JSP;
-	    }
-	} else if (n instanceof Node.IncludeAction) {
-	    if ("page".equals(name)) {
-		return TagInfo.BODY_CONTENT_JSP;
-	    }
-	} else if (n instanceof Node.ForwardAction) {
-	    if ("page".equals(name)) {
-		return TagInfo.BODY_CONTENT_JSP;
-	    }
-	} else if (n instanceof Node.SetProperty) {
-	    if ("value".equals(name)) {
-		return TagInfo.BODY_CONTENT_JSP;
-	    }
-	} else if (n instanceof Node.UseBean) {
-	    if ("beanName".equals(name)) {
-		return TagInfo.BODY_CONTENT_JSP;
-	    }
-	} else if (n instanceof Node.PlugIn) {
-	    if ("width".equals(name) || "height".equals(name)) {
-		return TagInfo.BODY_CONTENT_JSP;
-	    }
-	} else if (n instanceof Node.ParamAction) {
-	    if ("value".equals(name)) {
-		return TagInfo.BODY_CONTENT_JSP;
-	    }
-	} else if (n instanceof Node.JspElement) {
-	    return TagInfo.BODY_CONTENT_JSP;
-	}
+        if (n instanceof Node.CustomTag) {
+            TagInfo tagInfo = ((Node.CustomTag)n).getTagInfo();
+            TagAttributeInfo[] tldAttrs = tagInfo.getAttributes();
+            for (int i=0; i<tldAttrs.length; i++) {
+                if (name.equals(tldAttrs[i].getName())) {
+                    if (tldAttrs[i].isFragment()) {
+                        return TagInfo.BODY_CONTENT_SCRIPTLESS;
+                    }
+                    if (tldAttrs[i].canBeRequestTime()) {
+                        return TagInfo.BODY_CONTENT_JSP;
+                    }
+                }
+            }
+            if (tagInfo.hasDynamicAttributes()) {
+                return TagInfo.BODY_CONTENT_JSP;
+            }
+        } else if (n instanceof Node.IncludeAction) {
+            if ("page".equals(name)) {
+                return TagInfo.BODY_CONTENT_JSP;
+            }
+        } else if (n instanceof Node.ForwardAction) {
+            if ("page".equals(name)) {
+                return TagInfo.BODY_CONTENT_JSP;
+            }
+        } else if (n instanceof Node.SetProperty) {
+            if ("value".equals(name)) {
+                return TagInfo.BODY_CONTENT_JSP;
+            }
+        } else if (n instanceof Node.UseBean) {
+            if ("beanName".equals(name)) {
+                return TagInfo.BODY_CONTENT_JSP;
+            }
+        } else if (n instanceof Node.PlugIn) {
+            if ("width".equals(name) || "height".equals(name)) {
+                return TagInfo.BODY_CONTENT_JSP;
+            }
+        } else if (n instanceof Node.ParamAction) {
+            if ("value".equals(name)) {
+                return TagInfo.BODY_CONTENT_JSP;
+            }
+        } else if (n instanceof Node.JspElement) {
+            return TagInfo.BODY_CONTENT_JSP;
+        }
 
-	return JAVAX_BODY_CONTENT_TEMPLATE_TEXT;
+        return JAVAX_BODY_CONTENT_TEMPLATE_TEXT;
     }
 
     private void parseTagFileDirectives(Node parent)
         throws JasperException
     {
-	reader.setSingleFile(true);
-	reader.skipUntil("<");
+        reader.setSingleFile(true);
+        reader.skipUntil("<");
         while (reader.hasMoreInput()) {
             start = reader.mark();
             if (reader.matches("%--")) {
@@ -1925,8 +1929,8 @@
             } else if (reader.matches("jsp:directive.")) {
                 parseXMLDirective(parent);
             }
-	    reader.skipUntil("<");
-	}
+            reader.skipUntil("<");
+        }
     }
 }
 




More information about the jboss-svn-commits mailing list