parser.java
来自「精通tomcat书籍原代码,希望大家共同学习」· Java 代码 · 共 1,859 行 · 第 1/5 页
JAVA
1,859 行
return result;
}
/*
* Params ::= `>' S?
* ( ( `<jsp:body>'
* ( ( S? Param+ S? `</jsp:body>' )
* | <TRANSLATION_ERROR>
* )
* )
* | Param+
* )
* '</jsp:params>'
*/
private void parseJspParams(Node parent) throws JasperException {
Node jspParamsNode = new Node.ParamsAction(start, parent);
parseOptionalBody(jspParamsNode, "jsp:params",
JAVAX_BODY_CONTENT_PARAM );
}
/*
* Fallback ::= '/>'
* | ( `>' S? `<jsp:body>'
* ( ( S?
* ( Char* - ( Char* `</jsp:body>' ) )
* `</jsp:body>' S?
* )
* | <TRANSLATION_ERROR>
* )
* `</jsp:fallback>'
* )
* | ( '>'
* ( Char* - ( Char* '</jsp:fallback>' ) )
* '</jsp:fallback>'
* )
*/
private void parseFallBack(Node parent) throws JasperException {
Node fallBackNode = new Node.FallBackAction(start, parent);
parseOptionalBody(fallBackNode, "jsp:fallback",
JAVAX_BODY_CONTENT_TEMPLATE_TEXT);
}
/*
* For Plugin:
* StdActionContent ::= Attributes PluginBody
*
* PluginBody ::= EmptyBody
* | ( '>' S? ( '<jsp:attribute' NamedAttributes )?
* '<jsp:body'
* ( JspBodyPluginTags | <TRANSLATION_ERROR> )
* S? ETag
* )
* | ( '>' S? PluginTags ETag )
*
* EmptyBody ::= '/>'
* | ( '>' ETag )
* | ( '>' S? '<jsp:attribute' NamedAttributes ETag )
*
*/
private void parsePlugin(Node parent) throws JasperException {
Attributes attrs = parseAttributes();
reader.skipSpaces();
Node pluginNode = new Node.PlugIn(attrs, start, parent);
parseOptionalBody( pluginNode, "jsp:plugin",
JAVAX_BODY_CONTENT_PLUGIN );
}
/*
* PluginTags ::= ( '<jsp:params' Params S? )?
* ( '<jsp:fallback' Fallback? S? )?
*/
private void parsePluginTags( Node parent ) throws JasperException {
reader.skipSpaces();
if( reader.matches( "<jsp:params" ) ) {
parseJspParams( parent );
reader.skipSpaces();
}
if( reader.matches( "<jsp:fallback" ) ) {
parseFallBack( parent );
reader.skipSpaces();
}
}
/*
* StandardAction ::= 'include' StdActionContent
* | 'forward' StdActionContent
* | 'invoke' StdActionContent
* | 'doBody' StdActionContent
* | 'getProperty' StdActionContent
* | 'setProperty' StdActionContent
* | 'useBean' StdActionContent
* | 'plugin' StdActionContent
* | 'element' StdActionContent
*/
private void parseStandardAction(Node parent) throws JasperException {
Mark start = reader.mark();
if (reader.matches(INCLUDE_ACTION)) {
parseInclude(parent);
} else if (reader.matches(FORWARD_ACTION)) {
parseForward(parent);
} else if (reader.matches(INVOKE_ACTION)) {
if (!isTagFile) {
err.jspError(reader.mark(), "jsp.error.action.isnottagfile",
"<jsp:invoke");
}
parseInvoke(parent);
} else if (reader.matches(DOBODY_ACTION)) {
if (!isTagFile) {
err.jspError(reader.mark(), "jsp.error.action.isnottagfile",
"<jsp:doBody");
}
parseDoBody(parent);
} else if (reader.matches(GET_PROPERTY_ACTION)) {
parseGetProperty(parent);
} else if (reader.matches(SET_PROPERTY_ACTION)) {
parseSetProperty(parent);
} else if (reader.matches(USE_BEAN_ACTION)) {
parseUseBean(parent);
} else if (reader.matches(PLUGIN_ACTION)) {
parsePlugin(parent);
} else if (reader.matches(ELEMENT_ACTION)) {
parseElement(parent);
} else if (reader.matches(ATTRIBUTE_ACTION)) {
err.jspError(start, "jsp.error.namedAttribute.invalidUse");
} else if (reader.matches(BODY_ACTION)) {
err.jspError(start, "jsp.error.jspbody.invalidUse");
} else if (reader.matches(FALLBACK_ACTION)) {
err.jspError(start, "jsp.error.fallback.invalidUse");
} else if (reader.matches(PARAMS_ACTION)) {
err.jspError(start, "jsp.error.params.invalidUse");
} else if (reader.matches(PARAM_ACTION)) {
err.jspError(start, "jsp.error.param.invalidUse");
} else if (reader.matches(OUTPUT_ACTION)) {
err.jspError(start, "jsp.error.jspoutput.invalidUse");
} else {
err.jspError(start, "jsp.error.badStandardAction");
}
}
/*
* # '<' CustomAction CustomActionBody
*
* CustomAction ::= TagPrefix ':' CustomActionName
*
* TagPrefix ::= Name
*
* CustomActionName ::= Name
*
* CustomActionBody ::= ( Attributes CustomActionEnd )
* | <TRANSLATION_ERROR>
*
* Attributes ::= ( S Attribute )* S?
*
* CustomActionEnd ::= CustomActionTagDependent
* | CustomActionJSPContent
* | CustomActionScriptlessContent
*
* CustomActionTagDependent ::= TagDependentOptionalBody
*
* CustomActionJSPContent ::= OptionalBody
*
* CustomActionScriptlessContent ::= ScriptlessOptionalBody
*/
private boolean parseCustomTag(Node parent) throws JasperException {
if (reader.peekChar() != '<') {
return false;
}
// Parse 'CustomAction' production (tag prefix and custom action name)
reader.nextChar(); // skip '<'
String tagName = reader.parseToken(false);
int i = tagName.indexOf(':');
if (i == -1) {
reader.reset(start);
return false;
}
String prefix = tagName.substring(0, i);
String shortTagName = tagName.substring(i+1);
// Check if this is a user-defined tag.
String uri = pageInfo.getURI(prefix);
if (uri == null) {
reader.reset(start);
// Remember the prefix for later error checking
pageInfo.putNonCustomTagPrefix(prefix, reader.mark());
return false;
}
TagLibraryInfo tagLibInfo = pageInfo.getTaglib(uri);
TagInfo tagInfo = tagLibInfo.getTag(shortTagName);
TagFileInfo tagFileInfo = tagLibInfo.getTagFile(shortTagName);
if (tagInfo == null && tagFileInfo == null) {
err.jspError(start, "jsp.error.bad_tag", shortTagName, prefix);
}
Class tagHandlerClass = null;
if (tagInfo != null) {
// Must be a classic tag, load it here.
// tag files will be loaded later, in TagFileProcessor
String handlerClassName = tagInfo.getTagClassName();
try {
tagHandlerClass = ctxt.getClassLoader().loadClass(handlerClassName);
} catch (Exception e) {
err.jspError(start, "jsp.error.loadclass.taghandler",
handlerClassName, tagName);
}
}
// Parse 'CustomActionBody' production:
// At this point we are committed - if anything fails, we produce
// a translation error.
// Parse 'Attributes' production:
Attributes attrs = parseAttributes();
reader.skipSpaces();
// Parse 'CustomActionEnd' production:
if (reader.matches("/>")) {
if (tagInfo != null) {
new Node.CustomTag(tagName, prefix, shortTagName, uri, attrs,
start, parent, tagInfo, tagHandlerClass);
} else {
new Node.CustomTag(tagName, prefix, shortTagName, uri, attrs,
start, parent, tagFileInfo);
}
return true;
}
// Now we parse one of 'CustomActionTagDependent',
// 'CustomActionJSPContent', or 'CustomActionScriptlessContent'.
// depending on body-content in TLD.
// Looking for a body, it still can be empty; but if there is a
// a tag body, its syntax would be dependent on the type of
// body content declared in the TLD.
String bc;
if (tagInfo != null) {
bc = tagInfo.getBodyContent();
} else {
bc = tagFileInfo.getTagInfo().getBodyContent();
}
Node tagNode = null;
if (tagInfo != null) {
tagNode = new Node.CustomTag(tagName, prefix, shortTagName, uri,
attrs, start, parent, tagInfo,
tagHandlerClass);
} else {
tagNode = new Node.CustomTag(tagName, prefix, shortTagName, uri,
attrs, start, parent, tagFileInfo);
}
parseOptionalBody( tagNode, tagName, bc );
return true;
}
/*
* Parse for a template text string until '<' or "${" is encountered,
* recognizing escape sequences "\%" and "\$".
*/
private void parseTemplateText(Node parent) throws JasperException {
if (!reader.hasMoreInput())
return;
CharArrayWriter ttext = new CharArrayWriter();
// Output the first character
int ch = reader.nextChar();
if (ch == '\\') {
reader.pushChar();
} else {
ttext.write(ch);
}
while (reader.hasMoreInput()) {
ch = reader.nextChar();
if (ch == '<') {
reader.pushChar();
break;
}
else if( ch == '$' ) {
if (!reader.hasMoreInput()) {
ttext.write('$');
break;
}
ch = reader.nextChar();
if (ch == '{') {
reader.pushChar();
reader.pushChar();
break;
}
ttext.write('$');
reader.pushChar();
continue;
}
else if (ch == '\\') {
if (!reader.hasMoreInput()) {
ttext.write('\\');
break;
}
char next = (char)reader.peekChar();
// Looking for \% or \$
// TODO: only recognize \$ if isELIgnored is false, but since
// it can be set in a page directive, it cannot be determined
// here. Argh!
if (next == '%' || next == '$') {
ch = reader.nextChar();
}
}
ttext.write(ch);
}
new Node.TemplateText(ttext.toString(), start, parent);
}
/*
* XMLTemplateText ::= ( S? '/>' )
* | ( S? '>'
* ( ( Char* - ( Char* ( '<' | '${' ) ) )
* ( '${' ELExpressionBody )?
* CDSect?
* )* ETag
* )
* | <TRANSLATION_ERROR>
*/
private void parseXMLTemplateText(Node parent) throws JasperException {
reader.skipSpaces();
if( !reader.matches( "/>" ) ) {
if( !reader.matches( ">" ) ) {
err.jspError(start, "jsp.error.unterminated",
"<jsp:text>" );
}
CharArrayWriter ttext = new CharArrayWriter();
while (reader.hasMoreInput()) {
int ch = reader.nextChar();
if( ch == '<' ) {
// Check for <![CDATA[
if (!reader.matches("![CDATA[")) {
break;
}
start = reader.mark();
Mark stop = reader.skipUntil("]]>");
if (stop == null) {
err.jspError(start, "jsp.error.unterminated", "CDATA");
}
String text = reader.getText(start, stop);
ttext.write(text, 0, text.length());
}
else if( ch == '\\') {
if (!reader.hasMoreInput()) {
ttext.write('\\');
break;
}
ch = reader.nextChar();
if (ch != '$' ) {
ttext.write('\\');
}
ttext.write(ch);
}
else if( ch == '$' ) {
if (!reader.hasMoreInput()) {
ttext.write('$');
break;
}
ch = reader.nextChar();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?