protected Constraint rewriteConstraint(Constraint constraint) { if (constraint instanceof Comparison) { Comparison comparison = (Comparison) constraint; DynamicOperand left = comparison.getOperand1(); if (left instanceof PropertyValue) { PropertyValue propValue = (PropertyValue) left; if ("jcr:path".equals(propValue.getPropertyName())) { // Rewrite this constraint as a PATH criteria ... NodePath path = new NodePath(propValue.selectorName()); return new Comparison(path, comparison.operator(), comparison.getOperand2()); } if ("jcr:score".equals(propValue.getPropertyName())) { // Rewrite this constraint as a SCORE criteria ... FullTextSearchScore score = new FullTextSearchScore(propValue.selectorName()); return new Comparison(score, comparison.operator(), comparison.getOperand2()); } } } else if (constraint instanceof FullTextSearch) { FullTextSearch search = (FullTextSearch) constraint; if (".".equals(search.getPropertyName())) { // JCR-SQL's use of CONTAINS allows a '.' to be used to represent the search is to be // performed on all properties of the node(s). However, JCR-SQL2 and our AQM // expect a '*' to be used instead ... return new FullTextSearch(search.selectorName(), search.fullTextSearchExpression()); } } else if (constraint instanceof And) { And and = (And) constraint; constraint = new And(rewriteConstraint(and.left()), rewriteConstraint(and.right())); } else if (constraint instanceof Or) { Or or = (Or) constraint; constraint = new Or(rewriteConstraint(or.left()), rewriteConstraint(or.right())); } return constraint; }
/** * Create the constraint evaluator that is used by the {@link SelectComponent} to evaluate the * supplied {@link Constraint criteria}. * * @param types the type system; may not be null * @param schemata the schemata; may not be null * @param columns the definition of the result columns and the tuples; may not be null * @param constraint the criteria that this {@link SelectComponent} is to evaluate * @param variables the variables that are to be substituted for the various {@link * BindVariableName} {@link StaticOperand operands}; may not be null * @return the constraint evaluator; never null */ protected ConstraintChecker createChecker( final TypeSystem types, Schemata schemata, Columns columns, Constraint constraint, Map<String, Object> variables) { if (constraint instanceof Or) { Or orConstraint = (Or) constraint; final ConstraintChecker left = createChecker(types, schemata, columns, orConstraint.left(), variables); final ConstraintChecker right = createChecker(types, schemata, columns, orConstraint.right(), variables); return new ConstraintChecker() { @Override public boolean satisfiesConstraints(Object[] tuple) { return left.satisfiesConstraints(tuple) || right.satisfiesConstraints(tuple); } }; } if (constraint instanceof Not) { Not notConstraint = (Not) constraint; final ConstraintChecker original = createChecker(types, schemata, columns, notConstraint.getConstraint(), variables); return new ConstraintChecker() { @Override public boolean satisfiesConstraints(Object[] tuple) { return !original.satisfiesConstraints(tuple); } }; } if (constraint instanceof And) { And andConstraint = (And) constraint; final ConstraintChecker left = createChecker(types, schemata, columns, andConstraint.left(), variables); final ConstraintChecker right = createChecker(types, schemata, columns, andConstraint.right(), variables); return new ConstraintChecker() { @Override public boolean satisfiesConstraints(Object[] tuple) { return left.satisfiesConstraints(tuple) && right.satisfiesConstraints(tuple); } }; } if (constraint instanceof ChildNode) { ChildNode childConstraint = (ChildNode) constraint; final int locationIndex = columns.getLocationIndex(childConstraint.selectorName().name()); final Path parentPath = (Path) types.getPathFactory().create(childConstraint.getParentPath()); return new ConstraintChecker() { @Override public boolean satisfiesConstraints(Object[] tuple) { Location location = (Location) tuple[locationIndex]; return location.getPath().getParent().equals(parentPath); } }; } if (constraint instanceof DescendantNode) { DescendantNode descendantNode = (DescendantNode) constraint; final int locationIndex = columns.getLocationIndex(descendantNode.selectorName().name()); final Path ancestorPath = (Path) types.getPathFactory().create(descendantNode.getAncestorPath()); return new ConstraintChecker() { @Override public boolean satisfiesConstraints(Object[] tuple) { Location location = (Location) tuple[locationIndex]; return location.getPath().isDescendantOf(ancestorPath); } }; } if (constraint instanceof SameNode) { SameNode sameNode = (SameNode) constraint; final int locationIndex = columns.getLocationIndex(sameNode.selectorName().name()); final String path = sameNode.getPath(); return new ConstraintChecker() { @Override public boolean satisfiesConstraints(Object[] tuple) { Location location = (Location) tuple[locationIndex]; return location.toString().equals(path); } }; } if (constraint instanceof PropertyExistence) { PropertyExistence propertyExistance = (PropertyExistence) constraint; String selectorName = propertyExistance.selectorName().name(); final String propertyName = propertyExistance.getPropertyName(); final int columnIndex = columns.getColumnIndexForProperty(selectorName, propertyName); return new ConstraintChecker() { @Override public boolean satisfiesConstraints(Object[] tuple) { return tuple[columnIndex] != null; } }; } if (constraint instanceof FullTextSearch) { return new ConstraintChecker() { @Override public boolean satisfiesConstraints(Object[] tuple) { return true; } }; } if (constraint instanceof Relike) { return new ConstraintChecker() { @Override public boolean satisfiesConstraints(Object[] tuple) { return true; } }; } if (constraint instanceof Comparison) { Comparison comparison = (Comparison) constraint; // Create the correct dynamic operation ... DynamicOperation dynamicOperation = createDynamicOperation(types, schemata, columns, comparison.getOperand1()); Operator operator = comparison.operator(); StaticOperand staticOperand = comparison.getOperand2(); return createChecker(types, schemata, columns, dynamicOperation, operator, staticOperand); } if (constraint instanceof SetCriteria) { SetCriteria setCriteria = (SetCriteria) constraint; DynamicOperation dynamicOperation = createDynamicOperation(types, schemata, columns, setCriteria.leftOperand()); Operator operator = Operator.EQUAL_TO; final List<ConstraintChecker> checkers = new LinkedList<ConstraintChecker>(); for (StaticOperand setValue : setCriteria.rightOperands()) { ConstraintChecker rightChecker = createChecker(types, schemata, columns, dynamicOperation, operator, setValue); assert rightChecker != null; checkers.add(rightChecker); } if (checkers.isEmpty()) { // Nothing will satisfy these constraints ... return new ConstraintChecker() { @Override public boolean satisfiesConstraints(Object[] tuple) { return false; } }; } return new ConstraintChecker() { @Override public boolean satisfiesConstraints(Object[] tuple) { for (ConstraintChecker checker : checkers) { if (checker.satisfiesConstraints(tuple)) return true; } return false; } }; } assert false; return null; }