📄 parser.java
字号:
if (!reader.hasMoreInput()) {
ttext.write('\\');
break;
}
ch = reader.nextChar();
if (ch != '$' && ch != '#') {
ttext.write('\\');
}
ttext.write(ch);
} else if (ch == '$' || ch == '#') {
if (!reader.hasMoreInput()) {
ttext.write(ch);
break;
}
if (reader.nextChar() != '{') {
ttext.write(ch);
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, (char) ch);
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("#{")) {
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("#{")) {
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("#{")) {
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, at
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -