*/
@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;
}