private Path<?> getPath(Expression<?> leftHandSide) { if (leftHandSide instanceof Path<?>) { return (Path<?>)leftHandSide; } else if (leftHandSide instanceof Operation<?>) { Operation<?> operation = (Operation<?>) leftHandSide; if (operation.getOperator() == Ops.LOWER || operation.getOperator() == Ops.UPPER) { return (Path<?>)operation.getArg(0); } } throw new IllegalArgumentException("Unable to transform " + leftHandSide + " to path"); }
@Override public Set<Expression<?>> visit(Operation<?> expr, Set<Expression<?>> known) { if (expr.getOperator() == Ops.ALIAS) { known = add(known, expr.getArg(1)); } for (Expression<?> arg : expr.getArgs()) { known = arg.accept(this, known); } return known; }
@SuppressWarnings("unchecked") @Override public Expression<?> visit(Operation<?> expr, Context context) { final Expression<?>[] args = new Expression<?>[expr.getArgs().size()]; for (int i = 0; i < args.length; i++) { Context c = new Context(); args[i] = expr.getArg(i).accept(this, c); context.add(c); } if (context.replace) { if (expr.getType().equals(Boolean.class)) { Predicate predicate = new PredicateOperation((Operator)expr.getOperator(), ImmutableList.copyOf(args)); return !context.paths.isEmpty() ? exists(context, predicate) : predicate; } else { return new OperationImpl(expr.getType(), expr.getOperator(), ImmutableList.copyOf(args)); } } else { return expr; } }
@Override public Void visit(Operation<?> expr, Void context) { visitOperation(expr.getType(), expr.getOperator(), expr.getArgs()); return null; }
@Override public Integer visit(Operation<?> expr, Void context) { int result = expr.getOperator().hashCode(); return 31 * result + expr.getArgs().hashCode(); }
private void verifyArguments(Operation<?> operation) { List<Expression<?>> arguments = operation.getArgs(); for (int i = 1; i < arguments.size(); ++i) { if (!(arguments.get(i) instanceof Constant<?>) && !(arguments.get(i) instanceof ParamExpression<?>) && !(arguments.get(i) instanceof PhraseElement) && !(arguments.get(i) instanceof TermElement)) { throw new IllegalArgumentException("operand was of unsupported type " + arguments.get(i).getClass().getName()); } } }
final Expression<?> expr = (Expression<?>) rv; if (precedence > -1 && expr instanceof Operation) { Operator op = ((Operation<?>) expr).getOperator(); int opPrecedence = templates.getPrecedence(op); if (precedence < opPrecedence) {
private Predicate<Bindings> createBoundPredicate(final Operation<?> expr, final Operator<?> op) { final String key = getKey(expr.getArg(0)); return new Predicate<Bindings>() { @Override public boolean apply(Bindings bindings) { boolean rv = bindings.get(key) != null; return op == Ops.IS_NOT_NULL ? rv : !rv; } }; }
@Override public final boolean equals(Object o) { if (o == this) { return true; } else if (o instanceof Operation<?>) { Operation<?> op = (Operation<?>)o; return op.getOperator() == operator && op.getArgs().equals(args) && op.getType().equals(getType()); } else { return false; } }
@Override public String visit(Operation<?> o, Templates templates) { final Template template = templates.getTemplate(o.getOperator()); if (template != null) { final int precedence = templates.getPrecedence(o.getOperator()); final StringBuilder builder = new StringBuilder(); for (Template.Element element : template.getElements()) { final Object rv = element.convert(o.getArgs()); if (rv instanceof Expression) { if (precedence > -1 && rv instanceof Operation) { if (precedence < templates.getPrecedence(((Operation<?>)rv).getOperator())) { builder.append("("); builder.append(((Expression)rv).accept(this, templates)); builder.append(")"); continue; } } builder.append(((Expression)rv).accept(this, templates)); } else { builder.append(rv.toString()); } } return builder.toString(); } else { return "unknown operation with operator " + o.getOperator().getId() + " and args " + o.getArgs(); } }
@Override public Void visit(Operation<?> expr, List<Path<?>> paths) { visit(expr.getArgs(), paths); return null; }
private List<Expression<?>> transformList(Expression<?> expr, List<Expression<?>> elements) { if (expr instanceof Operation<?> && ((Operation<?>) expr).getOperator() == Ops.LIST) { Operation<?> list = (Operation<?>) expr; transformList(list.getArg(0), elements); elements.add(list.getArg(1)); } else { elements.add(expr); } return elements; }
@SuppressWarnings("unchecked") @Override public ValueExpr visit(Operation<?> expr, QueryMetadata md) { Operator<?> op = expr.getOperator(); if (op == Ops.AND){ return new And(toValue(expr.getArg(0), md), toValue(expr.getArg(1), md)); }else if (op == Ops.OR){ return new Or(toValue(expr.getArg(0), md), toValue(expr.getArg(1), md)); }else if (op == Ops.IN){ for (Object o : ((Constant<Collection>)expr.getArg(1)).getConstant()) { builder.or(ExpressionUtils.eqConst((Expression)expr.getArg(0), o)); return new Not(toValue(expr.getArg(0), md)); }else if (COMPARE_OPS.containsKey(op)){ if (expr.getArg(1) instanceof SubQueryExpression<?>){ return new CompareAll(toValue(expr.getArg(0), md), toTuple(expr.getArg(1), md), COMPARE_OPS.get(op)); }else{ return new Compare(toValue(expr.getArg(0), md), toValue(expr.getArg(1), md), COMPARE_OPS.get(op)); return new MathExpr(toValue(expr.getArg(0), md), toValue(expr.getArg(1), md), MATH_OPS.get(op)); }else if (op == Ops.NEGATE){ return new MathExpr(toValue(expr.getArg(0), md), toValue(new ConstantImpl<LIT>(new LIT("-1", XSD.intType)), md), MathOp.MULTIPLY); }else if (op == Ops.MATCHES){ return new Regex(new Str(toValue(expr.getArg(0), md)), new Str(toValue(expr.getArg(1), md)), null); }else if (op == Ops.MATCHES_IC){ return new Regex(new Str(toValue(expr.getArg(0), md)), new Str(toValue(expr.getArg(1), md)), CASE_INSENSITIVE); }else if (op == Ops.STRING_IS_EMPTY){ return new Regex(new Str(toValue(expr.getArg(0), md)), "", false); }else if (op == Ops.IS_NULL){
@SuppressWarnings("rawtypes") @Override public Expression<?> visit(Operation<?> expr, Context context) { Expression<?>[] args = new Expression<?>[expr.getArgs().size()]; for (int i = 0; i < args.length; i++) { Context c = new Context(); args[i] = expr.getArg(i).accept(this, c); context.add(c); } if (context.replace) { if (expr.getType().equals(Boolean.class)) { Predicate predicate = new PredicateOperation((Operator<Boolean>)expr.getOperator(), ImmutableList.copyOf(args)); return !context.paths.isEmpty() ? exists(context, predicate) : predicate; } else { return new OperationImpl(expr.getType(), expr.getOperator(), ImmutableList.copyOf(args)); } } else { return expr; } }
protected boolean isReference(Operation<?> expr, int exprIndex) { Expression<?> arg = expr.getArg(exprIndex); if (arg instanceof Path) { return isReference((Path<?>) arg); } else { return false; } }
@Override public Expression<?> visit(Operation<?> expr, @Nullable Void context) { ImmutableList<Expression<?>> args = visit(expr.getArgs()); if (args.equals(expr.getArgs())) { return expr; } else if (expr instanceof Predicate) { return new PredicateOperation((Operator)expr.getOperator(), args); } else { return new OperationImpl(expr.getType(), expr.getOperator(), args); } }
@Override public Void visit(Operation<?> expr, Void context) { handle(expr.getArgs()); return null; }
private static ImmutableMap<Expression<?>, Integer> createBindings(List<Expression<?>> exprs) { Map<Expression<?>, Integer> map = Maps.newHashMap(); for (int i = 0; i < exprs.size(); i++) { Expression<?> e = exprs.get(i); if (e instanceof Operation && ((Operation<?>)e).getOperator() == Ops.ALIAS) { map.put(((Operation<?>)e).getArg(1), i); } map.put(e, i); } return ImmutableMap.copyOf(map); }
@SuppressWarnings("unchecked") @Override public ValueExpr visit(Operation<?> expr, QueryMetadata md) { Operator<?> op = expr.getOperator(); if (op == Ops.AND) { return new And(toValue(expr.getArg(0), md), toValue(expr.getArg(1), md)); } else if (op == Ops.OR) { return new Or(toValue(expr.getArg(0), md), toValue(expr.getArg(1), md)); } else if (op == Ops.IN) { for (Object o : ((Constant<Collection>) expr.getArg(1)).getConstant()) { builder.or(ExpressionUtils.eqConst((Expression) expr.getArg(0), o)); return new Not(toValue(expr.getArg(0), md)); } else if (COMPARE_OPS.containsKey(op)) { if (expr.getArg(1) instanceof SubQueryExpression<?>) { return new CompareAll(toValue(expr.getArg(0), md), toTuple(expr.getArg(1), md), COMPARE_OPS.get(op)); } else { return new Compare(toValue(expr.getArg(0), md), toValue(expr.getArg(1), md), COMPARE_OPS.get(op)); return new MathExpr(toValue(expr.getArg(0), md), toValue(expr.getArg(1), md), MATH_OPS.get(op)); } else if (op == Ops.NEGATE) { return new MathExpr(toValue(expr.getArg(0), md), toValue(new ConstantImpl<LIT>(new LIT("-1", XSD.intType)), md), MathOp.MULTIPLY); } else if (op == Ops.MATCHES) { return new Regex(new Str(toValue(expr.getArg(0), md)), new Str(toValue(expr.getArg(1), md)), null); } else if (op == Ops.MATCHES_IC) { return new Regex(new Str(toValue(expr.getArg(0), md)), new Str(toValue(expr.getArg(1), md)), CASE_INSENSITIVE); } else if (op == Ops.STRING_IS_EMPTY) { return new Regex(new Str(toValue(expr.getArg(0), md)), "", false); } else if (op == Ops.IS_NULL) {