queryparser.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 2,704 行 · 第 1/5 页

JAVA
2,704
字号
  }  /**   * Adds an entity path   */  public PathExpr addPath(PathExpr path)  {    PathExpr oldPath = _pathMap.get(path);    if (oldPath != null)      return oldPath;    _pathMap.put(path, path);    return path;  }  /**   * Adds a new argument   */  public void addArg(ArgExpr arg)  {    _argList.add(arg);  }  /**   * Parses a schema.   */  private SchemaExpr parseSchema()    throws QueryParseException  {    int token = peekToken();    boolean isIn = token == IN;    if (isIn) {      scanToken();      _joinSemantics = FromItem.JoinSemantics.INNER;      if ((token = scanToken()) != '(')        throw error(L.l("expected '(' at '{0}'", tokenName(token)));    }    String name = parseIdentifier();    SchemaExpr schema = null;    if (! isIn) {      AmberEntityHome home = _persistenceUnit.getHomeBySchema(name);      if (home != null) {        EntityType type = home.getEntityType();        schema = new TableIdExpr(home.getEntityType(),                                 type.getTable().getName());      }    }    IdExpr id = null;    if (schema == null) {      id = getIdentifier(name);      if (id != null)        schema = new FromIdSchemaExpr(id);    }    if (! isIn && schema == null) {      while (peekToken() == '.') {        scanToken();        String segment = parseIdentifier();        name = name + '.' + segment;        AmberEntityHome home = _persistenceUnit.getHomeBySchema(name);        if (home != null) {          schema = new TableIdExpr(home.getEntityType(), name);          break;        }      }    }    if (schema == null) {      throw error(L.l("'{0}' is an unknown entity.",                      name));    }    name = "";    boolean isFirst = true;    while (peekToken() == '.') {      scanToken();      String segment = parseIdentifier();      if (isFirst) {        name += segment;        isFirst = false;      }      else        name += "." + segment;      schema = schema.createField(this, segment);    }    if (_isJoinFetch && (! name.equals(""))) {      _joinFetchMap.put(id, name);    }    if (isIn) {      if ((token = scanToken()) != ')')        throw error(L.l("expected ')' at '{0}'", tokenName(token)));    }    return schema;  }  /**   * Parses an expression.   */  private AmberExpr parseExpr()    throws QueryParseException  {    if (peekToken() == SELECT) {      SelectQuery select = parseSelect(true);      return new SubSelectExpr(select);    }    AmberExpr expr = parseOrExpr();    return expr; // .bindSelect(this);  }  /**   * Parses an or expression.   */  private AmberExpr parseOrExpr()    throws QueryParseException  {    AmberExpr expr = parseAndExpr();    OrExpr orExpr = null;    while (peekToken() == OR) {      scanToken();      if (orExpr == null) {        orExpr = new OrExpr();        orExpr.add(expr);      }      AmberExpr andExpr = parseAndExpr();      if (andExpr == null)        continue;      orExpr.add(andExpr);    }    return orExpr == null ? expr : orExpr;  }  /**   * Parses an and expression.   */  private AmberExpr parseAndExpr()    throws QueryParseException  {    AmberExpr expr = parseNotExpr();    AndExpr andExpr = null;    while (peekToken() == AND) {      scanToken();      if (andExpr == null) {        andExpr = new AndExpr();        andExpr.add(expr);      }      AmberExpr notExpr = parseNotExpr();      if (notExpr == null)        continue;      andExpr.add(notExpr);    }    return andExpr == null ? expr : andExpr;  }  /**   * Parses a NOT expression.   *   */  private AmberExpr parseNotExpr()    throws QueryParseException  {    AmberExpr expr;    if (peekToken() == NOT) {      scanToken();      expr = new UnaryExpr(NOT, parseCmpExpr());    }    else      expr = parseCmpExpr();    // jpa/1199, jpa/119l    if (_parsingResult || _parsingHaving)      return expr;    if (! _isSizeFunExpr)      return expr;    if (_havingExpr == null) {      _havingExpr = expr;    }    else if (expr != null) { // jpa/1199      _havingExpr = AndExpr.create(_havingExpr, expr);    }    return null;  }  /**   * Parses a comparison expression.   *   * <pre>   * cmp-expr ::= add-expr '=' add-expr is-term?   *          ::= add-expr 'NOT'? 'BETWEEN' add-expr 'AND' add-expr is-term?   *          ::= add-expr 'NOT'? 'LIKE' string ('ESCAPE' string)? is-term?   *          ::= add-expr 'NOT'? 'IN' ('lit-1', ..., 'lit-n')   *          ::= add-expr   * </pre>   *   * @return the parsed expression   */  private AmberExpr parseCmpExpr()    throws QueryParseException  {    AmberExpr expr = parseConcatExpr();    int token = peekToken();    boolean isNot = false;    if (token == NOT) {      scanToken();      isNot = true;      token = peekToken();      if (token != BETWEEN &&          token != LIKE &&          token != MEMBER &&          token != IN)        throw error(L.l("'NOT' is not expected here."));    }    if (token >= EQ && token <= GE) {      scanToken();      AmberExpr concatExpr = parseConcatExpr();      return parseIs(new BinaryExpr(token, expr, concatExpr));    }    else if (token == BETWEEN) {      scanToken();      AmberExpr min = parseConcatExpr();      if ((token = scanToken()) != AND)        throw error(L.l("Expected 'AND' at {0}", tokenName(token)));      AmberExpr max = parseConcatExpr();      // jpa/106a      if (! isCompatibleExpression(expr, min))        throw error(L.l("Expected compatible expression at {0} BETWEEN {1}", expr, min));      if (! isCompatibleExpression(expr, max))        throw error(L.l("Expected compatible expression at BETWEEN {0} AND {1}", min, max));      return new BetweenExpr(expr, min, max, isNot);    }    else if (token == LIKE) {      scanToken();      AmberExpr pattern = parseConcatExpr();      // jpa/1075      if (pattern instanceof LiteralExpr) {        LiteralExpr literalExpr = (LiteralExpr) pattern;        if (literalExpr.getJavaType() != String.class)          throw error(L.l("Expected string at {0}", pattern));      }      else if (! (pattern instanceof ArgExpr)) // jpa/1076        throw error(L.l("Expected string at {0}", pattern));      String escape = null;      if (peekToken() == ESCAPE) {        scanToken();        if ((token = scanToken()) != STRING)          throw error(L.l("Expected string at {0}", tokenName(token)));        escape = _lexeme.toString();      }      return parseIs(new LikeExpr(expr, pattern, escape, isNot));    }    else if (token == IN) {      scanToken();      token = scanToken();      if (token != '(')        throw error(L.l("Expected '(' after IN at {0}", tokenName(token)));      ArrayList<AmberExpr> args = new ArrayList<AmberExpr>();      while ((token = peekToken()) > 0 && token != ')') {        AmberExpr arg = parseExpr();        args.add(arg);        token = peekToken();        if (token == ',') {          scanToken();          token = peekToken();        }      }      if (peekToken() != ')')        throw error(L.l("Expected ')' after IN at {0}", tokenName(token)));      scanToken();      if (expr instanceof IdExpr) {        IdExpr idExpr = (IdExpr) expr;        // jpa/1174        if (idExpr.getFromItem().isEntityType())          throw error(L.l("Unexpected entity at '{0} IN'", expr));      }      return new InExpr(expr, args, isNot);    }    else if (token == MEMBER) {      scanToken();      token = peekToken();      if (token == OF)        token = scanToken();      AmberExpr collection = parseExpr();      // jpa/10c8      if (expr instanceof ArgExpr) {        addArg((ArgExpr) expr);      }      else if (! (expr instanceof PathExpr))        throw error(L.l("MEMBER OF requires an entity-valued item."));      if (! isCollectionExpr(collection))        throw error(L.l("MEMBER OF requires an entity-valued collection at '{0}'.",                        collection.getClass().getName()));      return parseIs(MemberExpr.create(this,                                       expr,                                       collection,                                       isNot));    }    else      return parseIs(expr);  }  private AmberExpr parseIs(AmberExpr expr)    throws QueryParseException  {    int token = peekToken();    if (token != IS)      return expr;    scanToken();    boolean isNot = false;    token = scanToken();    if (token == NOT) {      isNot = true;      token = scanToken();    }    if (token == NULL) {      if (expr instanceof KeyColumnExpr)        expr = ((KeyColumnExpr) expr).getParent();      else if (expr instanceof IdExpr) {        IdExpr idExpr = (IdExpr) expr;        // jpa/1093        if (idExpr.getFromItem().isEntityType())          throw error(L.l("Unexpected entity at '{0} IS'", expr));      }      if (isNot)        return new UnaryExpr(NOT_NULL, expr);      else        return new UnaryExpr(NULL, expr);    }    else if (token == EMPTY) {      if (! isCollectionExpr(expr))        throw error(L.l("IS EMPTY requires an entity-valued collection at '{0}'.",                        expr.getClass().getName()));      expr = new EmptyExpr(expr);      if (! isNot)        expr = new UnaryExpr(NOT, expr);      return expr;    }    else      throw error(L.l("expected NULL at '{0}'", tokenName(token)));  }  /**   * Parses a concat expression.   */  private AmberExpr parseConcatExpr()    throws QueryParseException  {    AmberExpr expr = parseAddExpr();    while (true) {      int token = peekToken();      switch (token) {      case CONCAT_OP:        scanToken();        ArrayList<AmberExpr> args = new ArrayList<AmberExpr>();        args.add(expr);        args.add(parseAddExpr());        expr = ConcatFunExpr.create(this, args);        break;      default:        return expr;      }    }  }  /**   * Parses an add expression.   */  private AmberExpr parseAddExpr()    throws QueryParseException  {    AmberExpr expr = parseMulExpr();    while (true) {      int token = peekToken();      switch (token) {      case '+':      case '-':        scanToken();        expr = new BinaryExpr(token, expr, parseMulExpr());        break;      default:        return expr;      }    }  }  /**   * Parses a mul expression.   */  private AmberExpr parseMulExpr()    throws QueryParseException  {    AmberExpr expr = parseTerm();    while (true) {      int token = peekToken();      switch (token) {      case '*':      case '/':        scanToken();        expr = new BinaryExpr(token, expr, parseTerm());        break;      default:        return expr;      }    }  }  /**   * Parses a term   *   * <pre>   * term ::= - term   *      ::= + term   *      ::= NOT term   * </pre>   */  private AmberExpr parseTerm()    throws QueryParseException  {    int token = peekToken();    switch (token) {    case '+':    case '-':    case NOT:      scanToken();      return new UnaryExpr(token, parseTerm());    default:      return parseSimpleTerm();    }  }  /**   * Parses a simple term   *   * <pre>   * term ::= INTEGER | LONG | DOUBLE | STRING   *      ::= THIS   *      ::= IDENTIFIER   *      ::= IDENTIFIER '(' args ')'   *      ::= '(' expr ')'   * </pre>   */  private AmberExpr parseSimpleTerm()    throws QueryParseException  {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?