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",
  -                                   "&lt;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", 
  -                    "&lt;jsp:attribute" );
  -            }
  -            else if( !reader.matches( ">" ) ) {
  -                err.jspError(reader.mark(), "jsp.error.unterminated",
  -                    "&lt;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", 
  -                    "&lt;jsp:attribute" );
  -            }
  -            else {
  -                if( namedAttributeNode.isTrim() ) {
  +            reader.skipSpaces();
  +         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")));
  -                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]>

Reply via email to