コード例 #1
0
 /**
  * {@inheritDoc}
  *
  * @see
  *     org.modeshape.jcr.query.parse.BasicSqlQueryParser#parseFrom(org.modeshape.common.text.TokenStream,
  *     org.modeshape.jcr.query.model.TypeSystem)
  */
 @Override
 protected Source parseFrom(TokenStream tokens, TypeSystem typeSystem) {
   Position firstSourcePosition = tokens.nextPosition();
   Source source = super.parseFrom(tokens, typeSystem);
   if (tokens.matches(',') && source instanceof NamedSelector) {
     NamedSelector selector = (NamedSelector) source;
     JoinableSources joinedSources = new JoinableSources(selector, firstSourcePosition);
     while (tokens.canConsume(',')) {
       // This is a JCR-SQL-style JOIN ...
       Position nextSourcePosition = tokens.nextPosition();
       NamedSelector nextSource = parseNamedSelector(tokens, typeSystem);
       joinedSources.add(nextSource, nextSourcePosition);
     }
     source = joinedSources;
   }
   return source;
 }
コード例 #2
0
 protected Source rewrite(JoinableSources joinableSources) {
   // Find the order of the joins ...
   List<Join> joins = new LinkedList<Join>();
   for (SameNodeJoinCondition joinCondition : joinableSources.getJoinConditions()) {
     SelectorName selector1 = joinCondition.selector1Name();
     SelectorName selector2 = joinCondition.selector2Name();
     boolean found = false;
     ListIterator<Join> iter = joins.listIterator();
     while (iter.hasNext()) {
       Join next = iter.next();
       Join replacement = null;
       if (usesSelector(next, selector1)) {
         Source right = joinableSources.getSelectors().get(selector2.name());
         replacement = new Join(next, JoinType.INNER, right, joinCondition);
       } else if (usesSelector(next, selector2)) {
         Source left = joinableSources.getSelectors().get(selector1.name());
         replacement = new Join(left, JoinType.INNER, next, joinCondition);
       }
       if (replacement != null) {
         iter.previous();
         iter.remove();
         joins.add(replacement);
         found = true;
         break;
       }
     }
     if (!found) {
       // Nothing matched, so add a new join ...
       Source left = joinableSources.getSelectors().get(selector1.name());
       Source right = joinableSources.getSelectors().get(selector2.name());
       if (left == null) {
         Position pos = joinableSources.getJoinCriteriaPosition();
         String msg =
             JcrI18n.selectorUsedInEquiJoinCriteriaDoesNotExistInQuery.text(
                 selector1.name(), pos.getLine(), pos.getColumn());
         throw new ParsingException(pos, msg);
       }
       if (right == null) {
         Position pos = joinableSources.getJoinCriteriaPosition();
         String msg =
             JcrI18n.selectorUsedInEquiJoinCriteriaDoesNotExistInQuery.text(
                 selector2.name(), pos.getLine(), pos.getColumn());
         throw new ParsingException(pos, msg);
       }
       joins.add(new Join(left, JoinType.INNER, right, joinCondition));
     }
   }
   if (joins.size() == 1) {
     return joins.get(0);
   }
   // Otherwise the join conditions were not sufficient
   return null;
 }
コード例 #3
0
  /**
   * Parse a constraint clause. This method inherits all of the functionality from JCR-SQL2, except
   * that JCR-SQL allows constraints that use "<code>jcr:path</code>" and "<code>jcr:score</code>"
   * pseudo-columns. In these special cases, the resulting {@link Comparison comparison} will have a
   * {@link NodePath} or {@link FullTextSearchScore} dynamic operand.
   *
   * @see
   *     org.modeshape.jcr.query.parse.BasicSqlQueryParser#parseConstraint(org.modeshape.common.text.TokenStream,
   *     org.modeshape.jcr.query.model.TypeSystem, org.modeshape.jcr.query.model.Source)
   */
  @Override
  protected Constraint parseConstraint(TokenStream tokens, TypeSystem typeSystem, Source source) {
    Constraint constraint = null;
    if (tokens.canConsume("JCR", ":", "PATH")) {
      // It is a property constraint on "jcr:path" ...
      SelectorName selector = getSelectorNameFor(source);
      PropertyValue value = new PropertyValue(selector, "jcr:path");
      Operator operator = parseComparisonOperator(tokens);
      StaticOperand right = parseStaticOperand(tokens, typeSystem);
      constraint = rewriteConstraint(new Comparison(value, operator, right));
    } else if (tokens.matches(ANY_VALUE, "IN")) {
      // This is a "... 'value' IN prop ..." pattern used in the JCR TCK tests but not in the JCR
      // 1.0.1 specification
      // ...
      Literal value = parseLiteral(tokens, typeSystem);
      tokens.consume("IN");
      PropertyValue propertyValue = parsePropertyValue(tokens, typeSystem, source);
      constraint = new SetCriteria(propertyValue, value);
    } else if (source instanceof JoinableSources
        && !(tokens.matches("(")
            || tokens.matches("NOT")
            || tokens.matches("CONTAINS", "(")
            || tokens.matches("ISSAMENODE", "(")
            || tokens.matches("ISCHILDNODE", "(")
            || tokens.matches("ISDESCENDANTNODE", "("))) {
      JoinableSources joinableSources = (JoinableSources) source;
      // See if this is a join condition ...
      if (tokens.matches(ANY_VALUE, ":", ANY_VALUE, ".", "JCR", ":", "PATH", "=")
          || tokens.matches(ANY_VALUE, ".", "JCR", ":", "PATH", "=")) {
        Position position = tokens.nextPosition();
        SelectorName selector1 = parseSelectorName(tokens, typeSystem);
        tokens.consume('.');
        parseName(tokens, typeSystem); // jcr:path
        tokens.consume('=');
        SelectorName selector2 = parseSelectorName(tokens, typeSystem);
        tokens.consume('.');
        parseName(tokens, typeSystem); // jcr:path
        joinableSources.add(new SameNodeJoinCondition(selector1, selector2), position);

        // AND has higher precedence than OR, so we need to evaluate it first ...
        while (tokens.canConsume("AND")) {
          Constraint rhs = parseConstraint(tokens, typeSystem, source);
          if (rhs != null) constraint = constraint != null ? new And(constraint, rhs) : rhs;
        }
        while (tokens.canConsume("OR")) {
          Constraint rhs = parseConstraint(tokens, typeSystem, source);
          if (rhs != null) constraint = constraint != null ? new And(constraint, rhs) : rhs;
        }
        return constraint;
      }
    }
    if (constraint != null) {
      // AND has higher precedence than OR, so we need to evaluate it first ...
      while (tokens.canConsume("AND")) {
        Constraint rhs = parseConstraint(tokens, typeSystem, source);
        if (rhs != null) constraint = new And(constraint, rhs);
      }
      while (tokens.canConsume("OR")) {
        Constraint rhs = parseConstraint(tokens, typeSystem, source);
        if (rhs != null) constraint = new Or(constraint, rhs);
      }
      return constraint;
    }

    constraint = super.parseConstraint(tokens, typeSystem, source);
    constraint = rewriteConstraint(constraint);
    return constraint;
  }