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",
"<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", "<"+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",
"<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",
"<" + 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", "<"+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",
"<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 + -
显示快捷键?