1 package org.apache.lucene.queryParser.core.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.QueryNode;
29 * This is a default implementation for the {@link QueryNodeProcessor}
30 * interface, it's an abstract class, so it should be extended by classes that
31 * want to process a {@link QueryNode} tree.
34 * This class process {@link QueryNode}s from left to right in the tree. While
35 * it's walking down the tree, for every node,
36 * {@link #preProcessNode(QueryNode)} is invoked. After a node's children are
37 * processed, {@link #postProcessNode(QueryNode)} is invoked for that node.
38 * {@link #setChildrenOrder(List)} is invoked before
39 * {@link #postProcessNode(QueryNode)} only if the node has at least one child,
40 * in {@link #setChildrenOrder(List)} the implementor might redefine the
41 * children order or remove any children from the children list.
44 * Here is an example about how it process the nodes:
55 * Here is the order the methods would be invoked for the tree described above:
58 * preProcessNode( a );
59 * preProcessNode( b );
60 * preProcessNode( c );
61 * postProcessNode( c );
62 * preProcessNode( d );
63 * postProcessNode( d );
64 * setChildrenOrder( bChildrenList );
65 * postProcessNode( b );
66 * preProcessNode( e );
67 * postProcessNode( e );
68 * setChildrenOrder( aChildrenList );
69 * postProcessNode( a )
72 * @see org.apache.lucene.queryParser.core.processors.QueryNodeProcessor
74 public abstract class QueryNodeProcessorImpl implements QueryNodeProcessor {
76 private ArrayList<ChildrenList> childrenListPool = new ArrayList<ChildrenList>();
78 private QueryConfigHandler queryConfig;
80 public QueryNodeProcessorImpl() {
84 public QueryNodeProcessorImpl(QueryConfigHandler queryConfigHandler) {
85 this.queryConfig = queryConfigHandler;
88 public QueryNode process(QueryNode queryTree) throws QueryNodeException {
89 return processIteration(queryTree);
92 private QueryNode processIteration(QueryNode queryTree)
93 throws QueryNodeException {
94 queryTree = preProcessNode(queryTree);
96 processChildren(queryTree);
98 queryTree = postProcessNode(queryTree);
105 * This method is called every time a child is processed.
108 * the query node child to be processed
109 * @throws QueryNodeException
110 * if something goes wrong during the query node processing
112 protected void processChildren(QueryNode queryTree) throws QueryNodeException {
114 List<QueryNode> children = queryTree.getChildren();
115 ChildrenList newChildren;
117 if (children != null && children.size() > 0) {
119 newChildren = allocateChildrenList();
123 for (QueryNode child : children) {
124 child = processIteration(child);
127 throw new NullPointerException();
131 newChildren.add(child);
135 List<QueryNode> orderedChildrenList = setChildrenOrder(newChildren);
137 queryTree.set(orderedChildrenList);
140 newChildren.beingUsed = false;
147 private ChildrenList allocateChildrenList() {
148 ChildrenList list = null;
150 for (ChildrenList auxList : this.childrenListPool) {
152 if (!auxList.beingUsed) {
163 list = new ChildrenList();
164 this.childrenListPool.add(list);
168 list.beingUsed = true;
175 * For reference about this method check:
176 * {@link QueryNodeProcessor#setQueryConfigHandler(QueryConfigHandler)}.
178 * @param queryConfigHandler
179 * the query configuration handler to be set.
181 * @see QueryNodeProcessor#getQueryConfigHandler()
182 * @see QueryConfigHandler
184 public void setQueryConfigHandler(QueryConfigHandler queryConfigHandler) {
185 this.queryConfig = queryConfigHandler;
189 * For reference about this method check:
190 * {@link QueryNodeProcessor#getQueryConfigHandler()}.
192 * @return QueryConfigHandler the query configuration handler to be set.
194 * @see QueryNodeProcessor#setQueryConfigHandler(QueryConfigHandler)
195 * @see QueryConfigHandler
197 public QueryConfigHandler getQueryConfigHandler() {
198 return this.queryConfig;
202 * This method is invoked for every node when walking down the tree.
205 * the query node to be pre-processed
207 * @return a query node
209 * @throws QueryNodeException
210 * if something goes wrong during the query node processing
212 abstract protected QueryNode preProcessNode(QueryNode node)
213 throws QueryNodeException;
216 * This method is invoked for every node when walking up the tree.
219 * node the query node to be post-processed
221 * @return a query node
223 * @throws QueryNodeException
224 * if something goes wrong during the query node processing
226 abstract protected QueryNode postProcessNode(QueryNode node)
227 throws QueryNodeException;
230 * This method is invoked for every node that has at least on child. It's
231 * invoked right before {@link #postProcessNode(QueryNode)} is invoked.
234 * the list containing all current node's children
236 * @return a new list containing all children that should be set to the
239 * @throws QueryNodeException
240 * if something goes wrong during the query node processing
242 abstract protected List<QueryNode> setChildrenOrder(List<QueryNode> children)
243 throws QueryNodeException;
245 private static class ChildrenList extends ArrayList<QueryNode> {
247 private static final long serialVersionUID = -2613518456949297135L;