深入浅出 jackrabbit 十三 查询之AST和QT
2009-09-17 00:00:00 来源:WEB开发网它的实现类中需要定义每一种QueryNode的处理逻辑,显然和SimpleNode的XPathVisitor有一点不一样,因为在 XPathVisitor中,是通过switch来决定如何处理node的,而这里变成了多个方法来处理,看上去更加直观,只是如果再加一个 QueryNode的子类,那么接口就需要改动(从这一点来看vistor比较适合数据结构不易变更的场景,比如asm中,字节码结构一般是不会变更的,所以用visitor模式是比较适合的),不过总的来说,SimpleNode和XpathVisitor的关系就如同QueryNode和 QueryNodeVisitor一样,连续两个关键步骤都使用了visitor模式。
看过接口之后,就是看它的主实现类,LuceneQueryBuilder,这个类相当重要,所有的query对象就是在这个类中构造出来的,很显然,构造query对象所需要的条件就藏在QT中。我们只要稍稍的查看一个方法,就可以得到证据:
Java代码
public Object visit(QueryRootNode node, Object data) {
BooleanQuery root = new BooleanQuery();
Query wrapped = root;
if (node.getLocationNode() != null) {
wrapped = (Query) node.getLocationNode().accept(this, root);
}
return wrapped;
}
显然,从这段代码里,开始了便利QT的旅程,因为QueryRootNode是QT的root,所以这里也是自顶向下遍历,比如,在创建了root之后,接着去处理QT上的LocationNode(也就是PathQueryNode节点),于是方法就跳到了:
Java代码
public Object visit(PathQueryNode node, Object data) {
Query context = null;
LocationStepQueryNode[] steps = node.getPathSteps();
if (steps.length > 0) {
if (node.isAbsolute() && !steps[0].getIncludeDescendants()) {
// eat up first step
Name nameTest = steps[0].getNameTest();
if (nameTest == null) {
// this is equivalent to the root node
context = new TermQuery(new Term(FieldNames.PARENT, ""));
} else if (nameTest.getLocalName().length() == 0) {
// root node
context = new TermQuery(new Term(FieldNames.PARENT, ""));
} else {
// then this is a node != the root node
// will never match anything!
String name = "";
try {
name = resolver.getJCRName(nameTest);
} catch (NamespaceException e) {
exceptions.add(e);
}
BooleanQuery and = new BooleanQuery();
and.add(new TermQuery(new Term(FieldNames.PARENT, "")), Occur.MUST);
and.add(new TermQuery(new Term(FieldNames.LABEL, name)), Occur.MUST);
context = and;
}
LocationStepQueryNode[] tmp = new LocationStepQueryNode[steps.length - 1];
System.arraycopy(steps, 1, tmp, 0, steps.length - 1);
steps = tmp;
} else {
// path is 1) relative or 2) descendant-or-self
// use root node as context
context = new TermQuery(new Term(FieldNames.PARENT, ""));
}
} else {
exceptions.add(new InvalidQueryException("Number of location steps must be > 0"));
}
// loop over steps
for (int i = 0; i < steps.length; i++) {
context = (Query) steps[i].accept(this, context);
}
if (data instanceof BooleanQuery) {
BooleanQuery constraint = (BooleanQuery) data;
if (constraint.getClauses().length > 0) {
constraint.add(context, Occur.MUST);
context = constraint;
}
}
return context;
}
Tags:深入浅出 jackrabbit 十三
编辑录入:爽爽 [复制链接] [打 印]更多精彩
赞助商链接