throw new InvalidQueryException(query, "An absolute path expression must start with '//' or '/jcr:root/...'");
}
}
// Walk the steps along the path expression ...
ConstraintBuilder where = builder.where();
List<StepExpression> path = new ArrayList<StepExpression>();
String tableName = null;
for (StepExpression step : steps) {
if (step instanceof AxisStep) {
AxisStep axis = (AxisStep)step;
NodeTest nodeTest = axis.getNodeTest();
if (nodeTest instanceof NameTest) {
if (appliesToPathConstraint(axis.getPredicates())) {
// Everything in this axis/step applies to the path, so add it and we'll translate it below ...
path.add(step);
} else {
// The constraints are more complicated than can be applied to the path ...
// if (!nameTest.isWildcard()) {
// There is a non-wildcard name test that we still need to add to the path ...
path.add(step);
// }
// We need to define a new source/table ...
tableName = translateSource(tableName, path, where);
translatePredicates(axis.getPredicates(), tableName, where);
path.clear();
}
} else if (nodeTest instanceof ElementTest) {
// We need to build a new source with the partial path we have so far ...
tableName = translateElementTest((ElementTest)nodeTest, path, where);
translatePredicates(axis.getPredicates(), tableName, where);
path.clear();
} else if (nodeTest instanceof AttributeNameTest) {
AttributeNameTest attributeName = (AttributeNameTest)nodeTest;
builder.select(nameFrom(attributeName.getNameTest()));
} else if (nodeTest instanceof TextTest) {
NameTest nameTest = new NameTest("jcr", "xmltext");
List<Component> predicates = axis.getPredicates();
if (predicates == null || predicates.isEmpty() || appliesToPathConstraint(predicates)) {
AxisStep textStep = new AxisStep(nameTest, axis.getPredicates());
path.add(textStep);
} else {
tableName = translateSource(tableName, path, where);
translatePredicates(predicates, tableName, where);
path.clear();
}
} else {
throw new InvalidQueryException(query, "The '" + step + "' step is not supported");
}
} else if (step instanceof FilterStep) {
FilterStep filter = (FilterStep)step;
Component primary = filter.getPrimaryExpression();
List<Component> predicates = filter.getPredicates();
if (primary instanceof ContextItem) {
if (appliesToPathConstraint(predicates)) {
// Can ignore the '.' ...
} else {
// The constraints are more complicated, so we need to define a new source/table ...
path.add(step);
tableName = translateSource(tableName, path, where);
translatePredicates(predicates, tableName, where);
path.clear();
}
} else if (primary instanceof Literal) {
throw new InvalidQueryException(query,
"A literal is not supported in the primary path expression; therefore '"
+ primary + "' is not valid");
} else if (primary instanceof FunctionCall) {
throw new InvalidQueryException(query,
"A function call is not supported in the primary path expression; therefore '"
+ primary + "' is not valid");
} else if (primary instanceof ParenthesizedExpression) {
// This can be used to define an OR-ed set of expressions defining select columns ...
ParenthesizedExpression paren = (ParenthesizedExpression)primary;
Component wrapped = paren.getWrapped().collapse();
if (wrapped instanceof AttributeNameTest) {
AttributeNameTest attributeName = (AttributeNameTest)wrapped;
builder.select(nameFrom(attributeName.getNameTest()));
} else if (wrapped instanceof BinaryComponent) {
for (AttributeNameTest attributeName : extractAttributeNames((BinaryComponent)wrapped)) {
builder.select(nameFrom(attributeName.getNameTest()));
}
path.add(filter); // in case any element names are there
} else {
throw new InvalidQueryException(query,
"A parenthesized expression of this type is not supported in the primary path expression; therefore '"
+ primary + "' is not valid");
}
}
} else {
path.add(step);
}
}
if (steps.isEmpty() || !path.isEmpty()) {
translateSource(tableName, path, where);
}
where.end();
// Process the order-by clause ...
OrderBy orderBy = pathExpression.getOrderBy();
if (orderBy != null) {
OrderByBuilder orderByBuilder = builder.orderBy();