return context;
}
public Object visit(LocationStepQueryNode node, Object data) {
Query context = (Query) data;
BooleanQuery andQuery = new BooleanQuery();
if (context == null) {
exceptions.add(new IllegalArgumentException("Unsupported query"));
}
// predicate on step?
Object[] predicates = node.acceptOperands(this, data);
for (int i = 0; i < predicates.length; i++) {
andQuery.add((Query) predicates[i], Occur.MUST);
}
// check for position predicate
QueryNode[] pred = node.getPredicates();
for (int i = 0; i < pred.length; i++) {
if (pred[i].getType() == QueryNode.TYPE_RELATION) {
RelationQueryNode pos = (RelationQueryNode) pred[i];
if (pos.getValueType() == QueryConstants.TYPE_POSITION) {
node.setIndex(pos.getPositionValue());
}
}
}
TermQuery nameTest = null;
if (node.getNameTest() != null) {
try {
String internalName = NameFormat.format(node.getNameTest(), nsMappings);
nameTest = new TermQuery(new Term(FieldNames.LABEL, internalName));
} catch (NoPrefixDeclaredException e) {
// should never happen
exceptions.add(e);
}
}
if (node.getIncludeDescendants()) {
if (nameTest != null) {
andQuery.add(new DescendantSelfAxisQuery(context, nameTest), Occur.MUST);
} else {
// descendant-or-self with nametest=*
if (predicates.length > 0) {
// if we have a predicate attached, the condition acts as
// the sub query.
// only use descendant axis if path is not //*
// otherwise the query for the predicate can be used itself
PathQueryNode pathNode = (PathQueryNode) node.getParent();
if (pathNode.getPathSteps()[0] != node) {
Query subQuery = new DescendantSelfAxisQuery(context, andQuery, false);
andQuery = new BooleanQuery();
andQuery.add(subQuery, Occur.MUST);
}
} else {
// todo this will traverse the whole index, optimize!
Query subQuery = null;
try {
subQuery = new MatchAllQuery(NameFormat.format(QName.JCR_PRIMARYTYPE, nsMappings));
} catch (NoPrefixDeclaredException e) {
// will never happen, prefixes are created when unknown
}
// only use descendant axis if path is not //*
PathQueryNode pathNode = (PathQueryNode) node.getParent();
if (pathNode.getPathSteps()[0] != node) {
context = new DescendantSelfAxisQuery(context, subQuery);
andQuery.add(new ChildAxisQuery(sharedItemMgr, context, null, node.getIndex()), Occur.MUST);
} else {
andQuery.add(subQuery, Occur.MUST);
}
}
}
} else {
// name test
if (nameTest != null) {
andQuery.add(new ChildAxisQuery(sharedItemMgr, context, nameTest.getTerm().text(), node.getIndex()), Occur.MUST);
} else {
// select child nodes
andQuery.add(new ChildAxisQuery(sharedItemMgr, context, null, node.getIndex()), Occur.MUST);
}
}
return andQuery;
}