package org.apache.lucene.queryparser.flexible.aqp.nodes; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; import org.apache.lucene.queryparser.flexible.aqp.builders.AqpFunctionQueryBuilder; import org.apache.lucene.queryparser.flexible.aqp.processors.AqpQProcessor; import org.apache.lucene.queryparser.flexible.aqp.processors.AqpQProcessor.OriginalInput; import org.apache.lucene.queryparser.flexible.core.builders.QueryBuilder; import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.QueryNodeImpl; import org.apache.lucene.queryparser.flexible.core.parser.EscapeQuerySyntax; import org.apache.lucene.queryparser.flexible.standard.parser.ParseException; /** * This QNode receives all the children of the QFUNC node, so typically * QFUNC * | * / \ * fName DEFOP * | * COMMA * | * / | \ * ... MODIFIER ... * | * TMODIFIER * | * FIELD * | * Q:node * | * value * * This node carries within itself a 'builder' which is responsible for * turning the node into a Query at *build* time. Ie. after the processors * finished running (that is the step 2). * * @author rchyla * */ public class AqpFunctionQueryNode extends QueryNodeImpl implements QueryNode { private static final long serialVersionUID = 751068795564006998L; private AqpFunctionQueryBuilder builder = null; private String name = null; private OriginalInput originalInput = null; private List<OriginalInput> funcValues; private Set<String> nodesToCount = new HashSet<String>(Arrays.asList("QRANGEIN", "QRANGEEX", "QFUNC")); public AqpFunctionQueryNode(String name, AqpFunctionQueryBuilder builder, List<OriginalInput> values) throws ParseException { allocate(); setLeaf(true); originalInput = values.get(0); funcValues = values; this.builder = builder; this.name = name; } public AqpFunctionQueryNode(String name, AqpFunctionQueryBuilder builder, AqpANTLRNode node) throws ParseException { allocate(); setLeaf(true); originalInput = AqpQProcessor.getOriginalInput(node, nodesToCount); funcValues = new ArrayList<OriginalInput>(); if (!node.isLeaf()) { AqpANTLRNode container = new AqpANTLRNode(node.getTree()); ArrayList<QueryNode> children = new ArrayList<QueryNode>(); for (QueryNode n: node.getChildren()) { int l = ((AqpANTLRNode) n).hasTokenName("QDELIMITER", 0); if (l > 0 && l < 4) { // MODIFIER/TMODIFIER/FIELD/QDELIMITER container.set(children); funcValues.add(AqpQProcessor.getOriginalInput((AqpANTLRNode) container, nodesToCount)); children.clear(); continue; } else { children.add(n); } } if (children.size() > 0) { container.set(children); funcValues.add(AqpQProcessor.getOriginalInput((AqpANTLRNode) container, nodesToCount)); children.clear(); } } else { funcValues.add(AqpQProcessor.getOriginalInput((AqpANTLRNode) node, nodesToCount)); } this.builder = builder; this.name = name; trimValues(); } public AqpFunctionQueryNode(String funcName, AqpFunctionQueryBuilder builder, OriginalInput origInput, ArrayList<OriginalInput> values) { allocate(); setLeaf(true); this.originalInput = origInput; funcValues = values; this.name = funcName; this.builder = builder; trimValues(); } public String toString() { StringBuffer bo = new StringBuffer(); bo.append("<function name=\""); bo.append(this.name == null ? getBuilder().getClass() : this.name); bo.append("\" originalInput=\"" + originalInput + "\""); bo.append("\">\n"); for (OriginalInput child: this.getFuncValues()) { bo.append("<funcValue>" + child.toString() + "</funcValue>\n"); } bo.append("</function>"); return bo.toString(); } private void trimValues() { for (OriginalInput oi: funcValues) { oi.value = oi.value.trim(); } } public QueryNode getChild() { return getChildren().get(0); } public CharSequence toQueryString(EscapeQuerySyntax escapeSyntaxParser) { return getBuilder().toString(); } public QueryBuilder getBuilder() { return builder; } public String getName() { return name; } public Boolean canBeAnalyzed() { return false; } public List<OriginalInput> getFuncValues() { return funcValues; } public OriginalInput getOriginalInput() { return originalInput; } }