jspparser.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 2,239 行 · 第 1/4 页
JAVA
2,239 行
else { eltName = JSP_SCRIPTLET; addText('-'); } break; default: eltName = JSP_SCRIPTLET; break; } setLocation(_jspPath, _filename, _lineStart); _jspBuilder.startElement(eltName); _jspBuilder.endAttributes(); while (ch >= 0) { switch (ch) { case '\\': addText('\\'); ch = read(); if (ch >= 0) addText((char) ch); ch = read(); break; case '%': ch = read(); if (ch == '>') { createText(); setLocation(); _jspBuilder.endElement(eltName.getName()); return; } else if (ch == '\\') { ch = read(); if (ch == '>') { addText("%"); } else addText("%\\"); } else addText('%'); break; default: addText((char) ch); ch = read(); break; } } createText(); setLocation(); _jspBuilder.endElement(eltName.getName()); } /** * Parses the JSP directive syntax. */ private void parseDirective() throws IOException, JspParseException { String language = null; int ch = skipWhitespace(read()); String directive = ""; if (XmlChar.isNameStart(ch)) { ch = readName(ch); directive = _tag.toString(); } else throw error(L.l("Expected jsp directive name at '{0}'. JSP directive syntax is <%@ name attr1='value1' ... %>", badChar(ch))); QName qname; if (directive.equals("page")) qname = JSP_DIRECTIVE_PAGE; else if (directive.equals("include")) qname = JSP_DIRECTIVE_INCLUDE; else if (directive.equals("taglib")) qname = JSP_DIRECTIVE_TAGLIB; else if (directive.equals("cache")) qname = JSP_DIRECTIVE_CACHE; else if (directive.equals("attribute")) qname = JSP_DIRECTIVE_ATTRIBUTE; else if (directive.equals("variable")) qname = JSP_DIRECTIVE_VARIABLE; else if (directive.equals("tag")) qname = JSP_DIRECTIVE_TAG; else throw error(L.l("'{0}' is an unknown jsp directive. Only <%@ page ... %>, <%@ include ... %>, <%@ taglib ... %>, and <%@ cache ... %> are known.", directive)); unread(ch); ArrayList<QName> keys = new ArrayList<QName>(); ArrayList<String> values = new ArrayList<String>(); parseAttributes(keys, values); ch = skipWhitespace(read()); if (ch != '%' || (ch = read()) != '>') { throw error(L.l("expected '%>' at {0}. JSP directive syntax is '<%@ name attr1='value1' ... %>'. (Started at line {1})", badChar(ch), _lineStart)); } setLocation(_jspPath, _filename, _lineStart); _lineStart = _line; _jspBuilder.startElement(qname); for (int i = 0; i < keys.size(); i++) { _jspBuilder.attribute(keys.get(i), values.get(i)); } _jspBuilder.endAttributes(); if (qname.equals(JSP_DIRECTIVE_TAGLIB)) processTaglibDirective(keys, values); setLocation(); _jspBuilder.endElement(qname.getName()); if (qname.equals(JSP_DIRECTIVE_PAGE) || qname.equals(JSP_DIRECTIVE_TAG)) { String contentEncoding = _parseState.getPageEncoding(); if (contentEncoding == null) contentEncoding = _parseState.getCharEncoding(); if (contentEncoding != null) { try { _stream.setEncoding(contentEncoding); } catch (Exception e) { log.log(Level.FINER, e.toString(), e); throw error(L.l("unknown content encoding '{0}'", contentEncoding), e); } } } /* if (directive.equals("include")) parseIncludeDirective(elt); else if (directive.equals("taglib")) parseTaglibDirective(elt); */ } /** * Parses an XML comment. */ private void parseComment() throws IOException, JspParseException { int ch = read(); while (ch >= 0) { if (ch == '-') { ch = read(); while (ch == '-') { if ((ch = read()) == '-') continue; else if (ch == '%' && (ch = read()) == '>') return; else if (ch == '-') ch = read(); } } else ch = read(); } } private void parseXmlComment() throws IOException, JspParseException { int ch; while ((ch = read()) >= 0) { while (ch == '-') { if ((ch = read()) == '-' && (ch = read()) == '>') return; } } } /** * Parses the open tag. */ private void parseOpenTag(String name, int ch, boolean isXml) throws IOException, JspParseException { addText(); ch = skipWhitespace(ch); ArrayList<QName> keys = new ArrayList<QName>(); ArrayList<String> values = new ArrayList<String>(); unread(ch); parseAttributes(keys, values); QName qname = getElementQName(name); setLocation(_jspPath, _filename, _lineStart); _lineStart = _line; _jspBuilder.startElement(qname); for (int i = 0; i < keys.size(); i++) { QName key = keys.get(i); String value = values.get(i); _jspBuilder.attribute(key, value); } _jspBuilder.endAttributes(); if (qname.equals(JSP_DIRECTIVE_TAGLIB)) processTaglibDirective(keys, values); ch = skipWhitespace(read()); JspNode node = _jspBuilder.getCurrentNode(); if (ch == '/') { if ((ch = read()) != '>') throw error(L.l("expected '/>' at '{0}' (for tag '<{1}>' at line {2}). The XML empty tag syntax is: <tag attr1='value1'/>", badChar(ch), name, String.valueOf(_lineStart))); setLocation(); _jspBuilder.endElement(qname.getName()); } else if (ch != '>') throw error(L.l("expected '>' at '{0}' (for tag '<{1}>' at line {2}). The XML tag syntax is: <tag attr1='value1'>", badChar(ch), name, String.valueOf(_lineStart))); // If tagdependent and not XML mode, then read the raw text. else if ("tagdependent".equals(node.getBodyContent()) && ! _isXml) { String tail = "</" + name + ">"; for (ch = read(); ch >= 0; ch = read()) { _text.append((char) ch); if (_text.endsWith(tail)) { _text.setLength(_text.length() - tail.length()); addText(); _jspBuilder.endElement(qname.getName()); return; } } throw error(L.l("expected '{0}' at end of file (for tag <{1}> at line {2}). Tags with 'tagdependent' content need close tags.", tail, String.valueOf(_lineStart))); } } /** * Returns the full QName for the JSP page's name. */ private QName getElementQName(String name) { int p = name.lastIndexOf(':'); if (p > 0) { String prefix = name.substring(0, p); String url = Namespace.find(_namespaces, prefix); _prefixes.add(prefix); if (url != null) return new QName(prefix, name.substring(p + 1), url); else return new QName("", name, ""); } else { String url = Namespace.find(_namespaces, ""); if (url != null) return new QName("", name, url); else return new QName("", name, ""); } } /** * Returns the full QName for the JSP page's name. */ private QName getAttributeQName(String name) { int p = name.lastIndexOf(':'); if (p > 0) { String prefix = name.substring(0, p); String url = Namespace.find(_namespaces, prefix); if (url != null) return new QName(prefix, name.substring(p + 1), url); else return new QName("", name, ""); } else return new QName("", name, ""); } /** * Parses the attributes of an element. */ private void parseAttributes(ArrayList<QName> names, ArrayList<String> values) throws IOException, JspParseException { names.clear(); values.clear(); int ch = skipWhitespace(read()); while (XmlChar.isNameStart(ch)) { ch = readName(ch); String key = _tag.toString(); readValue(key, ch, _isXml); String value = _value.toString(); if (key.startsWith("xmlns:")) { String prefix = key.substring(6); _jspBuilder.startPrefixMapping(prefix, value); //_parseState.pushNamespace(prefix, value); _namespaces = new Namespace(_namespaces, prefix, value); } else if (key.equals("xmlns")) { _jspBuilder.startPrefixMapping("", value); //_parseState.pushNamespace(prefix, value); //_parseState.pushNamespace("", value); _namespaces = new Namespace(_namespaces, "", value); } else { names.add(getAttributeQName(key)); values.add(value); } ch = skipWhitespace(read()); } unread(ch); } /** * Reads an attribute value. */ private void readValue(String attribute, int ch, boolean isXml) throws IOException, JspParseException { boolean isRuntimeAttribute = false; _value.clear(); ch = skipWhitespace(ch); if (ch != '=') { unread(ch); return; } ch = skipWhitespace(read()); if (ch != '\'' && ch != '"') { if (XmlChar.isNameChar(ch)) { ch = readName(ch); throw error(L.l("'{0}' attribute value must be quoted at '{1}'. JSP attribute syntax is either attr=\"value\" or attr='value'.", attribute, _tag)); } else throw error(L.l("'{0}' attribute value must be quoted at '{1}'. JSP attribute syntax is either attr=\"value\" or attr='value'.", attribute, badChar(ch))); } int end = ch; int lastCh = 0; ch = read(); if (ch != '<') { } else if ((ch = read()) != '%') _value.append('<'); else if ((ch = read()) != '=') _value.append("<%"); else { _value.append("<%"); isRuntimeAttribute = true; } while (ch != -1 && (ch != end || isRuntimeAttribute)) { if (ch == '\\') { switch ((ch = read())) { case '\\': case '\'': case '\"': // jsp/1505 vs jsp/184s // _value.append('\\'); _value.append((char) ch); ch = read(); break; case '>': if (lastCh == '%') { _value.append('>'); ch = read(); } else _value.append('\\'); break; case '%': if (lastCh == '<') { _value.append('%'); ch = read(); } else _value.append('\\'); break; default: _value.append('\\'); break; } } else if (ch == '%' && isRuntimeAttribute) { _value.append('%'); ch = read(); if (ch == '>') isRuntimeAttribute = false; } else if (ch == '&' && isXml) { lastCh = -1; _value.append((char) parseEntity()); ch = read(); } else if (ch == '&') { if ((ch = read()) == 'a') { if ((ch = read()) != 'p') _value.append("&a"); else if ((ch = read()) != 'o') _value.append("&ap"); else if ((ch = read()) != 's') _value.append("&apo"); else if ((ch = read()) != ';') _value.append("&apos"); else { _value.append('\''); ch = read(); } } else if (ch == 'q') { if ((ch = read()) != 'u') _value.append("&q"); else if ((ch = read()) != 'o') _value.append("&qu"); else if ((ch = read()) != 't') _value.append("&quo"); else if ((ch = read()) != ';') _value.append("""); else { _value.append('"'); ch = read(); } } else _value.append('&'); } else { _value.append((char) ch); lastCh = ch; ch = read(); } } } /** * Parses an XML entity. */ int parseEntity() throws IOException, JspParseException { int ch = read(); if (_isXml && ch == '#') { int value = 0; for (ch = read(); ch >= '0' && ch <= '9'; ch = read()) value = 10 * value + ch - '0'; if (ch != ';') throw error(L.l("expected ';' at '{0}' in character entity. The XML character entities syntax is &#nn;", badChar(ch))); return (char) value; } CharBuffer cb = CharBuffer.allocate(); for (; ch >= 'a' && ch <= 'z'; ch = read()) cb.append((char) ch); if (ch != ';') { log.warning(L.l("expected ';' at '{0}' in entity '&{1}'. The XML entity syntax is &name;", badChar(ch), cb)); } String entity = cb.close(); if (entity.equals("lt")) return '<'; else if (entity.equals("gt")) return '>'; else if (entity.equals("amp")) return '&'; else if (entity.equals("apos")) return '\''; else if (entity.equals("quot")) return '"'; else throw error(L.l("unknown entity '&{0};'. XML only recognizes the special entities <, >, &, ' and "", entity)); } private int parseCloseTag() throws IOException, JspParseException { int ch; if (! XmlChar.isNameStart(ch = read())) { addText("</"); return ch; } ch = readName(ch); String name = _tag.toString(); if (! _isXml && getTag(name) == TAG_UNKNOWN) { addText("</"); addText(name); return ch; } ch = skipWhitespace(ch); if (ch != '>') throw error(L.l("expected '>' at {0}. The XML close tag syntax is </name>.", badChar(ch))); JspNode node = _jspBuilder.getCurrentNode(); String nodeName = node.getTagName(); if (nodeName.equals(name)) { } else if (nodeName.equals("resin-c:when")) { throw error(L.l("#if expects closing #end before </{0}> (#if at {1}). #if statements require #end before the enclosing tag closes.", name, String.valueOf(node.getStartLine()))); } else if (nodeName.equals("resin-c:otherwise")) { throw error(L.l("#else expects closing #end before </{0}> (#else at {1}). #if statements require #end before the enclosing tag closes.", name, String.valueOf(node.getStartLine()))); } else { throw error(L.l("expected </{0}> at </{1}>. Closing tags must match opened tags.", nodeName, name));
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?