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("&quot");          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 &lt;, &gt;, &amp;, &apos; and &quot;", 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 + -
显示快捷键?