bundles/org.apache.jasper.glassfish/src/org/apache/jasper/compiler/Parser.java
private boolean parseJspAttributeAndBody( Node parent, String tag, 
        String bodyType ) 
        throws JasperException
    {
        boolean result = false;
        
        if( reader.matchesOptionalSpacesFollowedBy( "<jsp:attribute" ) ) {
            // May be an EmptyBody, depending on whether
            // There's a "<jsp:body" before the ETag
            
            // First, parse <jsp:attribute> elements:
            parseNamedAttributes( parent );
            
            result = true;
        }
        
        if( reader.matchesOptionalSpacesFollowedBy( "<jsp:body" ) ) {
            // ActionBody
            parseJspBody( parent, bodyType );
            reader.skipSpaces();
            if( !reader.matchesETag( tag ) ) {
                err.jspError(reader.mark(), "jsp.error.unterminated", 
                    "&lt;" + tag );
            }
            
            result = true;
        }
        else if( result && !reader.matchesETag( tag ) ) {
            // If we have <jsp:attribute> but something other than
            // <jsp:body> or the end tag, translation error.
            err.jspError(reader.mark(), "jsp.error.jspbody.required", 
                "&lt;" + tag );
        }
        
        return result;
    }
private boolean parseJspAttributeAndBody( Node parent, String tag, 
        String bodyType ) 
        throws JasperException
    {
        boolean result = false;
        
        if( reader.matchesOptionalSpacesFollowedBy( "<jsp:attribute" ) ) {
            // May be an EmptyBody, depending on whether
            // There's a "<jsp:body" before the ETag
            
            // First, parse <jsp:attribute> elements:
            parseNamedAttributes( parent );
            
            result = true;
        }
        
        if( reader.matchesOptionalSpacesFollowedBy( "<jsp:body" ) ) {
            // ActionBody
            parseJspBody( parent, bodyType );
            reader.skipSpaces();
            if( !reader.matchesETag( tag ) ) {
                err.jspError(reader.mark(), "jsp.error.unterminated", 
                    "&lt;" + tag );
            }
            
            result = true;
        }
        else if( result && !reader.matchesETag( tag ) ) {
            // If we have <jsp:attribute> but something other than
            // <jsp:body> or the end tag, translation error.
            err.jspError(reader.mark(), "jsp.error.jspbody.required", 
                "&lt;" + tag );
        }
        
        return result;
    }
private boolean parseJspAttributeAndBody ( Node parent , String tag , String bodyType ) throws JasperException { boolean result = false ; if ( reader . matchesOptionalSpacesFollowedBy ( "<jsp:attribute" ) ) { // May be an EmptyBody, depending on whether // There's a "<jsp:body" before the ETag // First, parse <jsp:attribute> elements: parseNamedAttributes ( parent ) ; result = true ; } if ( reader . matchesOptionalSpacesFollowedBy ( "<jsp:body" ) ) { // ActionBody parseJspBody ( parent , bodyType ) ; reader . skipSpaces ( ) ; if ( ! reader . matchesETag ( tag ) ) { err . jspError ( reader . mark ( ) , "jsp.error.unterminated" , "&lt;" + tag ) ; } result = true ; } else if ( result && ! reader . matchesETag ( tag ) ) { // If we have <jsp:attribute> but something other than // <jsp:body> or the end tag, translation error. err . jspError ( reader . mark ( ) , "jsp.error.jspbody.required" , "&lt;" + tag ) ; } return result ; }
Attempts to parse 'JspAttributeAndBody' production.  Returns true if
it matched, or false if not.  Assumes EmptyBody is okay as well.

JspAttributeAndBody ::=
( '>' # S? ( '<jsp:attribute' NamedAttributes )?
'<jsp:body'
( JspBodyBody | <TRANSLATION_ERROR> )
S? ETag
)
Attempts to parse JspAttributeAndBody production . Returns true if it matched or false if not . Assumes EmptyBody is okay as well .