@Override
 public Void visit(Operation<?> expr, Stack<String> context) {
   throw new IllegalStateException("Detected " + expr.getType() + " in path expression!");
 }
 private String regexValue(Operation<?> expr, int index) {
   return Pattern.quote(expr.getArg(index).accept(this, null).toString());
 }
  @Override
  public Object visit(Operation<?> expr, Void context) {
    Operator<?> op = expr.getOperator();
    if (op == Ops.EQ) {
      if (expr.getArg(0) instanceof Operation) {
        Operation<?> lhs = (Operation<?>) expr.getArg(0);
        if (lhs.getOperator() == Ops.COL_SIZE || lhs.getOperator() == Ops.ARRAY_SIZE) {
          return asDBObject(asDBKey(lhs, 0), asDBObject("$size", asDBValue(expr, 1)));
        } else {
          throw new UnsupportedOperationException("Illegal operation " + expr);
        }
      } else {
        return asDBObject(asDBKey(expr, 0), asDBValue(expr, 1));
      }

    } else if (op == Ops.STRING_IS_EMPTY) {
      return asDBObject(asDBKey(expr, 0), "");

    } else if (op == Ops.AND) {
      BasicDBObject left = (BasicDBObject) handle(expr.getArg(0));
      left.putAll((BSONObject) handle(expr.getArg(1)));
      return left;

    } else if (op == Ops.NOT) {
      // Handle the not's child
      BasicDBObject arg = (BasicDBObject) handle(expr.getArg(0));

      // Only support the first key, let's see if there
      // is cases where this will get broken
      String key = arg.keySet().iterator().next();

      Operator<?> subOp = ((Operation<?>) expr.getArg(0)).getOperator();
      if (subOp != Ops.EQ && subOp != Ops.STRING_IS_EMPTY) {
        return asDBObject(key, asDBObject("$not", arg.get(key)));
      } else {
        return asDBObject(key, asDBObject("$ne", arg.get(key)));
      }

    } else if (op == Ops.OR) {
      BasicDBList list = new BasicDBList();
      list.add(handle(expr.getArg(0)));
      list.add(handle(expr.getArg(1)));
      return asDBObject("$or", list);

    } else if (op == Ops.NE) {
      return asDBObject(asDBKey(expr, 0), asDBObject("$ne", asDBValue(expr, 1)));

    } else if (op == Ops.STARTS_WITH) {
      return asDBObject(asDBKey(expr, 0), Pattern.compile("^" + regexValue(expr, 1)));

    } else if (op == Ops.STARTS_WITH_IC) {
      return asDBObject(
          asDBKey(expr, 0), Pattern.compile("^" + regexValue(expr, 1), Pattern.CASE_INSENSITIVE));

    } else if (op == Ops.ENDS_WITH) {
      return asDBObject(asDBKey(expr, 0), Pattern.compile(regexValue(expr, 1) + "$"));

    } else if (op == Ops.ENDS_WITH_IC) {
      return asDBObject(
          asDBKey(expr, 0), Pattern.compile(regexValue(expr, 1) + "$", Pattern.CASE_INSENSITIVE));

    } else if (op == Ops.EQ_IGNORE_CASE) {
      return asDBObject(
          asDBKey(expr, 0),
          Pattern.compile("^" + regexValue(expr, 1) + "$", Pattern.CASE_INSENSITIVE));

    } else if (op == Ops.STRING_CONTAINS) {
      return asDBObject(asDBKey(expr, 0), Pattern.compile(".*" + regexValue(expr, 1) + ".*"));

    } else if (op == Ops.STRING_CONTAINS_IC) {
      return asDBObject(
          asDBKey(expr, 0),
          Pattern.compile(".*" + regexValue(expr, 1) + ".*", Pattern.CASE_INSENSITIVE));

    } else if (op == Ops.MATCHES) {
      return asDBObject(asDBKey(expr, 0), Pattern.compile(asDBValue(expr, 1).toString()));

    } else if (op == Ops.MATCHES_IC) {
      return asDBObject(
          asDBKey(expr, 0),
          Pattern.compile(asDBValue(expr, 1).toString(), Pattern.CASE_INSENSITIVE));

    } else if (op == Ops.LIKE) {
      String regex = ExpressionUtils.likeToRegex((Expression) expr.getArg(1)).toString();
      return asDBObject(asDBKey(expr, 0), Pattern.compile(regex));

    } else if (op == Ops.BETWEEN) {
      BasicDBObject value = new BasicDBObject("$gte", asDBValue(expr, 1));
      value.append("$lte", asDBValue(expr, 2));
      return asDBObject(asDBKey(expr, 0), value);

    } else if (op == Ops.IN) {
      int constIndex = 0;
      int exprIndex = 1;
      if (expr.getArg(1) instanceof Constant<?>) {
        constIndex = 1;
        exprIndex = 0;
      }
      if (Collection.class.isAssignableFrom(expr.getArg(constIndex).getType())) {
        Collection<?> values =
            (Collection<?>) ((Constant<?>) expr.getArg(constIndex)).getConstant();
        return asDBObject(asDBKey(expr, exprIndex), asDBObject("$in", values.toArray()));
      } else {
        return asDBObject(asDBKey(expr, exprIndex), asDBValue(expr, constIndex));
      }

    } else if (op == Ops.LT) {
      return asDBObject(asDBKey(expr, 0), asDBObject("$lt", asDBValue(expr, 1)));

    } else if (op == Ops.GT) {
      return asDBObject(asDBKey(expr, 0), asDBObject("$gt", asDBValue(expr, 1)));

    } else if (op == Ops.LOE) {
      return asDBObject(asDBKey(expr, 0), asDBObject("$lte", asDBValue(expr, 1)));

    } else if (op == Ops.GOE) {
      return asDBObject(asDBKey(expr, 0), asDBObject("$gte", asDBValue(expr, 1)));

    } else if (op == Ops.IS_NULL) {
      return asDBObject(asDBKey(expr, 0), asDBObject("$exists", false));

    } else if (op == Ops.IS_NOT_NULL) {
      return asDBObject(asDBKey(expr, 0), asDBObject("$exists", true));

    } else if (op == Ops.CONTAINS_KEY) {
      Path<?> path = (Path<?>) expr.getArg(0);
      Expression<?> key = expr.getArg(1);
      return asDBObject(visit(path, context) + "." + key.toString(), asDBObject("$exists", true));

    } else if (op == MongodbExpressions.NEAR) {
      return asDBObject(asDBKey(expr, 0), asDBObject("$near", asDBValue(expr, 1)));

    } else if (op == MongodbExpressions.ELEM_MATCH) {
      return asDBObject(asDBKey(expr, 0), asDBObject("$elemMatch", asDBValue(expr, 1)));
    }

    throw new UnsupportedOperationException("Illegal operation " + expr);
  }
 private Object asDBValue(Operation<?> expr, int index) {
   return expr.getArg(index).accept(this, null);
 }
Exemple #5
0
 @Override
 public boolean equals(Object o) {
   return opMixin.equals(o);
 }
Exemple #6
0
 @Override
 public Operator<? super T> getOperator() {
   return opMixin.getOperator();
 }
Exemple #7
0
 @Override
 public List<Expression<?>> getArgs() {
   return opMixin.getArgs();
 }
Exemple #8
0
 @Override
 public Expression<?> getArg(int index) {
   return opMixin.getArg(index);
 }