parser.java

来自「精通tomcat书籍原代码,希望大家共同学习」· Java 代码 · 共 1,859 行 · 第 1/5 页

JAVA
1,859
字号
                    if (ch != '{') {
                        ttext.write('$');
                        reader.pushChar();
                        continue;
                    }
                    // Create a template text node
                    new Node.TemplateText( ttext.toString(), start, parent);

                    // Mark and parse the EL expression and create its node:
                    start = reader.mark();
                    parseELExpression(parent);

                    start = reader.mark();
                    ttext = new CharArrayWriter();
                }
                else {
                    ttext.write( ch );
                }
            }

            new Node.TemplateText( ttext.toString(), start, parent );

	    if (! reader.hasMoreInput()) {
                err.jspError( start, "jsp.error.unterminated",
                    "<jsp:text>" );
	    } else if( !reader.matchesETagWithoutLessThan( "jsp:text" ) ) {
                err.jspError( start, "jsp.error.jsptext.badcontent");
            }
        }
    }

    /*
     * AllBody ::=       ( '<%--'              JSPCommentBody     )
     *                 | ( '<%@'               DirectiveBody      )
     *                 | ( '<jsp:directive.'   XMLDirectiveBody   )
     *                 | ( '<%!'               DeclarationBody    )
     *                 | ( '<jsp:declaration'  XMLDeclarationBody )
     *                 | ( '<%='               ExpressionBody     )
     *                 | ( '<jsp:expression'   XMLExpressionBody  )
     *                 | ( '${'                ELExpressionBody   )
     *                 | ( '<%'                ScriptletBody      )
     *                 | ( '<jsp:scriptlet'    XMLScriptletBody   )
     *                 | ( '<jsp:text'         XMLTemplateText    )
     *                 | ( '<jsp:'             StandardAction     )
     *                 | ( '<'                 CustomAction
     *                                         CustomActionBody   )
     *	               | TemplateText
     */
    private void parseElements(Node parent) 
        throws JasperException 
    {
        if( scriptlessCount > 0 ) {
            // vc: ScriptlessBody
            // We must follow the ScriptlessBody production if one of
            // our parents is ScriptlessBody.
            parseElementsScriptless( parent );
            return;
        }
        
	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("<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("<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)) {
            checkUnbalancedEndTag();
            parseTemplateText(parent);
	}
    }

    /*
     * ScriptlessBody ::=  ( '<%--'              JSPCommentBody      )
     *                   | ( '<%@'               DirectiveBody       )
     *                   | ( '<jsp:directive.'   XMLDirectiveBody    )
     *                   | ( '<%!'               <TRANSLATION_ERROR> )
     *                   | ( '<jsp:declaration'  <TRANSLATION_ERROR> )
     *                   | ( '<%='               <TRANSLATION_ERROR> )
     *                   | ( '<jsp:expression'   <TRANSLATION_ERROR> )
     *                   | ( '<%'                <TRANSLATION_ERROR> )
     *                   | ( '<jsp:scriptlet'    <TRANSLATION_ERROR> )
     *                   | ( '<jsp:text'         XMLTemplateText     )
     *                   | ( '${'                ELExpressionBody    )
     *                   | ( '<jsp:'             StandardAction      )
     *                   | ( '<'                 CustomAction
     *                                           CustomActionBody    )
     *                   | TemplateText
     */
    private void parseElementsScriptless(Node parent) 
        throws JasperException 
    {
        // Keep track of how many scriptless nodes we've encountered
        // 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);
        } else if (reader.matches("<jsp:directive.")) {
            parseXMLDirective(parent);
	} 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("<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("<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)) {
            checkUnbalancedEndTag();
            parseTemplateText(parent);
	}
        
        scriptlessCount--;
    }
    
    /*
     * TemplateTextBody ::=   ( '<%--'              JSPCommentBody      )
     *                      | ( '<%@'               DirectiveBody       )
     *                      | ( '<jsp:directive.'   XMLDirectiveBody    )
     *                      | ( '<%!'               <TRANSLATION_ERROR> )
     *                      | ( '<jsp:declaration'  <TRANSLATION_ERROR> )
     *                      | ( '<%='               <TRANSLATION_ERROR> )
     *                      | ( '<jsp:expression'   <TRANSLATION_ERROR> )
     *                      | ( '<%'                <TRANSLATION_ERROR> )
     *                      | ( '<jsp:scriptlet'    <TRANSLATION_ERROR> )
     *                      | ( '<jsp:text'         <TRANSLATION_ERROR> )
     *                      | ( '${'                <TRANSLATION_ERROR> )
     *                      | ( '<jsp:'             <TRANSLATION_ERROR> )
     *                      | TemplateText
     */
    private void parseElementsTemplateText(Node parent)
        throws JasperException
    {
        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.not.in.template",
		"Declarations" );
        } else if (reader.matches("<jsp:declaration")) {
            err.jspError( reader.mark(), "jsp.error.not.in.template",
		"Declarations" );
        } else if (reader.matches("<%=")) {
            err.jspError( reader.mark(), "jsp.error.not.in.template",
		"Expressions" );
        } else if (reader.matches("<jsp:expression")) {
            err.jspError( reader.mark(), "jsp.error.not.in.template",
		"Expressions" );
        } else if (reader.matches("<%")) {
            err.jspError( reader.mark(), "jsp.error.not.in.template",
		"Scriptlets" );
        } else if (reader.matches("<jsp:scriptlet")) {
            err.jspError( reader.mark(), "jsp.error.not.in.template",
		"Scriptlets" );
        } else if (reader.matches("<jsp:text")) {
            err.jspError( reader.mark(), "jsp.error.not.in.template",
		"&lt;jsp:text" );
        } else if (reader.matches("${")) {
            err.jspError( reader.mark(), "jsp.error.not.in.template",
		"Expression language" );
        } else if (reader.matches("<jsp:")) {
            err.jspError( reader.mark(), "jsp.error.not.in.template",
		"Standard actions" );
	} else if (parseCustomTag(parent)) {
            err.jspError( reader.mark(), "jsp.error.not.in.template",
		"Custom actions" );
	} else {
            checkUnbalancedEndTag();
            parseTemplateText(parent);
	}
    }

    /*
     * Flag as error if an unbalanced end tag appears by itself.
     */
    private void checkUnbalancedEndTag() throws JasperException {

        if (!reader.matches("</")) {
            return;
        }

        // Check for unbalanced standard actions
        if (reader.matches("jsp:")) {
            err.jspError(start, "jsp.error.unbalanced.endtag", "jsp:");
        }

        // Check for unbalanced custom actions
        String tagName = reader.parseToken(false);
        int i = tagName.indexOf(':');
        if (i == -1 || pageInfo.getURI(tagName.substring(0, i)) == null) {
            reader.reset(start);
            return;
        }

        err.jspError(start, "jsp.error.unbalanced.endtag", tagName);
    }

    /**
     * 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);
    }

    /*
     * Parses jsp:body action.
     */
    private void parseJspBody(Node parent, String bodyType) 
        throws JasperException 
    {
        Mark start = reader.mark();
	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 );
	}
    }

    /*
     * Parse the body as JSP content.
     * @param tag The name of the tag whose end tag would terminate the body
     * @param bodyType One of the TagInfo body types
     */
    private void parseBody(Node parent, String tag, String bodyType) 
        throws JasperException 
    {
        if( bodyType.equalsIgnoreCase( TagInfo.BODY_CONTENT_TAG_DEPENDENT ) ) {
            parseTagDependentBody( parent, tag );
        }
        else if( bodyType.equalsIgnoreCase( TagInfo.BODY_CONTENT_EMPTY ) ) {
            if( !reader.matchesETag( tag ) ) {
		err.jspError(start, "jasper.error.emptybodycontent.nonempty",
			     tag);
            }
        }
        else if( bodyType == JAVAX_BODY_CONTENT_PLUGIN ) {
            // (note the == since we won't recognize JAVAX_* 
            // from outside this module).
            parsePluginTags(parent);
            if( !reader.matchesETag( tag ) ) {
                err.jspError( reader.mark(), "jsp.error.unterminated",
                    "&lt;" + tag  );
            }
        }
        else if( bodyType.equalsIgnoreCase( TagInfo.BODY_CONTENT_JSP ) ||
            bodyType.equalsIgnoreCase( TagInfo.BODY_CONTENT_SCRIPTLESS ) ||
            (bodyType == JAVAX_BODY_CONTENT_PARAM) ||
            (bodyType == JAVAX_BODY_CONTENT_TEMPLATE_TEXT) )
        {
            while (reader.hasMoreInput()) {
                if (reader.matchesETag(tag)) {
                    return;
                }
                
                // Check for nested jsp:body or jsp:attribute
                if (tag.equals("jsp:body") || tag.equals("jsp:attribute")) {
                    if (reader.matches("<jsp:attribute")) {
                        err.jspError(reader.mark(), "jsp.error.nested.jspattribute");
                    }
                    else if (reader.matches("<jsp:body")) {
                        err.jspError(reader.mark(), "jsp.error.nested.jspbody");
                    }
                }

                if( bodyType.equalsIgnoreCase( TagInfo.BODY_CONTENT_JSP ) ) {
                    parseElements( parent );
                }
                else if( bodyType.equalsIgnoreCase( 
                    TagInfo.BODY_CONTENT_SCRIPTLESS ) ) 
                {
                    parseElementsScriptless( parent );
                }
                else if( bodyType == JAVAX_BODY_CONTENT_PARAM ) {
                    // (note the == since we won't recognize JAVAX_* 
                    // from outside this module).
                    reader.skipSpaces();
                    parseParam( 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");
        }
    }

    /*
     * Parses named attributes.
     */
    private void parseNamedAttributes(Node parent) throws JasperException {
        do {
            Mark start = reader.mark();
            Attributes attrs = parseAttributes();
            Node.NamedAttribute namedAttributeNode =
                new Node.NamedAttribute( attrs, start, parent );

            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 subElems = namedAttributeNode.getBody();
		    if (subElems != null) {
			Node lastNode = subElems.getNode(subElems.size() - 1);
			if (lastNode instanceof Node.TemplateText) {
			    ((Node.TemplateText)lastNode).rtrim();
			}
		    }
                }
            }
            reader.skipSpaces();
        } while( reader

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?