+++ /dev/null
-package org.apache.lucene.queryParser.core.builders;
-
-/**
- * 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.HashMap;
-import java.util.List;
-
-import org.apache.lucene.messages.MessageImpl;
-import org.apache.lucene.queryParser.core.QueryNodeException;
-import org.apache.lucene.queryParser.core.messages.QueryParserMessages;
-import org.apache.lucene.queryParser.core.nodes.FieldableNode;
-import org.apache.lucene.queryParser.core.nodes.QueryNode;
-import org.apache.lucene.queryParser.core.util.StringUtils;
-import org.apache.lucene.queryParser.standard.parser.EscapeQuerySyntaxImpl;
-
-/**
- * This class should be used when there is a builder for each type of node.
- *
- * The type of node may be defined in 2 different ways: - by the field name,
- * when the node implements the {@link FieldableNode} interface - by its class,
- * it keeps checking the class and all the interfaces and classes this class
- * implements/extends until it finds a builder for that class/interface
- *
- * This class always check if there is a builder for the field name before it
- * checks for the node class. So, field name builders have precedence over class
- * builders.
- *
- * When a builder is found for a node, it's called and the node is passed to the
- * builder. If the returned built object is not <code>null</code>, it's tagged
- * on the node using the tag {@link QueryTreeBuilder#QUERY_TREE_BUILDER_TAGID}.
- *
- * The children are usually built before the parent node. However, if a builder
- * associated to a node is an instance of {@link QueryTreeBuilder}, the node is
- * delegated to this builder and it's responsible to build the node and its
- * children.
- *
- * @see QueryBuilder
- */
-public class QueryTreeBuilder implements QueryBuilder {
-
- /**
- * This tag is used to tag the nodes in a query tree with the built objects
- * produced from their own associated builder.
- */
- public static final String QUERY_TREE_BUILDER_TAGID = QueryTreeBuilder.class
- .getName();
-
- private HashMap<Class<? extends QueryNode>, QueryBuilder> queryNodeBuilders;
-
- private HashMap<String, QueryBuilder> fieldNameBuilders;
-
- /**
- * {@link QueryTreeBuilder} constructor.
- */
- public QueryTreeBuilder() {
- // empty constructor
- }
-
- /**
- * Associates a field name with a builder.
- *
- * @param fieldName the field name
- * @param builder the builder to be associated
- */
- public void setBuilder(String fieldName, QueryBuilder builder) {
-
- if (this.fieldNameBuilders == null) {
- this.fieldNameBuilders = new HashMap<String, QueryBuilder>();
- }
-
- this.fieldNameBuilders.put(fieldName.toString(), builder);
-
- }
-
- /**
- * Associates a field name with a builder.
- *
- * @param fieldName the field name
- * @param builder the builder to be associated
- *
- * @deprecated use {@link #setBuilder(String, QueryBuilder)} instead
- */
- @Deprecated
- public void setBuilder(CharSequence fieldName, QueryBuilder builder) {
- setBuilder(StringUtils.toString(fieldName), builder);
- }
-
- /**
- * Associates a class with a builder
- *
- * @param queryNodeClass the class
- * @param builder the builder to be associated
- */
- public void setBuilder(Class<? extends QueryNode> queryNodeClass,
- QueryBuilder builder) {
-
- if (this.queryNodeBuilders == null) {
- this.queryNodeBuilders = new HashMap<Class<? extends QueryNode>, QueryBuilder>();
- }
-
- this.queryNodeBuilders.put(queryNodeClass, builder);
-
- }
-
- private void process(QueryNode node) throws QueryNodeException {
-
- if (node != null) {
- QueryBuilder builder = getBuilder(node);
-
- if (!(builder instanceof QueryTreeBuilder)) {
- List<QueryNode> children = node.getChildren();
-
- if (children != null) {
-
- for (QueryNode child : children) {
- process(child);
- }
-
- }
-
- }
-
- processNode(node, builder);
-
- }
-
- }
-
- private QueryBuilder getBuilder(QueryNode node) {
- QueryBuilder builder = null;
-
- if (this.fieldNameBuilders != null && node instanceof FieldableNode) {
- builder = this.fieldNameBuilders.get(StringUtils
- .toString(((FieldableNode) node).getField()));
- }
-
- if (builder == null && this.queryNodeBuilders != null) {
-
- Class<?> clazz = node.getClass();
-
- do {
- builder = getQueryBuilder(clazz);
-
- if (builder == null) {
- Class<?>[] classes = node.getClass().getInterfaces();
-
- for (Class<?> actualClass : classes) {
- builder = getQueryBuilder(actualClass);
-
- if (builder != null) {
- break;
- }
-
- }
-
- }
-
- } while (builder == null && (clazz = clazz.getSuperclass()) != null);
-
- }
-
- return builder;
-
- }
-
- private void processNode(QueryNode node, QueryBuilder builder)
- throws QueryNodeException {
-
- if (builder == null) {
-
- throw new QueryNodeException(new MessageImpl(
- QueryParserMessages.LUCENE_QUERY_CONVERSION_ERROR, node
- .toQueryString(new EscapeQuerySyntaxImpl()), node.getClass()
- .getName()));
-
- }
-
- Object obj = builder.build(node);
-
- if (obj != null) {
- node.setTag(QUERY_TREE_BUILDER_TAGID, obj);
- }
-
- }
-
- private QueryBuilder getQueryBuilder(Class<?> clazz) {
-
- if (QueryNode.class.isAssignableFrom(clazz)) {
- return this.queryNodeBuilders.get(clazz);
- }
-
- return null;
-
- }
-
- /**
- * Builds some kind of object from a query tree. Each node in the query tree
- * is built using an specific builder associated to it.
- *
- * @param queryNode the query tree root node
- *
- * @return the built object
- *
- * @throws QueryNodeException if some node builder throws a
- * {@link QueryNodeException} or if there is a node which had no
- * builder associated to it
- */
- public Object build(QueryNode queryNode) throws QueryNodeException {
- process(queryNode);
-
- return queryNode.getTag(QUERY_TREE_BUILDER_TAGID);
-
- }
-
-}