jspparser.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 2,239 行 · 第 1/4 页
JAVA
2,239 行
case '&': if (! _isXml) addText((char) ch); else { addText((char) parseEntity()); } ch = read(); break; case '$': ch = read(); if (ch == '{' && ! isELIgnored()) ch = parseJspExpression(); else addText('$'); break; case '#': ch = read(); if (isVelocity()) { ch = parseVelocity(ch); } else if (ch != '{' || isELIgnored()) { addText('#'); } else if (isDeferredSyntaxAllowedAsLiteral()) { addText('#'); } else throw error(L.l("Deferred syntax ('#{...}') not allowed as literal.")); break; case '\\': switch (ch = read()) { case '$': if (! isELIgnored()) { addText('$'); ch = read(); } else addText('\\'); break; case '#': if (! isELIgnored()) { addText('#'); ch = read(); } else addText('\\'); break; case '\\': addText('\\'); break; default: addText('\\'); break; } break; default: addText((char) ch); ch = read(); break; } } addText(); /* XXX: end document if (! _activeNode.getNodeName().equals("jsp:root")) throw error(L.l("'</{0}>' expected at end of file. For XML, the top-level tag must have a matching closing tag.", activeNode.getNodeName())); */ } /** * JSTL-style expressions. Currently understood: * * <code><pre> * ${a * b} - any arbitrary expression * </pre></code> */ private int parseJspExpression() throws IOException, JspParseException { addText(); Path jspPath = _jspPath; String filename = _filename; int line = _line; CharBuffer cb = CharBuffer.allocate(); int ch; cb.append("${"); for (ch = read(); ch >= 0 && ch != '}'; ch = read()) cb.append((char) ch); cb.append("}"); ch = read(); String prefix = _parseState.findPrefix(JSTL_CORE_URI); if (prefix == null) { prefix = "resin-c"; /* _jspBuilder.startElement(JSP_DIRECTIVE_TAGLIB); _jspBuilder.attribute(new QName("prefix"), prefix); _jspBuilder.attribute(new QName("uri"), JSTL_CORE_URI); _jspBuilder.endAttributes(); _jspBuilder.endElement(JSP_DIRECTIVE_TAGLIB.getName()); */ _jspBuilder.addNamespace(prefix, JSTL_CORE_URI); processTaglib(prefix, JSTL_CORE_URI); } setLocation(jspPath, filename, line); _jspBuilder.startElement(JSTL_CORE_OUT); _jspBuilder.attribute(new QName("value"), cb.close()); _jspBuilder.attribute(new QName("escapeXml"), "false"); _jspBuilder.endAttributes(); _jspBuilder.endElement(JSTL_CORE_OUT.getName()); return ch; } private int parseVelocity(int ch) throws IOException, JspParseException { if (ch == '{') { return parseVelocityScriptlet(); } else if ('a' <= ch && ch <= 'z') { ch = readName(ch); String name = _tag.toString(); if (name.equals("if")) { ch = parseVelocityIf("if"); } else if (name.equals("elseif")) { addText(); setLocation(); JspNode node = _jspBuilder.getCurrentNode(); if (! "resin-c:when".equals(node.getTagName())) throw error(L.l("#elseif is missing a corresponding #if. Velocity-style #if syntax needs matching #if ... #elseif ... #else ... #end. The #if statements must also nest properly with any tags.")); _jspBuilder.endElement("resin-c:when"); ch = parseVelocityIf("elseif"); } else if (name.equals("else")) { addText(); setLocation(); _jspBuilder.endElement("resin-c:when"); setLocation(_jspPath, _filename, _lineStart); _lineStart = _line; _jspBuilder.startElement(JSTL_CORE_OTHERWISE); _jspBuilder.endAttributes(); ch = skipWhitespaceToEndOfLine(ch); } else if (name.equals("foreach")) { ch = parseVelocityForeach("resin-c:forEach"); } else if (name.equals("end")) { addText(); JspNode node = _jspBuilder.getCurrentNode(); String nodeName = null; if (node != null) nodeName = node.getTagName(); if (nodeName.equals("resin-c:when") || nodeName.equals("resin-c:otherwise")) { _jspBuilder.endElement(nodeName); _jspBuilder.endElement(JSTL_CORE_CHOOSE.getName()); } else if (nodeName.equals("resin-c:forEach")) _jspBuilder.endElement(nodeName); else { throw error(L.l("#end is missing a corresponding #if or #foreach. Velocity-style #if syntax needs matching #if ... #elseif ... #else ... #end. The #if statements must also nest properly with any tags.")); } ch = skipWhitespaceToEndOfLine(ch); } else { addText('#'); addText(name); } } else addText('#'); return ch; } /** * This syntax isn't part of velocity. * * <code><pre> * #{ int foo = 3; }# * </pre></code> */ private int parseVelocityScriptlet() throws IOException, JspParseException { addText(); setLocation(_jspPath, _filename, _line); _lineStart = _line; _jspBuilder.startElement(JSP_SCRIPTLET); _jspBuilder.endAttributes(); int ch = read(); while (ch >= 0) { if (ch == '}') { ch = read(); if (ch == '#') break; else addText('}'); } else { addText((char) ch); ch = read(); } } createText(); _jspBuilder.endElement(JSP_SCRIPTLET.getName()); ch = read(); if (ch == '\r') { ch = read(); if (ch == '\n') return read(); else return ch; } else if (ch == '\n') return read(); else return ch; } /** * parses a #foreach statement * * <pre> * #foreach ([Type] var in expr) * ... * #end * </pre> * * <pre> * #foreach ([Type] var in [min .. max]) * ... * #end * </pre> */ private int parseVelocityForeach(String eltName) throws IOException, JspParseException { int ch; for (ch = read(); XmlChar.isWhitespace(ch); ch = read()) { } if (ch != '(') throw error(L.l("Expected `(' after #foreach at `{0}'. The velocity-style #foreach syntax needs parentheses: #foreach ($a in expr)", badChar(ch))); addText(); processTaglib("resin-c", JSTL_CORE_URI); setLocation(_jspPath, _filename, _lineStart); _lineStart = _line; _jspBuilder.startElement(JSTL_CORE_FOREACH); CharBuffer cb = CharBuffer.allocate(); parseVelocityName(cb); if (cb.length() == 0) { throw error(L.l("Expected iteration variable for #foreach at `{0}'. The velocity-style #foreach syntax is: #foreach ($a in expr)", badChar(ch))); } String name = cb.toString(); cb.clear(); parseVelocityName(cb); if (cb.length() == 0) { throw error(L.l("Expected 'in' for #foreach at `{0}'. The velocity-style #foreach syntax is: #foreach ($a in expr)", badChar(ch))); } String value = cb.toString(); if (! value.equals("in")) { throw error(L.l("Expected 'in' for #foreach at `{0}'. The velocity-style #foreach syntax is: #foreach ($a in expr)", badChar(ch))); } if (name.startsWith("$")) name = name.substring(1); _jspBuilder.attribute(new QName("var"), name); cb.clear(); parseVelocityExpr(cb, ')'); String expr = cb.close(); if (expr.indexOf("..") > 0) { int h = 0; for (; Character.isWhitespace(expr.charAt(h)); h++) { } if (expr.charAt(h) != '[') throw error(L.l("Expected '[' for #foreach `{0}'. The velocity-style #foreach syntax is: #foreach ([Type] $a in [min .. max])", badChar(expr.charAt(h)))); int t = expr.length() - 1; for (; Character.isWhitespace(expr.charAt(t)); t--) { } if (expr.charAt(t) != ']') throw error(L.l("Expected ']' for #foreach `{0}'. The velocity-style #foreach syntax is: #foreach ($a in [min .. max])", badChar(expr.charAt(t)))); int p = expr.indexOf(".."); String min = expr.substring(h + 1, p); String max = expr.substring(p + 2, t); _jspBuilder.attribute(new QName("begin"), "${" + min + "}"); _jspBuilder.attribute(new QName("end"), "${" + max + "}"); } else { _jspBuilder.attribute(new QName("items"), "${" + expr + "}"); } _jspBuilder.endAttributes(); return skipWhitespaceToEndOfLine(read()); } /** * parses an #if statement */ private int parseVelocityIf(String eltName) throws IOException, JspParseException { int ch; for (ch = read(); XmlChar.isWhitespace(ch); ch = read()) { } if (ch != '(') throw error(L.l("Expected `(' after #if at `{0}'. The velocity-style #if syntax needs parentheses: #if (...)", badChar(ch))); addText(); processTaglib("resin-c", JSTL_CORE_URI); setLocation(_jspPath, _filename, _line); if (eltName.equals("if")) { _jspBuilder.startElement(JSTL_CORE_CHOOSE); _jspBuilder.endAttributes(); } _jspBuilder.startElement(JSTL_CORE_WHEN); _lineStart = _line; CharBuffer cb = CharBuffer.allocate(); parseVelocityExpr(cb, ')'); _jspBuilder.attribute(new QName("test"), "${" + cb.close() + "}"); _jspBuilder.endAttributes(); return skipWhitespaceToEndOfLine(read()); } private int parseVelocityName(CharBuffer cb) throws IOException, JspParseException { int ch; for (ch = read(); XmlChar.isWhitespace(ch); ch = read()) { } for (; Character.isJavaIdentifierPart((char) ch); ch = read()) cb.append((char) ch); return ch; } private int parseVelocityMin(CharBuffer cb) throws IOException, JspParseException { int ch; for (ch = read(); ch >= 0; ch = read()) { if (ch != '$') cb.append((char) ch); if (ch == '(') { ch = parseVelocityExpr(cb, ')'); cb.append((char) ch); } else if (ch == '[') { ch = parseVelocityExpr(cb, ']'); cb.append((char) ch); } else if (ch == '.') { ch = read(); if (ch == '.') return ch; else { cb.append('.'); _peek = ch; } } } return ch; } private int parseVelocityExpr(CharBuffer cb, int end) throws IOException, JspParseException { int ch; for (ch = read(); ch >= 0 && ch != end; ch = read()) { if (ch != '$') cb.append((char) ch); if (ch == '(') { ch = parseVelocityExpr(cb, ')'); cb.append((char) ch); } else if (ch == '[') { ch = parseVelocityExpr(cb, ']'); cb.append((char) ch); } } return ch; } /** * Parses a <![CDATA[ block. All text in the CDATA is uninterpreted. */ private void parseCdata() throws IOException, JspParseException { int ch; ch = readName(read()); String name = _tag.toString(); if (! name.equals("CDATA")) throw error(L.l("Expected <![CDATA[ at <!['{0}'.", name, "XML only recognizes the <![CDATA directive.")); if (ch != '[') throw error(L.l("Expected '[' at '{0}'. The XML CDATA syntax is <![CDATA[...]]>.", String.valueOf(ch))); String filename = _filename; int line = _line; while ((ch = read()) >= 0) { while (ch == ']') { if ((ch = read()) != ']') addText(']'); else if ((ch = read()) != '>') addText("]]"); else return; } addText((char) ch); } throw error(L.l("Expected closing ]]> at end of file to match <![[CDATA at {0}.", filename + ":" + line)); } /** * Parses an XML name for elements and attribute names. The parsed name * is stored in the 'tag' class variable. * * @param ch the next character * * @return the character following the name */ private int readName(int ch) throws IOException, JspParseException { _tag.clear(); for (; XmlChar.isNameChar((char) ch); ch = read()) _tag.append((char) ch); return ch; } private void parsePageDirective(String name, String value) throws IOException, JspParseException { if ("isELIgnored".equals(name)) { if ("true".equals(value)) _parseState.setELIgnored(true); } } /** * Parses a special JSP syntax. */ private void parseScriptlet() throws IOException, JspParseException { addText(); _lineStart = _line; int ch = read(); // probably should be a qname QName eltName = null; switch (ch) { case '=': eltName = JSP_EXPRESSION; ch = read(); break; case '!': eltName = JSP_DECLARATION; ch = read(); break; case '@': parseDirective(); return; case '-': if ((ch = read()) == '-') { parseComment(); return; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?