kinman 02/04/16 18:42:54 Modified: jasper2/src/share/org/apache/jasper/compiler JspReader.java Parser.java Log: - Implemented attribute parser in Parser.java. Next step is to clean up JspReader.java and remove now unused methods. Revision Changes Path 1.4 +0 -37 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/JspReader.java Index: JspReader.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/JspReader.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- JspReader.java 11 Apr 2002 18:14:03 -0000 1.3 +++ JspReader.java 17 Apr 2002 01:42:54 -0000 1.4 @@ -280,43 +280,6 @@ return caw.toCharArray(); } - /** - * Get the text for a scripting element from the stream. It handles - * the escape string "%\>". - * - * @param start The starting postion to read - * @param stop The ending (exclusive) postion to read - * @return The resultant text - */ - char[] getScriptingText(Mark start, Mark stop) throws JasperException { - Mark oldstart = mark(); - reset(start); - CharArrayWriter caw = new CharArrayWriter(); - while (!stop.equals(mark())) { - int c = nextChar(); - caw.write(c); - if (c == '%') { - if (stop.equals(mark())) - break; - int c2 = nextChar(); - if (stop.equals(mark())) { - caw.write(c2); - break; - } - int c3 = nextChar(); - if (c2 == '\\' && c3 == '>') { - caw.write('>'); - } else { - caw.write(c2); - caw.write(c3); - } - } - } - caw.close(); - reset(oldstart); - return caw.toCharArray(); - } - public int peekChar() { return current.stream[current.cursor]; } 1.3 +178 -17 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Parser.java Index: Parser.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Parser.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- Parser.java 4 Apr 2002 02:34:01 -0000 1.2 +++ Parser.java 17 Apr 2002 01:42:54 -0000 1.3 @@ -1,7 +1,7 @@ /* - * $Header: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Parser.java,v 1.2 2002/04/04 02:34:01 kinman Exp $ - * $Revision: 1.2 $ - * $Date: 2002/04/04 02:34:01 $ + * $Header: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Parser.java,v 1.3 2002/04/17 01:42:54 kinman Exp $ + * $Revision: 1.3 $ + * $Date: 2002/04/17 01:42:54 $ * * ==================================================================== * @@ -61,10 +61,12 @@ package org.apache.jasper.compiler; import java.io.FileNotFoundException; +import java.io.CharArrayWriter; import java.util.Hashtable; import javax.servlet.jsp.tagext.TagLibraryInfo; import javax.servlet.jsp.tagext.TagInfo; import org.xml.sax.Attributes; +import org.xml.sax.helpers.AttributesImpl; import org.apache.jasper.JspCompilationContext; import org.apache.jasper.JasperException; @@ -124,6 +126,160 @@ return page; } + /** + * Attributes ::= (S Attribute)* S? + */ + Attributes parseAttributes() throws JasperException { + AttributesImpl attrs = new AttributesImpl(); + + reader.skipSpaces(); + while (parseAttribute(attrs)) + reader.skipSpaces(); + + return attrs; + } + + /** + * Attribute ::= Name S? Eq S? + * ( '"<%= RTAttributeValueDouble + * | '"' AttributeValueDouble + * | "'<%= RTAttributeValueSingle + * | "'" AttributeValueSingle + * } + * Note: JSP and XML spec does not allow while spaces around Eq. It is + * added to be backward compatible with Tomcat, and with other xml parsers. + */ + private boolean parseAttribute(AttributesImpl attrs) throws JasperException { + String name = parseName(); + if (name == null) + return false; + + 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"); + + String watchString = ""; + if (reader.matches("<%=")) + watchString = "%>"; + watchString = watchString + quote; + + String attr = parseAttributeValue(watchString); + attrs.addAttribute("", name, name, "CDATA", attr); + 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; + } + + /** + * AttributeValueDouble ::= (QuotedChar - '"')* + * ('"' | <TRANSLATION_ERROR>) + * RTAttributeValueDouble ::= ((QuotedChar - '"')* - ((QuotedChar-'"')'%>"') + * ('%>"' | TRANSLATION_ERROR) + */ + private String parseAttributeValue(String watch) throws JasperException { + Mark start = reader.mark(); + Mark stop = reader.skipUntil(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; + + // putback delimiter '<%=' and '%>', since they are needed if the + // attribute does not allow RTexpression. + return "<%=" + ret + "%>"; + } + + /** + * QuotedChar ::= ''' + * | '"' + * | '\\' + * | '\"' + * | "\'" + * | '\>' + * | Char + */ + private String parseQuoted(char[] tx) { + StringBuffer buf = new StringBuffer(); + int size = tx.length; + int i = 0; + while (i < size) { + char ch = tx[i]; + if (ch == '&') { + if (i+5 < size && tx[i+1] == 'a' && tx[i+2] == 'p' && + tx[i+3] == 'o' && tx[i+4] == 's' && tx[i+5] == ';') { + buf.append('\''); + i += 6; + } else if (i+5 < size && tx[i+1] == 'q' && tx[i+2] == 'u' && + tx[i+3] == 'o' && tx[i+4] == 't' && tx[i+5] == ';') { + buf.append('"'); + i += 6; + } else { + buf.append(ch); + ++i; + } + } else if (ch == '\\' && i+1 < size) { + ch = tx[i+1]; + if (ch == '\\' || ch == '\"' || ch == '\'' || ch == '>') { + buf.append(ch); + i += 2; + } else { + buf.append('\\'); + ++i; + } + } else { + buf.append(ch); + ++i; + } + } + return buf.toString(); + } + + private char[] parseScriptText(char[] tx) { + CharArrayWriter cw = new CharArrayWriter(); + int size = tx.length; + int i = 0; + while (i < size) { + char ch = tx[i]; + if (i+2 < size && ch == '%' && tx[i+1] == '\\' && tx[i+2] == '>') { + cw.write('%'); + cw.write('>'); + i += 3; + } else { + cw.write(ch); + ++i; + } + } + cw.close(); + return cw.toCharArray(); + } + /* * Invokes parserController to parse the included page */ @@ -147,7 +303,7 @@ * PageDirective ::= ( S Attribute)* */ private void parsePageDirective(Node parent) throws JasperException { - Attributes attrs = reader.parseTagAttributes(); + Attributes attrs = parseAttributes(); Node.PageDirective n = new Node.PageDirective(attrs, start, parent); /* @@ -167,7 +323,7 @@ * IncludeDirective ::= ( S Attribute)* */ private void parseIncludeDirective(Node parent) throws JasperException { - Attributes attrs = reader.parseTagAttributes(); + Attributes attrs = parseAttributes(); // Included file expanded here Node includeNode = new Node.IncludeDirective(attrs, start, parent); @@ -179,7 +335,7 @@ * Directive ::= ( S Attribute)* */ private void parseTaglibDirective(Node parent) throws JasperException { - Attributes attrs = reader.parseTagAttributes(); + Attributes attrs = parseAttributes(); String uri = attrs.getValue("uri"); String prefix = attrs.getValue("prefix"); if (uri != null || prefix != null) { @@ -246,7 +402,8 @@ err.jspError(start, "jsp.error.unterminated", "<%!"); } - new Node.Declaration(reader.getScriptingText(start, stop), start, parent); + new Node.Declaration(parseScriptText(reader.getText(start, stop)), + start, parent); } /* @@ -259,7 +416,8 @@ err.jspError(start, "jsp.error.unterminated", "<%="); } - new Node.Expression(reader.getScriptingText(start, stop), start, parent); + new Node.Expression(parseScriptText(reader.getText(start, stop)), + start, parent); } /* @@ -272,7 +430,8 @@ err.jspError(start, "jsp.error.unterminated", "<%"); } - new Node.Scriptlet(reader.getScriptingText(start, stop), start, parent); + new Node.Scriptlet(parseScriptText(reader.getText(start, stop)), + start, parent); } /** @@ -283,7 +442,7 @@ if (!reader.matches("<jsp:param")) { err.jspError(reader.mark(), "jsp.error.paramexpectedonly"); } - Attributes attrs = reader.parseTagAttributes(); + Attributes attrs = parseAttributes(); reader.skipSpaces(); if (!reader.matches("/>")) { @@ -318,7 +477,7 @@ * ) */ private void parseInclude(Node parent) throws JasperException { - Attributes attrs = reader.parseTagAttributes(); + Attributes attrs = parseAttributes(); reader.skipSpaces(); if (reader.matches("/>")) { @@ -345,7 +504,7 @@ */ private void parseForward(Node parent) throws JasperException { - Attributes attrs = reader.parseTagAttributes(); + Attributes attrs = parseAttributes(); reader.skipSpaces(); if (reader.matches("/>")) { @@ -368,7 +527,7 @@ * GetProperty ::= (S? Attribute)* S? '/>/ */ private void parseGetProperty(Node parent) throws JasperException { - Attributes attrs = reader.parseTagAttributes(); + Attributes attrs = parseAttributes(); reader.skipSpaces(); if (!reader.matches("/>")) { @@ -383,7 +542,7 @@ * SetProperty ::= (S Attribute)* S? '/>' */ private void parseSetProperty(Node parent) throws JasperException { - Attributes attrs = reader.parseTagAttributes(); + Attributes attrs = parseAttributes(); reader.skipSpaces(); if (!reader.matches("/>")) { @@ -399,7 +558,7 @@ * ('/>' | ( '>' Body '</jsp:useBean' S? '>' )) */ private void parseUseBean(Node parent) throws JasperException { - Attributes attrs = reader.parseTagAttributes(); + Attributes attrs = parseAttributes(); reader.skipSpaces(); if (reader.matches("/>")) { @@ -455,7 +614,7 @@ * ('<jsp:fallback' JspFallack S?)? */ private void parsePlugin(Node parent) throws JasperException { - Attributes attrs = reader.parseTagAttributes(); + Attributes attrs = parseAttributes(); reader.skipSpaces(); if (!reader.matches(">")) { @@ -541,7 +700,7 @@ // EmptyElemTag ::= '<' Name ( #S Attribute )* S? '/>' // or Stag ::= '<' Name ( #S Attribute)* S? '>' - Attributes attrs = reader.parseTagAttributes(); + Attributes attrs = parseAttributes(); reader.skipSpaces(); if (reader.matches("/>")) { @@ -657,5 +816,7 @@ } err.jspError(start, "jsp.error.unterminated", "<"+tag+">"); } + + }
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>