X-Git-Url: https://git.mdrn.pl/pylucene.git/blobdiff_plain/a2e61f0c04805cfcb8706176758d1283c7e3a55c..aaeed5504b982cf3545252ab528713250aa33eed:/lucene-java-3.5.0/lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/processors/GroupQueryNodeProcessor.java?ds=sidebyside diff --git a/lucene-java-3.5.0/lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/processors/GroupQueryNodeProcessor.java b/lucene-java-3.5.0/lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/processors/GroupQueryNodeProcessor.java new file mode 100644 index 0000000..866cd4a --- /dev/null +++ b/lucene-java-3.5.0/lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/processors/GroupQueryNodeProcessor.java @@ -0,0 +1,218 @@ +package org.apache.lucene.queryParser.standard.processors; + +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.util.ArrayList; +import java.util.List; + +import org.apache.lucene.queryParser.core.QueryNodeException; +import org.apache.lucene.queryParser.core.config.QueryConfigHandler; +import org.apache.lucene.queryParser.core.nodes.AndQueryNode; +import org.apache.lucene.queryParser.core.nodes.BooleanQueryNode; +import org.apache.lucene.queryParser.core.nodes.GroupQueryNode; +import org.apache.lucene.queryParser.core.nodes.ModifierQueryNode; +import org.apache.lucene.queryParser.core.nodes.OrQueryNode; +import org.apache.lucene.queryParser.core.nodes.QueryNode; +import org.apache.lucene.queryParser.core.nodes.ModifierQueryNode.Modifier; +import org.apache.lucene.queryParser.core.parser.SyntaxParser; +import org.apache.lucene.queryParser.core.processors.QueryNodeProcessor; +import org.apache.lucene.queryParser.standard.config.StandardQueryConfigHandler; +import org.apache.lucene.queryParser.standard.config.StandardQueryConfigHandler.ConfigurationKeys; +import org.apache.lucene.queryParser.standard.config.StandardQueryConfigHandler.Operator; +import org.apache.lucene.queryParser.standard.nodes.BooleanModifierNode; + +/** + * The {@link SyntaxParser} + * generates query node trees that consider the boolean operator precedence, but + * Lucene current syntax does not support boolean precedence, so this processor + * remove all the precedence and apply the equivalent modifier according to the + * boolean operation defined on an specific query node.
+ *
+ * If there is a {@link GroupQueryNode} in the query node tree, the query node + * tree is not merged with the one above it. + * + * Example: TODO: describe a good example to show how this processor works + * + * @see org.apache.lucene.queryParser.standard.config.StandardQueryConfigHandler + */ +public class GroupQueryNodeProcessor implements QueryNodeProcessor { + + private ArrayList queryNodeList; + + private boolean latestNodeVerified; + + private QueryConfigHandler queryConfig; + + private Boolean usingAnd = false; + + public GroupQueryNodeProcessor() { + // empty constructor + } + + public QueryNode process(QueryNode queryTree) throws QueryNodeException { + Operator defaultOperator = getQueryConfigHandler().get(ConfigurationKeys.DEFAULT_OPERATOR); + + if (defaultOperator == null) { + throw new IllegalArgumentException( + "DEFAULT_OPERATOR should be set on the QueryConfigHandler"); + } + + this.usingAnd = StandardQueryConfigHandler.Operator.AND == defaultOperator; + + if (queryTree instanceof GroupQueryNode) { + queryTree = ((GroupQueryNode) queryTree).getChild(); + } + + this.queryNodeList = new ArrayList(); + this.latestNodeVerified = false; + readTree(queryTree); + + List actualQueryNodeList = this.queryNodeList; + + for (int i = 0; i < actualQueryNodeList.size(); i++) { + QueryNode node = actualQueryNodeList.get(i); + + if (node instanceof GroupQueryNode) { + actualQueryNodeList.set(i, process(node)); + } + + } + + this.usingAnd = false; + + if (queryTree instanceof BooleanQueryNode) { + queryTree.set(actualQueryNodeList); + + return queryTree; + + } else { + return new BooleanQueryNode(actualQueryNodeList); + } + + } + + /** + */ + private QueryNode applyModifier(QueryNode node, QueryNode parent) { + + if (this.usingAnd) { + + if (parent instanceof OrQueryNode) { + + if (node instanceof ModifierQueryNode) { + + ModifierQueryNode modNode = (ModifierQueryNode) node; + + if (modNode.getModifier() == Modifier.MOD_REQ) { + return modNode.getChild(); + } + + } + + } else { + + if (node instanceof ModifierQueryNode) { + + ModifierQueryNode modNode = (ModifierQueryNode) node; + + if (modNode.getModifier() == Modifier.MOD_NONE) { + return new BooleanModifierNode(modNode.getChild(), Modifier.MOD_REQ); + } + + } else { + return new BooleanModifierNode(node, Modifier.MOD_REQ); + } + + } + + } else { + + if (node.getParent() instanceof AndQueryNode) { + + if (node instanceof ModifierQueryNode) { + + ModifierQueryNode modNode = (ModifierQueryNode) node; + + if (modNode.getModifier() == Modifier.MOD_NONE) { + return new BooleanModifierNode(modNode.getChild(), Modifier.MOD_REQ); + } + + } else { + return new BooleanModifierNode(node, Modifier.MOD_REQ); + } + + } + + } + + return node; + + } + + private void readTree(QueryNode node) { + + if (node instanceof BooleanQueryNode) { + List children = node.getChildren(); + + if (children != null && children.size() > 0) { + + for (int i = 0; i < children.size() - 1; i++) { + readTree(children.get(i)); + } + + processNode(node); + readTree(children.get(children.size() - 1)); + + } else { + processNode(node); + } + + } else { + processNode(node); + } + + } + + private void processNode(QueryNode node) { + + if (node instanceof AndQueryNode || node instanceof OrQueryNode) { + + if (!this.latestNodeVerified && !this.queryNodeList.isEmpty()) { + this.queryNodeList.add(applyModifier(this.queryNodeList + .remove(this.queryNodeList.size() - 1), node)); + this.latestNodeVerified = true; + + } + + } else if (!(node instanceof BooleanQueryNode)) { + this.queryNodeList.add(applyModifier(node, node.getParent())); + this.latestNodeVerified = false; + + } + + } + + public QueryConfigHandler getQueryConfigHandler() { + return this.queryConfig; + } + + public void setQueryConfigHandler(QueryConfigHandler queryConfigHandler) { + this.queryConfig = queryConfigHandler; + } + +}