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 &lt;![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 + -
显示快捷键?