luehe 2002/12/11 19:30:59 Modified: jasper2/src/share/org/apache/jasper/compiler Generator.java JspDocumentParser.java Node.java Parser.java Log: - Allow empty <jsp:attribute> body, and treat it as "". - In a JSP document (XML syntax), preserve any leading and trailing white-space-only textual nodes in a <jsp:attribute> whose 'trim' attribute is set to FALSE (these nodes are dropped otherwise). Revision Changes Path 1.140 +30 -25 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Generator.java Index: Generator.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Generator.java,v retrieving revision 1.139 retrieving revision 1.140 diff -u -r1.139 -r1.140 --- Generator.java 11 Dec 2002 19:40:45 -0000 1.139 +++ Generator.java 12 Dec 2002 03:30:58 -0000 1.140 @@ -2687,8 +2687,8 @@ * @return The name of the temporary variable the result is stored in. */ public String generateNamedAttributeValue( Node.NamedAttribute n ) - throws JasperException - { + throws JasperException { + String varName = n.getTemporaryVariableName(); // If the only body element for this named attribute node is @@ -2696,29 +2696,34 @@ // pushBody and popBody. Maybe we can further optimize // here by getting rid of the temporary variable, but in // reality it looks like javac does this for us. - boolean templateTextOptimization = false; Node.Nodes body = n.getBody(); - if( body.size() == 1 ) { - Node bodyElement = body.getNode( 0 ); - if( bodyElement instanceof Node.TemplateText ) { - templateTextOptimization = true; - out.printil( "String " + varName + " = " + - quote( new String( - ((Node.TemplateText)bodyElement).getText() ) ) + ";" ); - } - } + if (body != null) { + boolean templateTextOptimization = false; + if( body.size() == 1 ) { + Node bodyElement = body.getNode( 0 ); + if( bodyElement instanceof Node.TemplateText ) { + templateTextOptimization = true; + out.printil("String " + varName + " = " + + quote(new String(((Node.TemplateText)bodyElement).getText())) + + ";"); + } + } - // XXX - Another possible optimization would be for - // lone EL expressions (no need to pushBody here either). + // XXX - Another possible optimization would be for + // lone EL expressions (no need to pushBody here either). - if( !templateTextOptimization ) { - out.printil( "out = pageContext.pushBody();" ); - visitBody( n ); - out.printil( "String " + varName + " = " + - "((javax.servlet.jsp.tagext.BodyContent)" + - "out).getString();" ); - out.printil( "out = pageContext.popBody();" ); - } + if( !templateTextOptimization ) { + out.printil( "out = pageContext.pushBody();" ); + visitBody( n ); + out.printil( "String " + varName + " = " + + "((javax.servlet.jsp.tagext.BodyContent)" + + "out).getString();" ); + out.printil( "out = pageContext.popBody();" ); + } + } else { + // Empty body must be treated as "" + out.printil("String " + varName + " = \"\";"); + } return varName; } 1.33 +38 -24 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/JspDocumentParser.java Index: JspDocumentParser.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/JspDocumentParser.java,v retrieving revision 1.32 retrieving revision 1.33 diff -u -r1.32 -r1.33 --- JspDocumentParser.java 10 Dec 2002 21:33:35 -0000 1.32 +++ JspDocumentParser.java 12 Dec 2002 03:30:58 -0000 1.33 @@ -349,12 +349,15 @@ int offset, int len) throws SAXException { /* - * All textual nodes that have only white space are to be dropped from - * the document, except for nodes in a jsp:text element, which are - * kept verbatim (JSP 5.2.1). + * JSP.6.1.1: All textual nodes that have only white space are to be + * dropped from the document, except for nodes in a jsp:text element, + * and any leading and trailing white-space-only textual nodes in a + * jsp:attribute whose 'trim' attribute is set to FALSE, which are to + * be kept verbatim. */ boolean isAllSpace = true; - if (!(current instanceof Node.JspText)) { + if (!(current instanceof Node.JspText) + && !(current instanceof Node.NamedAttribute)) { for (int i=offset; i<offset+len; i++) { if (!Character.isSpace(buf[i])) { isAllSpace = false; @@ -362,7 +365,8 @@ } } } - if ((current instanceof Node.JspText) || !isAllSpace) { + if ((current instanceof Node.JspText) + || (current instanceof Node.NamedAttribute) || !isAllSpace) { Mark start = new Mark(path, locator.getLineNumber(), locator.getColumnNumber()); @@ -440,24 +444,34 @@ } if (current instanceof Node.NamedAttribute) { - Node.Nodes subelems = ((Node.NamedAttribute) current).getBody(); - if (subelems == null) { - throw new SAXParseException( - err.getString("jsp.error.empty.body.not.allowed", - "<jsp:attribute"), - locator); - } - if (((Node.NamedAttribute) current).isTrim()) { + boolean isTrim = ((Node.NamedAttribute) current).isTrim(); + Node.Nodes subElems = ((Node.NamedAttribute) current).getBody(); + for (int i=0; subElems != null && i<subElems.size(); i++) { + Node subElem = subElems.getNode(i); + if (!(subElem instanceof Node.TemplateText)) { + continue; + } // Ignore any whitespace (including spaces, carriage returns, // line feeds, and tabs, that appear at the beginning and at - // the end of the body of the <jsp:attribute> action. - Node firstNode = subelems.getNode(0); - if (firstNode instanceof Node.TemplateText) { - ((Node.TemplateText) firstNode).ltrim(); - } - Node lastNode = subelems.getNode(subelems.size() - 1); - if (lastNode instanceof Node.TemplateText) { - ((Node.TemplateText) lastNode).rtrim(); + // the end of the body of the <jsp:attribute> action, if the + // action's 'trim' attribute is set to TRUE (default). + // In addition, any textual nodes in the <jsp:attribute> that + // have only white space are dropped from the document, with + // the exception of leading and trailing white-space-only + // textual nodes in a <jsp:attribute> whose 'trim' attribute + // is set to FALSE, which must be kept verbatim. + if (i == 0) { + if (isTrim) { + ((Node.TemplateText) subElem).ltrim(); + } + } else if (i == subElems.size()-1) { + if (isTrim) { + ((Node.TemplateText) subElem).rtrim(); + } + } else { + if (((Node.TemplateText) subElem).isAllSpace()) { + subElems.remove(subElem); + } } } } else if (current instanceof Node.ScriptingElement) { 1.47 +25 -3 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Node.java Index: Node.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Node.java,v retrieving revision 1.46 retrieving revision 1.47 diff -u -r1.46 -r1.47 --- Node.java 5 Dec 2002 23:56:39 -0000 1.46 +++ Node.java 12 Dec 2002 03:30:58 -0000 1.47 @@ -1425,6 +1425,20 @@ } text = text.substring(0, index); } + + /** + * Returns true if this template text contains whitespace only. + */ + public boolean isAllSpace() { + boolean isAllSpace = true; + for (int i=0; i<text.length(); i++) { + if (!Character.isSpace(text.charAt(i))) { + isAllSpace = false; + break; + } + } + return isAllSpace; + } } /********************************************************************* @@ -1591,6 +1605,14 @@ public void add(Node n) { list.add(n); root = null; + } + + /** + * Removes the given node from the list. + * @param n The node to be removed + */ + public void remove(Node n) { + list.remove(n); } /** 1.44 +22 -37 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.43 retrieving revision 1.44 diff -u -r1.43 -r1.44 --- Parser.java 9 Dec 2002 22:17:32 -0000 1.43 +++ Parser.java 12 Dec 2002 03:30:58 -0000 1.44 @@ -1684,50 +1684,35 @@ } /* - * NamedAttributes ::= AttributeBody S? - * ( '<jsp:attribute' AttributeBody S? )* - * - * AttributeBody ::= ATTR[ !name, trim ] S? AttributeBodyRequired - * - * AttributeBodyRequired ::= '>' ( ScriptlessBody - '' ) '</jsp:attribute>' + * Parses named attributes. */ private void parseNamedAttributes(Node parent) throws JasperException { do { Mark start = reader.mark(); Attributes attrs = parseAttributes(); - reader.skipSpaces(); - Node.NamedAttribute namedAttributeNode = new Node.NamedAttribute( attrs, start, parent ); - if( reader.matches( "/>" ) ) { - // Body was empty. This is illegal, according to the grammar. - err.jspError(reader.mark(), "jsp.error.empty.body.not.allowed", - "<jsp:attribute" ); - } - else if( !reader.matches( ">" ) ) { - err.jspError(reader.mark(), "jsp.error.unterminated", - "<jsp:attribute"); - } - - if( reader.matches( "</jsp:attribute" ) ) { - // Body was empty. This is illegal, according to the grammar. - err.jspError(reader.mark(), "jsp.error.empty.body.not.allowed", - "<jsp:attribute" ); - } - else { - if( namedAttributeNode.isTrim() ) { + reader.skipSpaces(); + if (!reader.matches("/>")) { + if (!reader.matches(">")) { + err.jspError(start, "jsp.error.unterminated", + "<jsp:attribute"); + } + if (namedAttributeNode.isTrim()) { reader.skipSpaces(); } - parseBody( namedAttributeNode, "jsp:attribute", - getAttributeBodyType(parent, attrs.getValue("name"))); - if( namedAttributeNode.isTrim() ) { - Node.Nodes subelements = namedAttributeNode.getBody(); - Node lastNode = subelements.getNode( - subelements.size() - 1 ); - if( lastNode instanceof Node.TemplateText ) { - ((Node.TemplateText)lastNode).rtrim(); - } + parseBody(namedAttributeNode, "jsp:attribute", + 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(); + } + } } } reader.skipSpaces();
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>