📄 jspdocumentparser.java
字号:
localName.equals(ATTRIBUTE_ACTION)) {
current =
parseStandardAction(
qName,
localName,
nonTaglibAttrs,
nonTaglibXmlnsAttrs,
taglibAttrs,
startMark,
current);
return;
}
if (tagDependentPending) {
tagDependentPending = false;
tagDependentNesting++;
}
if (tagDependentNesting > 0) {
node =
new Node.UninterpretedTag(
qName,
localName,
nonTaglibAttrs,
nonTaglibXmlnsAttrs,
taglibAttrs,
startMark,
current);
} else if (JSP_URI.equals(uri)) {
node =
parseStandardAction(
qName,
localName,
nonTaglibAttrs,
nonTaglibXmlnsAttrs,
taglibAttrs,
startMark,
current);
} else {
node =
parseCustomAction(
qName,
localName,
uri,
nonTaglibAttrs,
nonTaglibXmlnsAttrs,
taglibAttrs,
startMark,
current);
if (node == null) {
node =
new Node.UninterpretedTag(
qName,
localName,
nonTaglibAttrs,
nonTaglibXmlnsAttrs,
taglibAttrs,
startMark,
current);
} else {
// custom action
String bodyType = getBodyType((Node.CustomTag) node);
if (scriptlessBodyNode == null
&& bodyType.equalsIgnoreCase(TagInfo.BODY_CONTENT_SCRIPTLESS)) {
scriptlessBodyNode = node;
}
else if (TagInfo.BODY_CONTENT_TAG_DEPENDENT.equalsIgnoreCase(bodyType)) {
tagDependentPending = true;
}
}
}
current = node;
}
/*
* Receives notification of character data inside an element.
*
* The SAX does not call this method with all of the template text, but may
* invoke this method with chunks of it. This is a problem when we try
* to determine if the text contains only whitespaces, or when we are
* looking for an EL expression string. Therefore it is necessary to
* buffer and concatenate the chunks and process the concatenated text
* later (at beginTag and endTag)
*
* @param buf The characters
* @param offset The start position in the character array
* @param len The number of characters to use from the character array
*
* @throws SAXException
*/
public void characters(char[] buf, int offset, int len) {
if (charBuffer == null) {
charBuffer = new StringBuffer();
}
charBuffer.append(buf, offset, len);
}
private void processChars() throws SAXException {
if (charBuffer == null || directivesOnly) {
return;
}
/*
* JSP.6.1.1: All textual nodes that have only white space are to be
* dropped from the document, except for nodes in a jsp:text element,
* and any leading and trailing white-space-only textual nodes in a
* jsp:attribute whose 'trim' attribute is set to FALSE, which are to
* be kept verbatim.
* JSP.6.2.3 defines white space characters.
*/
boolean isAllSpace = true;
if (!(current instanceof Node.JspText)
&& !(current instanceof Node.NamedAttribute)) {
for (int i = 0; i < charBuffer.length(); i++) {
if (!(charBuffer.charAt(i) == ' '
|| charBuffer.charAt(i) == '\n'
|| charBuffer.charAt(i) == '\r'
|| charBuffer.charAt(i) == '\t')) {
isAllSpace = false;
break;
}
}
}
if (!isAllSpace && tagDependentPending) {
tagDependentPending = false;
tagDependentNesting++;
}
if (tagDependentNesting > 0) {
if (charBuffer.length() > 0) {
new Node.TemplateText(charBuffer.toString(), startMark, current);
}
startMark = new Mark(ctxt, path, locator.getLineNumber(),
locator.getColumnNumber());
charBuffer = null;
return;
}
if ((current instanceof Node.JspText)
|| (current instanceof Node.NamedAttribute)
|| !isAllSpace) {
int line = startMark.getLineNumber();
int column = startMark.getColumnNumber();
CharArrayWriter ttext = new CharArrayWriter();
int lastCh = 0, elType = 0;
for (int i = 0; i < charBuffer.length(); i++) {
int ch = charBuffer.charAt(i);
if (ch == '\n') {
column = 1;
line++;
} else {
column++;
}
if ((lastCh == '$' || lastCh == '#') && ch == '{') {
elType = lastCh;
if (ttext.size() > 0) {
new Node.TemplateText(
ttext.toString(),
startMark,
current);
ttext = new CharArrayWriter();
//We subtract two from the column number to
//account for the '[$,#]{' that we've already parsed
startMark = new Mark(ctxt, path, line, column - 2);
}
// following "${" || "#{" to first unquoted "}"
i++;
boolean singleQ = false;
boolean doubleQ = false;
lastCh = 0;
for (;; i++) {
if (i >= charBuffer.length()) {
throw new SAXParseException(
Localizer.getMessage(
"jsp.error.unterminated",
(char) elType + "{"),
locator);
}
ch = charBuffer.charAt(i);
if (ch == '\n') {
column = 1;
line++;
} else {
column++;
}
if (lastCh == '\\' && (singleQ || doubleQ)) {
ttext.write(ch);
lastCh = 0;
continue;
}
if (ch == '}') {
new Node.ELExpression((char) elType,
ttext.toString(),
startMark,
current);
ttext = new CharArrayWriter();
startMark = new Mark(ctxt, path, line, column);
break;
}
if (ch == '"')
doubleQ = !doubleQ;
else if (ch == '\'')
singleQ = !singleQ;
ttext.write(ch);
lastCh = ch;
}
} else if (lastCh == '\\' && (ch == '$' || ch == '#')) {
ttext.write(ch);
ch = 0; // Not start of EL anymore
} else {
if (lastCh == '$' || lastCh == '#' || lastCh == '\\') {
ttext.write(lastCh);
}
if (ch != '$' && ch != '#' && ch != '\\') {
ttext.write(ch);
}
}
lastCh = ch;
}
if (lastCh == '$' || lastCh == '#' || lastCh == '\\') {
ttext.write(lastCh);
}
if (ttext.size() > 0) {
new Node.TemplateText(ttext.toString(), startMark, current);
}
}
startMark = new Mark(ctxt, path, locator.getLineNumber(),
locator.getColumnNumber());
charBuffer = null;
}
/*
* Receives notification of the end of an element.
*/
public void endElement(String uri, String localName, String qName)
throws SAXException {
processChars();
if (directivesOnly &&
!(JSP_URI.equals(uri) && localName.startsWith(DIRECTIVE_ACTION))) {
return;
}
if (current instanceof Node.NamedAttribute) {
boolean isTrim = ((Node.NamedAttribute)current).isTrim();
Node.Nodes subElems = ((Node.NamedAttribute)current).getBody();
for (int i = 0; subElems != null && i < subElems.size(); i++) {
Node subElem = subElems.getNode(i);
if (!(subElem instanceof Node.TemplateText)) {
continue;
}
// Ignore any whitespace (including spaces, carriage returns,
// line feeds, and tabs, that appear at the beginning and at
// the end of the body of the <jsp:attribute> action, if the
// action's 'trim' attribute is set to TRUE (default).
// In addition, any textual nodes in the <jsp:attribute> that
// have only white space are dropped from the document, with
// the exception of leading and trailing white-space-only
// textual nodes in a <jsp:attribute> whose 'trim' attribute
// is set to FALSE, which must be kept verbatim.
if (i == 0) {
if (isTrim) {
((Node.TemplateText)subElem).ltrim();
}
} else if (i == subElems.size() - 1) {
if (isTrim) {
((Node.TemplateText)subElem).rtrim();
}
} else {
if (((Node.TemplateText)subElem).isAllSpace()) {
subElems.remove(subElem);
}
}
}
} else if (current instanceof Node.ScriptingElement) {
checkScriptingBody((Node.ScriptingElement)current);
}
if ( isTagDependent(current)) {
tagDependentNesting--;
}
if (scriptlessBodyNode != null
&& current.equals(scriptlessBodyNode)) {
scriptlessBodyNode = null;
}
if (current.getParent() != null) {
current = current.getParent();
}
}
/*
* Receives the document locator.
*
* @param locator the document locator
*/
public void setDocumentLocator(Locator locator) {
this.locator = locator;
}
/*
* See org.xml.sax.ext.LexicalHandler.
*/
public void comment(char[] buf, int offset, int len) throws SAXException {
processChars(); // Flush char buffer and remove white spaces
// ignore comments in the DTD
if (!inDTD) {
startMark =
new Mark(
ctxt,
path,
locator.getLineNumber(),
locator.getColumnNumber());
new Node.Comment(new String(buf, offset, len), startMark, current);
}
}
/*
* See org.xml.sax.ext.LexicalHandler.
*/
public void startCDATA() throws SAXException {
processChars(); // Flush char buffer and remove white spaces
startMark = new Mark(ctxt, path, locator.getLineNumber(),
locator.getColumnNumber());
}
/*
* See org.xml.sax.ext.LexicalHandler.
*/
public void endCDATA() throws SAXException {
processChars(); // Flush char buffer and remove white spaces
}
/*
* See org.xml.sax.ext.LexicalHandler.
*/
public void startEntity(String name) throws SAXException {
// do nothing
}
/*
* See org.xml.sax.ext.LexicalHandler.
*/
public void endEntity(String name) throws SAXException {
// do nothing
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -