1 package org.apache.lucene.queryParser.standard.processors;
4 * Licensed to the Apache Software Foundation (ASF) under one or more
5 * contributor license agreements. See the NOTICE file distributed with
6 * this work for additional information regarding copyright ownership.
7 * The ASF licenses this file to You under the Apache License, Version 2.0
8 * (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
20 import java.util.ArrayList;
21 import java.util.List;
23 import org.apache.lucene.queryParser.core.QueryNodeException;
24 import org.apache.lucene.queryParser.core.config.QueryConfigHandler;
25 import org.apache.lucene.queryParser.core.nodes.AndQueryNode;
26 import org.apache.lucene.queryParser.core.nodes.BooleanQueryNode;
27 import org.apache.lucene.queryParser.core.nodes.GroupQueryNode;
28 import org.apache.lucene.queryParser.core.nodes.ModifierQueryNode;
29 import org.apache.lucene.queryParser.core.nodes.OrQueryNode;
30 import org.apache.lucene.queryParser.core.nodes.QueryNode;
31 import org.apache.lucene.queryParser.core.nodes.ModifierQueryNode.Modifier;
32 import org.apache.lucene.queryParser.core.parser.SyntaxParser;
33 import org.apache.lucene.queryParser.core.processors.QueryNodeProcessor;
34 import org.apache.lucene.queryParser.standard.config.StandardQueryConfigHandler;
35 import org.apache.lucene.queryParser.standard.config.StandardQueryConfigHandler.ConfigurationKeys;
36 import org.apache.lucene.queryParser.standard.config.StandardQueryConfigHandler.Operator;
37 import org.apache.lucene.queryParser.standard.nodes.BooleanModifierNode;
40 * The {@link SyntaxParser}
41 * generates query node trees that consider the boolean operator precedence, but
42 * Lucene current syntax does not support boolean precedence, so this processor
43 * remove all the precedence and apply the equivalent modifier according to the
44 * boolean operation defined on an specific query node. <br/>
46 * If there is a {@link GroupQueryNode} in the query node tree, the query node
47 * tree is not merged with the one above it.
49 * Example: TODO: describe a good example to show how this processor works
51 * @see org.apache.lucene.queryParser.standard.config.StandardQueryConfigHandler
53 public class GroupQueryNodeProcessor implements QueryNodeProcessor {
55 private ArrayList<QueryNode> queryNodeList;
57 private boolean latestNodeVerified;
59 private QueryConfigHandler queryConfig;
61 private Boolean usingAnd = false;
63 public GroupQueryNodeProcessor() {
67 public QueryNode process(QueryNode queryTree) throws QueryNodeException {
68 Operator defaultOperator = getQueryConfigHandler().get(ConfigurationKeys.DEFAULT_OPERATOR);
70 if (defaultOperator == null) {
71 throw new IllegalArgumentException(
72 "DEFAULT_OPERATOR should be set on the QueryConfigHandler");
75 this.usingAnd = StandardQueryConfigHandler.Operator.AND == defaultOperator;
77 if (queryTree instanceof GroupQueryNode) {
78 queryTree = ((GroupQueryNode) queryTree).getChild();
81 this.queryNodeList = new ArrayList<QueryNode>();
82 this.latestNodeVerified = false;
85 List<QueryNode> actualQueryNodeList = this.queryNodeList;
87 for (int i = 0; i < actualQueryNodeList.size(); i++) {
88 QueryNode node = actualQueryNodeList.get(i);
90 if (node instanceof GroupQueryNode) {
91 actualQueryNodeList.set(i, process(node));
96 this.usingAnd = false;
98 if (queryTree instanceof BooleanQueryNode) {
99 queryTree.set(actualQueryNodeList);
104 return new BooleanQueryNode(actualQueryNodeList);
111 private QueryNode applyModifier(QueryNode node, QueryNode parent) {
115 if (parent instanceof OrQueryNode) {
117 if (node instanceof ModifierQueryNode) {
119 ModifierQueryNode modNode = (ModifierQueryNode) node;
121 if (modNode.getModifier() == Modifier.MOD_REQ) {
122 return modNode.getChild();
129 if (node instanceof ModifierQueryNode) {
131 ModifierQueryNode modNode = (ModifierQueryNode) node;
133 if (modNode.getModifier() == Modifier.MOD_NONE) {
134 return new BooleanModifierNode(modNode.getChild(), Modifier.MOD_REQ);
138 return new BooleanModifierNode(node, Modifier.MOD_REQ);
145 if (node.getParent() instanceof AndQueryNode) {
147 if (node instanceof ModifierQueryNode) {
149 ModifierQueryNode modNode = (ModifierQueryNode) node;
151 if (modNode.getModifier() == Modifier.MOD_NONE) {
152 return new BooleanModifierNode(modNode.getChild(), Modifier.MOD_REQ);
156 return new BooleanModifierNode(node, Modifier.MOD_REQ);
167 private void readTree(QueryNode node) {
169 if (node instanceof BooleanQueryNode) {
170 List<QueryNode> children = node.getChildren();
172 if (children != null && children.size() > 0) {
174 for (int i = 0; i < children.size() - 1; i++) {
175 readTree(children.get(i));
179 readTree(children.get(children.size() - 1));
191 private void processNode(QueryNode node) {
193 if (node instanceof AndQueryNode || node instanceof OrQueryNode) {
195 if (!this.latestNodeVerified && !this.queryNodeList.isEmpty()) {
196 this.queryNodeList.add(applyModifier(this.queryNodeList
197 .remove(this.queryNodeList.size() - 1), node));
198 this.latestNodeVerified = true;
202 } else if (!(node instanceof BooleanQueryNode)) {
203 this.queryNodeList.add(applyModifier(node, node.getParent()));
204 this.latestNodeVerified = false;
210 public QueryConfigHandler getQueryConfigHandler() {
211 return this.queryConfig;
214 public void setQueryConfigHandler(QueryConfigHandler queryConfigHandler) {
215 this.queryConfig = queryConfigHandler;