1
2 package org.galagosearch.core.retrieval.traversal;
3
4 import java.util.ArrayList;
5 import org.galagosearch.core.retrieval.query.Node;
6 import org.galagosearch.core.retrieval.query.NodeType;
7 import org.galagosearch.core.retrieval.query.Traversal;
8 import org.galagosearch.core.retrieval.structured.CountIterator;
9 import org.galagosearch.core.retrieval.structured.ScoreIterator;
10 import org.galagosearch.core.retrieval.structured.StructuredRetrieval;
11
12 /***
13 * For many kinds of queries, it may be preferable to not have to type
14 * an explicit #feature operator around a count or extents term. For example,
15 * we want #combine(#feature:dirichlet(#counts:dog())) to be the same as
16 * #combine(dog). This transformation automatically adds the #feature:dirichlet
17 * operator.
18 *
19 * @author trevor
20 */
21 public class ImplicitFeatureCastTraversal implements Traversal {
22 StructuredRetrieval retrieval;
23
24 public ImplicitFeatureCastTraversal(StructuredRetrieval retrieval) {
25 this.retrieval = retrieval;
26 }
27
28 Node createSmoothingNode(Node child) {
29 ArrayList<Node> data = new ArrayList<Node>();
30 data.add(child);
31 return new Node("feature", "dirichlet", data, child.getPosition());
32 }
33
34 public boolean isCountNode(Node node) throws Exception {
35 NodeType nodeType = retrieval.getNodeType(node);
36 if (nodeType == null) return false;
37 Class outputClass = nodeType.getIteratorClass();
38 return CountIterator.class.isAssignableFrom(outputClass);
39 }
40
41 public void beforeNode(Node node) throws Exception {
42 }
43
44 public Node afterNode(Node node) throws Exception {
45 ArrayList<Node> newChildren = new ArrayList<Node>();
46 NodeType nodeType = retrieval.getNodeType(node);
47 if (nodeType == null) return node;
48 ArrayList<Node> children = node.getInternalNodes();
49
50
51 Class[] types = nodeType.getParameterTypes(children.size() + 1);
52 if (types == null) return node;
53
54 for (int i = 1; i < types.length; ++i) {
55 Node child = children.get(i-1);
56
57
58 if (ScoreIterator.class.isAssignableFrom(types[i]) &&
59 isCountNode(children.get(i-1))) {
60 Node feature = createSmoothingNode(child);
61 newChildren.add(feature);
62 } else {
63 newChildren.add(child);
64 }
65 }
66
67 return new Node(node.getOperator(), node.getParameters(),
68 newChildren, node.getPosition());
69 }
70 }