add --shared
[pylucene.git] / lucene-java-3.4.0 / lucene / contrib / queryparser / src / java / org / apache / lucene / queryParser / precedence / processors / BooleanModifiersQueryNodeProcessor.java
1 package org.apache.lucene.queryParser.precedence.processors;
2
3 /**
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
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  */
19
20 import java.util.ArrayList;
21 import java.util.List;
22
23 import org.apache.lucene.queryParser.core.QueryNodeException;
24 import org.apache.lucene.queryParser.core.nodes.AndQueryNode;
25 import org.apache.lucene.queryParser.core.nodes.BooleanQueryNode;
26 import org.apache.lucene.queryParser.core.nodes.ModifierQueryNode;
27 import org.apache.lucene.queryParser.core.nodes.OrQueryNode;
28 import org.apache.lucene.queryParser.core.nodes.QueryNode;
29 import org.apache.lucene.queryParser.core.nodes.ModifierQueryNode.Modifier;
30 import org.apache.lucene.queryParser.core.processors.QueryNodeProcessorImpl;
31 import org.apache.lucene.queryParser.precedence.PrecedenceQueryParser;
32 import org.apache.lucene.queryParser.standard.config.StandardQueryConfigHandler;
33 import org.apache.lucene.queryParser.standard.config.StandardQueryConfigHandler.ConfigurationKeys;
34 import org.apache.lucene.queryParser.standard.config.StandardQueryConfigHandler.Operator;
35
36 /**
37  * <p>
38  * This processor is used to apply the correct {@link ModifierQueryNode} to {@link BooleanQueryNode}s children.
39  * </p>
40  * <p>
41  * It walks through the query node tree looking for {@link BooleanQueryNode}s. If an {@link AndQueryNode} is found,
42  * every child, which is not a {@link ModifierQueryNode} or the {@link ModifierQueryNode} 
43  * is {@link Modifier#MOD_NONE}, becomes a {@link Modifier#MOD_REQ}. For any other
44  * {@link BooleanQueryNode} which is not an {@link OrQueryNode}, it checks the default operator is {@link Operator#AND},
45  * if it is, the same operation when an {@link AndQueryNode} is found is applied to it.
46  * </p>
47  * 
48  * @see ConfigurationKeys#DEFAULT_OPERATOR
49  * @see PrecedenceQueryParser#setDefaultOperator
50  */
51 public class BooleanModifiersQueryNodeProcessor extends QueryNodeProcessorImpl {
52
53   private ArrayList<QueryNode> childrenBuffer = new ArrayList<QueryNode>();
54
55   private Boolean usingAnd = false;
56
57   public BooleanModifiersQueryNodeProcessor() {
58     // empty constructor
59   }
60
61   @Override
62   public QueryNode process(QueryNode queryTree) throws QueryNodeException {
63     Operator op = getQueryConfigHandler().get(ConfigurationKeys.DEFAULT_OPERATOR);
64     
65     if (op == null) {
66       throw new IllegalArgumentException(
67           "StandardQueryConfigHandler.ConfigurationKeys.DEFAULT_OPERATOR should be set on the QueryConfigHandler");
68     }
69
70     this.usingAnd = StandardQueryConfigHandler.Operator.AND == op;
71
72     return super.process(queryTree);
73
74   }
75
76   @Override
77   protected QueryNode postProcessNode(QueryNode node) throws QueryNodeException {
78
79     if (node instanceof AndQueryNode) {
80       this.childrenBuffer.clear();
81       List<QueryNode> children = node.getChildren();
82
83       for (QueryNode child : children) {
84         this.childrenBuffer.add(applyModifier(child, Modifier.MOD_REQ));
85       }
86
87       node.set(this.childrenBuffer);
88
89     } else if (this.usingAnd && node instanceof BooleanQueryNode
90         && !(node instanceof OrQueryNode)) {
91
92       this.childrenBuffer.clear();
93       List<QueryNode> children = node.getChildren();
94
95       for (QueryNode child : children) {
96         this.childrenBuffer.add(applyModifier(child, Modifier.MOD_REQ));
97       }
98
99       node.set(this.childrenBuffer);
100
101     }
102
103     return node;
104
105   }
106
107   private QueryNode applyModifier(QueryNode node, Modifier mod) {
108
109     // check if modifier is not already defined and is default
110     if (!(node instanceof ModifierQueryNode)) {
111       return new ModifierQueryNode(node, mod);
112
113     } else {
114       ModifierQueryNode modNode = (ModifierQueryNode) node;
115
116       if (modNode.getModifier() == Modifier.MOD_NONE) {
117         return new ModifierQueryNode(modNode.getChild(), mod);
118       }
119
120     }
121
122     return node;
123
124   }
125
126   @Override
127   protected QueryNode preProcessNode(QueryNode node) throws QueryNodeException {
128     return node;
129   }
130
131   @Override
132   protected List<QueryNode> setChildrenOrder(List<QueryNode> children)
133       throws QueryNodeException {
134
135     return children;
136
137   }
138
139 }