lucene-java-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From busc...@apache.org
Subject svn commit: r800191 [9/12] - in /lucene/java/trunk: ./ contrib/ contrib/queryparser/ contrib/queryparser/src/ contrib/queryparser/src/java/ contrib/queryparser/src/java/org/ contrib/queryparser/src/java/org/apache/ contrib/queryparser/src/java/org/apac...
Date Mon, 03 Aug 2009 03:38:50 GMT
Added: lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/FuzzyQueryNodeProcessor.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/FuzzyQueryNodeProcessor.java?rev=800191&view=auto
==============================================================================
--- lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/FuzzyQueryNodeProcessor.java (added)
+++ lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/FuzzyQueryNodeProcessor.java Mon Aug  3 03:38:44 2009
@@ -0,0 +1,86 @@
+package org.apache.lucene.queryParser.original.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.List;
+
+import org.apache.lucene.queryParser.core.QueryNodeException;
+import org.apache.lucene.queryParser.core.config.QueryConfigHandler;
+import org.apache.lucene.queryParser.core.nodes.FuzzyQueryNode;
+import org.apache.lucene.queryParser.core.nodes.QueryNode;
+import org.apache.lucene.queryParser.core.processors.QueryNodeProcessorImpl;
+import org.apache.lucene.queryParser.original.config.FuzzyAttribute;
+import org.apache.lucene.search.FuzzyQuery;
+
+/**
+ * This processor iterates the query node tree looking for every
+ * {@link FuzzyQueryNode}, when this kind of node is found, it checks on the
+ * query configuration for {@link FuzzyAttribute}, gets the fuzzy prefix length
+ * and default similarity from it and set to the fuzzy node. For more
+ * information about fuzzy prefix length check: {@link FuzzyQuery}. <br/>
+ * 
+ * @see FuzzyAttribute
+ * @see FuzzyQuery
+ * @see FuzzyQueryNode
+ */
+public class FuzzyQueryNodeProcessor extends QueryNodeProcessorImpl {
+
+  @Override
+  protected QueryNode postProcessNode(QueryNode node) throws QueryNodeException {
+
+    return node;
+
+  }
+
+  @Override
+  protected QueryNode preProcessNode(QueryNode node) throws QueryNodeException {
+
+    if (node instanceof FuzzyQueryNode) {
+      FuzzyQueryNode fuzzyNode = (FuzzyQueryNode) node;
+      QueryConfigHandler config = getQueryConfigHandler();
+
+      if (config != null && config.hasAttribute(FuzzyAttribute.class)) {
+        FuzzyAttribute fuzzyAttr = (FuzzyAttribute) config
+            .getAttribute(FuzzyAttribute.class);
+        fuzzyNode.setPrefixLength(fuzzyAttr.getPrefixLength());
+
+        if (fuzzyNode.getSimilarity() < 0) {
+          fuzzyNode.setSimilarity(fuzzyAttr.getFuzzyMinSimilarity());
+
+        }
+
+      } else if (fuzzyNode.getSimilarity() < 0) {
+        throw new IllegalArgumentException("No "
+            + FuzzyAttribute.class.getName() + " set in the config");
+      }
+
+    }
+
+    return node;
+
+  }
+
+  @Override
+  protected List<QueryNode> setChildrenOrder(List<QueryNode> children)
+      throws QueryNodeException {
+
+    return children;
+
+  }
+
+}

Propchange: lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/FuzzyQueryNodeProcessor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/GroupQueryNodeProcessor.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/GroupQueryNodeProcessor.java?rev=800191&view=auto
==============================================================================
--- lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/GroupQueryNodeProcessor.java (added)
+++ lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/GroupQueryNodeProcessor.java Mon Aug  3 03:38:44 2009
@@ -0,0 +1,219 @@
+package org.apache.lucene.queryParser.original.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.original.config.DefaultOperatorAttribute;
+import org.apache.lucene.queryParser.original.config.DefaultOperatorAttribute.Operator;
+import org.apache.lucene.queryParser.original.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. <br/>
+ * <br/>
+ * 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.original.config.OriginalQueryConfigHandler
+ */
+public class GroupQueryNodeProcessor implements QueryNodeProcessor {
+
+  private ArrayList<QueryNode> queryNodeList;
+
+  private boolean latestNodeVerified;
+
+  private QueryConfigHandler queryConfig;
+
+  private Boolean usingAnd = false;
+
+  public GroupQueryNodeProcessor() {
+    // empty constructor
+  }
+
+  public QueryNode process(QueryNode queryTree) throws QueryNodeException {
+
+    if (!getQueryConfigHandler().hasAttribute(DefaultOperatorAttribute.class)) {
+      throw new IllegalArgumentException(
+          "DefaultOperatorAttribute should be set on the QueryConfigHandler");
+    }
+
+    usingAnd = Operator.AND == ((DefaultOperatorAttribute) getQueryConfigHandler()
+        .getAttribute(DefaultOperatorAttribute.class)).getOperator();
+
+    if (queryTree instanceof GroupQueryNode) {
+      queryTree = ((GroupQueryNode) queryTree).getChild();
+    }
+
+    this.queryNodeList = new ArrayList<QueryNode>();
+    this.latestNodeVerified = false;
+    readTree(queryTree);
+
+    List<QueryNode> 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);
+    }
+
+  }
+
+  /**
+   * @param node
+   * @return
+   */
+  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<QueryNode> 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;
+  }
+
+}

Propchange: lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/GroupQueryNodeProcessor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/LowercaseExpandedTermsQueryNodeProcessor.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/LowercaseExpandedTermsQueryNodeProcessor.java?rev=800191&view=auto
==============================================================================
--- lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/LowercaseExpandedTermsQueryNodeProcessor.java (added)
+++ lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/LowercaseExpandedTermsQueryNodeProcessor.java Mon Aug  3 03:38:44 2009
@@ -0,0 +1,93 @@
+package org.apache.lucene.queryParser.original.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.List;
+
+import org.apache.lucene.queryParser.core.QueryNodeException;
+import org.apache.lucene.queryParser.core.config.QueryConfigHandler;
+import org.apache.lucene.queryParser.core.nodes.FieldQueryNode;
+import org.apache.lucene.queryParser.core.nodes.FuzzyQueryNode;
+import org.apache.lucene.queryParser.core.nodes.ParametricQueryNode;
+import org.apache.lucene.queryParser.core.nodes.QueryNode;
+import org.apache.lucene.queryParser.core.nodes.WildcardQueryNode;
+import org.apache.lucene.queryParser.core.processors.QueryNodeProcessorImpl;
+import org.apache.lucene.queryParser.original.config.LowercaseExpandedTermsAttribute;
+
+/**
+ * This processor verifies if the attribute
+ * {@link LowercaseExpandedTermsAttribute} is defined in the
+ * {@link QueryConfigHandler}. If it is and the expanded terms should be
+ * lower-cased, it looks for every {@link WildcardQueryNode},
+ * {@link FuzzyQueryNode} and {@link ParametricQueryNode} and lower-case its
+ * term. <br/>
+ * 
+ * @see LowercaseExpandedTermsAttribute
+ */
+public class LowercaseExpandedTermsQueryNodeProcessor extends
+    QueryNodeProcessorImpl {
+
+  public LowercaseExpandedTermsQueryNodeProcessor() {
+    // empty constructor
+  }
+
+  public QueryNode process(QueryNode queryTree) throws QueryNodeException {
+
+    if (getQueryConfigHandler().hasAttribute(
+        LowercaseExpandedTermsAttribute.class)) {
+
+      if (((LowercaseExpandedTermsAttribute) getQueryConfigHandler()
+          .getAttribute(LowercaseExpandedTermsAttribute.class))
+          .isLowercaseExpandedTerms()) {
+        return super.process(queryTree);
+      }
+
+    }
+
+    return queryTree;
+
+  }
+
+  protected QueryNode postProcessNode(QueryNode node) throws QueryNodeException {
+
+    if (node instanceof WildcardQueryNode || node instanceof FuzzyQueryNode
+        || node instanceof ParametricQueryNode) {
+
+      FieldQueryNode fieldNode = (FieldQueryNode) node;
+      fieldNode.setText(fieldNode.getText().toString().toLowerCase());
+
+    }
+
+    return node;
+
+  }
+
+  protected QueryNode preProcessNode(QueryNode node) throws QueryNodeException {
+
+    return node;
+
+  }
+
+  protected List<QueryNode> setChildrenOrder(List<QueryNode> children)
+      throws QueryNodeException {
+
+    return children;
+
+  }
+
+}

Propchange: lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/LowercaseExpandedTermsQueryNodeProcessor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/MatchAllDocsQueryNodeProcessor.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/MatchAllDocsQueryNodeProcessor.java?rev=800191&view=auto
==============================================================================
--- lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/MatchAllDocsQueryNodeProcessor.java (added)
+++ lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/MatchAllDocsQueryNodeProcessor.java Mon Aug  3 03:38:44 2009
@@ -0,0 +1,73 @@
+package org.apache.lucene.queryParser.original.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.List;
+
+import org.apache.lucene.queryParser.core.QueryNodeException;
+import org.apache.lucene.queryParser.core.nodes.MatchAllDocsQueryNode;
+import org.apache.lucene.queryParser.core.nodes.QueryNode;
+import org.apache.lucene.queryParser.core.nodes.WildcardQueryNode;
+import org.apache.lucene.queryParser.core.processors.QueryNodeProcessorImpl;
+import org.apache.lucene.search.MatchAllDocsQuery;
+
+/**
+ * This processor converts every {@link WildcardQueryNode} that is "*:*" to
+ * {@link MatchAllDocsQueryNode}.
+ * 
+ * @see MatchAllDocsQueryNode
+ * @see MatchAllDocsQuery
+ */
+public class MatchAllDocsQueryNodeProcessor extends QueryNodeProcessorImpl {
+
+  public MatchAllDocsQueryNodeProcessor() {
+    // empty constructor
+  }
+
+  protected QueryNode postProcessNode(QueryNode node) throws QueryNodeException {
+
+    if (node instanceof WildcardQueryNode) {
+      WildcardQueryNode wildcardNode = (WildcardQueryNode) node;
+
+      if (wildcardNode.getField().toString().equals("*")
+          && wildcardNode.getText().toString().equals("*")) {
+
+        return new MatchAllDocsQueryNode();
+
+      }
+
+    }
+
+    return node;
+
+  }
+
+  protected QueryNode preProcessNode(QueryNode node) throws QueryNodeException {
+
+    return node;
+
+  }
+
+  protected List<QueryNode> setChildrenOrder(List<QueryNode> children)
+      throws QueryNodeException {
+
+    return children;
+
+  }
+
+}

Propchange: lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/MatchAllDocsQueryNodeProcessor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/MultiFieldQueryNodeProcessor.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/MultiFieldQueryNodeProcessor.java?rev=800191&view=auto
==============================================================================
--- lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/MultiFieldQueryNodeProcessor.java (added)
+++ lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/MultiFieldQueryNodeProcessor.java Mon Aug  3 03:38:44 2009
@@ -0,0 +1,131 @@
+package org.apache.lucene.queryParser.original.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.LinkedList;
+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.BooleanQueryNode;
+import org.apache.lucene.queryParser.core.nodes.FieldableNode;
+import org.apache.lucene.queryParser.core.nodes.GroupQueryNode;
+import org.apache.lucene.queryParser.core.nodes.QueryNode;
+import org.apache.lucene.queryParser.core.processors.QueryNodeProcessorImpl;
+import org.apache.lucene.queryParser.original.config.MultiFieldAttribute;
+
+/**
+ * This processor is used to expand terms so the query looks for the same term
+ * in different fields. It also boosts a query based on its field. <br/>
+ * <br/>
+ * This processor looks for every {@link FieldableNode} contained in the query
+ * node tree. If a {@link FieldableNode} is found, it checks if there is a
+ * {@link MultiFieldAttribute} defined in the {@link QueryConfigHandler}. If
+ * there is, the {@link FieldableNode} is cloned N times and the clones are
+ * added to a {@link BooleanQueryNode} together with the original node. N is
+ * defined by the number of fields that it will be expanded to. The
+ * {@link BooleanQueryNode} is returned. <br/>
+ * 
+ * @see MultiFieldAttribute
+ */
+public class MultiFieldQueryNodeProcessor extends QueryNodeProcessorImpl {
+
+  private boolean processChildren = true;
+
+  public MultiFieldQueryNodeProcessor() {
+    // empty constructor
+  }
+
+  protected QueryNode postProcessNode(QueryNode node) throws QueryNodeException {
+
+    return node;
+
+  }
+
+  protected void processChildren(QueryNode queryTree) throws QueryNodeException {
+
+    if (this.processChildren) {
+      super.processChildren(queryTree);
+
+    } else {
+      this.processChildren = true;
+    }
+
+  }
+
+  protected QueryNode preProcessNode(QueryNode node) throws QueryNodeException {
+
+    if (node instanceof FieldableNode) {
+      this.processChildren = false;
+      FieldableNode fieldNode = (FieldableNode) node;
+
+      if (fieldNode.getField() == null) {
+
+        if (!getQueryConfigHandler().hasAttribute(MultiFieldAttribute.class)) {
+          throw new IllegalArgumentException(
+              "MultiFieldAttribute should be set on the QueryConfigHandler");
+        }
+
+        CharSequence[] fields = ((MultiFieldAttribute) getQueryConfigHandler()
+            .getAttribute(MultiFieldAttribute.class)).getFields();
+
+        if (fields != null && fields.length > 0) {
+          fieldNode.setField(fields[0]);
+
+          if (fields.length == 1) {
+            return fieldNode;
+
+          } else {
+            LinkedList<QueryNode> children = new LinkedList<QueryNode>();
+            children.add(fieldNode);
+
+            for (int i = 1; i < fields.length; i++) {
+              try {
+                fieldNode = (FieldableNode) fieldNode.cloneTree();
+                fieldNode.setField(fields[i]);
+
+                children.add(fieldNode);
+
+              } catch (CloneNotSupportedException e) {
+                // should never happen
+              }
+
+            }
+
+            return new GroupQueryNode(new BooleanQueryNode(children));
+
+          }
+
+        }
+
+      }
+
+    }
+
+    return node;
+
+  }
+
+  protected List<QueryNode> setChildrenOrder(List<QueryNode> children)
+      throws QueryNodeException {
+
+    return children;
+
+  }
+
+}

Propchange: lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/MultiFieldQueryNodeProcessor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/OriginalQueryNodeProcessorPipeline.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/OriginalQueryNodeProcessorPipeline.java?rev=800191&view=auto
==============================================================================
--- lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/OriginalQueryNodeProcessorPipeline.java (added)
+++ lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/OriginalQueryNodeProcessorPipeline.java Mon Aug  3 03:38:44 2009
@@ -0,0 +1,70 @@
+package org.apache.lucene.queryParser.original.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 org.apache.lucene.queryParser.core.config.QueryConfigHandler;
+import org.apache.lucene.queryParser.core.processors.NoChildOptimizationQueryNodeProcessor;
+import org.apache.lucene.queryParser.core.processors.QueryNodeProcessorPipeline;
+import org.apache.lucene.queryParser.core.processors.RemoveDeletedQueryNodesProcessor;
+import org.apache.lucene.queryParser.original.builders.OriginalQueryTreeBuilder;
+import org.apache.lucene.queryParser.original.config.OriginalQueryConfigHandler;
+import org.apache.lucene.queryParser.original.parser.OriginalSyntaxParser;
+import org.apache.lucene.search.Query;
+
+/**
+ * This pipeline has all the processors needed to process a query node tree,
+ * generated by {@link OriginalSyntaxParser}, already assembled. <br/>
+ * <br/>
+ * The order they are assembled affects the results. <br/>
+ * <br/>
+ * This processor pipeline was designed to work with
+ * {@link OriginalQueryConfigHandler}. <br/>
+ * <br/>
+ * The result query node tree can be used to build a {@link Query} object using
+ * {@link OriginalQueryTreeBuilder}. <br/>
+ * 
+ * @see OriginalQueryTreeBuilder
+ * @see OriginalQueryConfigHandler
+ * @see OriginalSyntaxParser
+ */
+public class OriginalQueryNodeProcessorPipeline extends
+    QueryNodeProcessorPipeline {
+
+  public OriginalQueryNodeProcessorPipeline(QueryConfigHandler queryConfig) {
+    super(queryConfig);
+
+    addProcessor(new MultiFieldQueryNodeProcessor());
+    addProcessor(new FuzzyQueryNodeProcessor());
+    addProcessor(new MatchAllDocsQueryNodeProcessor());
+    addProcessor(new LowercaseExpandedTermsQueryNodeProcessor());
+    addProcessor(new ParametricRangeQueryNodeProcessor());
+    addProcessor(new AllowLeadingWildcardProcessor());
+    addProcessor(new PrefixWildcardQueryNodeProcessor());
+    addProcessor(new AnalyzerQueryNodeProcessor());
+    addProcessor(new PhraseSlopQueryNodeProcessor());
+    addProcessor(new GroupQueryNodeProcessor());
+    addProcessor(new NoChildOptimizationQueryNodeProcessor());
+    addProcessor(new RemoveDeletedQueryNodesProcessor());
+    addProcessor(new RemoveEmptyNonLeafQueryNodeProcessor());
+    addProcessor(new BooleanSingleChildOptimizationQueryNodeProcessor());
+    addProcessor(new DefaultPhraseSlopQueryNodeProcessor());
+    addProcessor(new BoostQueryNodeProcessor());
+
+  }
+
+}

Propchange: lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/OriginalQueryNodeProcessorPipeline.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/ParametricRangeQueryNodeProcessor.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/ParametricRangeQueryNodeProcessor.java?rev=800191&view=auto
==============================================================================
--- lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/ParametricRangeQueryNodeProcessor.java (added)
+++ lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/ParametricRangeQueryNodeProcessor.java Mon Aug  3 03:38:44 2009
@@ -0,0 +1,188 @@
+package org.apache.lucene.queryParser.original.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.text.Collator;
+import java.text.DateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+
+import org.apache.lucene.document.DateField;
+import org.apache.lucene.document.DateTools;
+import org.apache.lucene.document.DateTools.Resolution;
+import org.apache.lucene.queryParser.core.QueryNodeException;
+import org.apache.lucene.queryParser.core.config.FieldConfig;
+import org.apache.lucene.queryParser.core.config.QueryConfigHandler;
+import org.apache.lucene.queryParser.core.nodes.ParametricQueryNode;
+import org.apache.lucene.queryParser.core.nodes.ParametricRangeQueryNode;
+import org.apache.lucene.queryParser.core.nodes.QueryNode;
+import org.apache.lucene.queryParser.core.nodes.ParametricQueryNode.CompareOperator;
+import org.apache.lucene.queryParser.core.processors.QueryNodeProcessorImpl;
+import org.apache.lucene.queryParser.original.config.MultiTermRewriteMethodAttribute;
+import org.apache.lucene.queryParser.original.config.DateResolutionAttribute;
+import org.apache.lucene.queryParser.original.config.LocaleAttribute;
+import org.apache.lucene.queryParser.original.config.RangeCollatorAttribute;
+import org.apache.lucene.queryParser.original.nodes.RangeQueryNode;
+import org.apache.lucene.search.MultiTermQuery;
+
+/**
+ * This processor converts {@link ParametricRangeQueryNode} objects to
+ * {@link RangeQueryNode} objects. It reads the lower and upper bounds value
+ * from the {@link ParametricRangeQueryNode} object and try to parse their
+ * values using a {@link DateFormat}. If the values cannot be parsed to a date
+ * value, it will only create the {@link RangeQueryNode} using the non-parsed
+ * values. <br/>
+ * <br/>
+ * If a {@link LocaleAttribute} is defined in the {@link QueryConfigHandler} it
+ * will be used to parse the date, otherwise {@link Locale#getDefault()} will be
+ * used. <br/>
+ * <br/>
+ * If a {@link DateResolutionAttribute} is defined and the {@link Resolution} is
+ * not <code>null</code> it will also be used to parse the date value. <br/>
+ * <br/>
+ * This processor will also try to retrieve a {@link RangeCollatorAttribute}
+ * from the {@link QueryConfigHandler}. If a {@link RangeCollatorAttribute} is
+ * found and the {@link Collator} is not <code>null</code>, it's set on the
+ * {@link RangeQueryNode}. <br/>
+ * 
+ * @see RangeCollatorAttribute
+ * @see DateResolutionAttribute
+ * @see LocaleAttribute
+ * @see RangeQueryNode
+ * @see ParametricRangeQueryNode
+ */
+public class ParametricRangeQueryNodeProcessor extends QueryNodeProcessorImpl {
+
+  public ParametricRangeQueryNodeProcessor() {
+    // empty constructor
+  }
+
+  protected QueryNode postProcessNode(QueryNode node) throws QueryNodeException {
+
+    if (node instanceof ParametricRangeQueryNode) {
+      ParametricRangeQueryNode parametricRangeNode = (ParametricRangeQueryNode) node;
+      ParametricQueryNode upper = parametricRangeNode.getUpperBound();
+      ParametricQueryNode lower = parametricRangeNode.getLowerBound();
+      Locale locale = Locale.getDefault();
+      Collator collator = null;
+      DateTools.Resolution dateRes = null;
+      boolean inclusive = false;
+
+      if (!getQueryConfigHandler().hasAttribute(
+          MultiTermRewriteMethodAttribute.class)) {
+        throw new IllegalArgumentException(
+            "MultiTermRewriteMethodAttribute should be set on the QueryConfigHandler");
+      }
+
+      MultiTermQuery.RewriteMethod rewriteMethod = ((MultiTermRewriteMethodAttribute) getQueryConfigHandler()
+          .getAttribute(MultiTermRewriteMethodAttribute.class))
+          .getMultiTermRewriteMethod();
+
+      if (getQueryConfigHandler().hasAttribute(RangeCollatorAttribute.class)) {
+        collator = ((RangeCollatorAttribute) getQueryConfigHandler()
+            .getAttribute(RangeCollatorAttribute.class)).getRangeCollator();
+      }
+
+      if (getQueryConfigHandler().hasAttribute(LocaleAttribute.class)) {
+        locale = ((LocaleAttribute) getQueryConfigHandler().getAttribute(
+            LocaleAttribute.class)).getLocale();
+      }
+
+      FieldConfig fieldConfig = getQueryConfigHandler().getFieldConfig(
+          parametricRangeNode.getField());
+
+      if (fieldConfig != null) {
+
+        if (fieldConfig.hasAttribute(DateResolutionAttribute.class)) {
+          dateRes = ((DateResolutionAttribute) fieldConfig
+              .getAttribute(DateResolutionAttribute.class)).getDateResolution();
+        }
+
+      }
+
+      if (upper.getOperator() == CompareOperator.LE) {
+        inclusive = true;
+
+      } else if (lower.getOperator() == CompareOperator.GE) {
+        inclusive = true;
+      }
+
+      String part1 = lower.getTextAsString();
+      String part2 = upper.getTextAsString();
+
+      try {
+        DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, Locale
+            .getDefault());
+        df.setLenient(true);
+        Date d1 = df.parse(part1);
+        Date d2 = df.parse(part2);
+        if (inclusive) {
+          // The user can only specify the date, not the time, so make sure
+          // the time is set to the latest possible time of that date to really
+          // include all documents:
+          Calendar cal = Calendar.getInstance(locale);
+          cal.setTime(d2);
+          cal.set(Calendar.HOUR_OF_DAY, 23);
+          cal.set(Calendar.MINUTE, 59);
+          cal.set(Calendar.SECOND, 59);
+          cal.set(Calendar.MILLISECOND, 999);
+          d2 = cal.getTime();
+        }
+
+        if (dateRes == null) {
+          // no default or field specific date resolution has been set,
+          // use deprecated DateField to maintain compatibilty with
+          // pre-1.9 Lucene versions.
+          part1 = DateField.dateToString(d1);
+          part2 = DateField.dateToString(d2);
+
+        } else {
+          part1 = DateTools.dateToString(d1, dateRes);
+          part2 = DateTools.dateToString(d2, dateRes);
+        }
+      } catch (Exception e) {
+        // do nothing
+      }
+
+      lower.setText(part1);
+      upper.setText(part2);
+
+      return new RangeQueryNode(lower, upper, collator, rewriteMethod);
+
+    }
+
+    return node;
+
+  }
+
+  protected QueryNode preProcessNode(QueryNode node) throws QueryNodeException {
+
+    return node;
+
+  }
+
+  protected List<QueryNode> setChildrenOrder(List<QueryNode> children)
+      throws QueryNodeException {
+
+    return children;
+
+  }
+
+}

Propchange: lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/ParametricRangeQueryNodeProcessor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/PhraseSlopQueryNodeProcessor.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/PhraseSlopQueryNodeProcessor.java?rev=800191&view=auto
==============================================================================
--- lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/PhraseSlopQueryNodeProcessor.java (added)
+++ lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/PhraseSlopQueryNodeProcessor.java Mon Aug  3 03:38:44 2009
@@ -0,0 +1,71 @@
+package org.apache.lucene.queryParser.original.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.List;
+
+import org.apache.lucene.queryParser.core.QueryNodeException;
+import org.apache.lucene.queryParser.core.nodes.QueryNode;
+import org.apache.lucene.queryParser.core.nodes.SlopQueryNode;
+import org.apache.lucene.queryParser.core.nodes.TokenizedPhraseQueryNode;
+import org.apache.lucene.queryParser.core.processors.QueryNodeProcessorImpl;
+import org.apache.lucene.queryParser.original.nodes.MultiPhraseQueryNode;
+
+/**
+ * This processor removes invalid {@link SlopQueryNode} objects in the query
+ * node tree. A {@link SlopQueryNode} is invalid if its child is neither a
+ * {@link TokenizedPhraseQueryNode} nor a {@link MultiPhraseQueryNode}. <br/>
+ * 
+ * @see SlopQueryNode
+ */
+public class PhraseSlopQueryNodeProcessor extends QueryNodeProcessorImpl {
+
+  public PhraseSlopQueryNodeProcessor() {
+    // empty constructor
+  }
+
+  protected QueryNode postProcessNode(QueryNode node) throws QueryNodeException {
+
+    if (node instanceof SlopQueryNode) {
+      SlopQueryNode phraseSlopNode = (SlopQueryNode) node;
+
+      if (!(phraseSlopNode.getChild() instanceof TokenizedPhraseQueryNode)
+          && !(phraseSlopNode.getChild() instanceof MultiPhraseQueryNode)) {
+        return phraseSlopNode.getChild();
+      }
+
+    }
+
+    return node;
+
+  }
+
+  protected QueryNode preProcessNode(QueryNode node) throws QueryNodeException {
+
+    return node;
+
+  }
+
+  protected List<QueryNode> setChildrenOrder(List<QueryNode> children)
+      throws QueryNodeException {
+
+    return children;
+
+  }
+
+}

Propchange: lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/PhraseSlopQueryNodeProcessor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/PrefixWildcardQueryNodeProcessor.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/PrefixWildcardQueryNodeProcessor.java?rev=800191&view=auto
==============================================================================
--- lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/PrefixWildcardQueryNodeProcessor.java (added)
+++ lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/PrefixWildcardQueryNodeProcessor.java Mon Aug  3 03:38:44 2009
@@ -0,0 +1,72 @@
+package org.apache.lucene.queryParser.original.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.List;
+
+import org.apache.lucene.queryParser.core.QueryNodeException;
+import org.apache.lucene.queryParser.core.nodes.PrefixWildcardQueryNode;
+import org.apache.lucene.queryParser.core.nodes.QueryNode;
+import org.apache.lucene.queryParser.core.processors.QueryNodeProcessorImpl;
+import org.apache.lucene.queryParser.original.parser.OriginalSyntaxParser;
+import org.apache.lucene.search.PrefixQuery;
+
+/**
+ * The {@link OriginalSyntaxParser} creates {@link PrefixWildcardQueryNode} nodes which
+ * have values containing the prefixed wildcard. However, Lucene
+ * {@link PrefixQuery} cannot contain the prefixed wildcard. So, this processor
+ * basically removed the prefixed wildcard from the
+ * {@link PrefixWildcardQueryNode} value. <br/>
+ * 
+ * @see PrefixQuery
+ * @see PrefixWildcardQueryNode
+ */
+public class PrefixWildcardQueryNodeProcessor extends QueryNodeProcessorImpl {
+
+  public PrefixWildcardQueryNodeProcessor() {
+    // empty constructor
+  }
+
+  protected QueryNode postProcessNode(QueryNode node) throws QueryNodeException {
+
+    if (node instanceof PrefixWildcardQueryNode) {
+      PrefixWildcardQueryNode prefixWildcardNode = (PrefixWildcardQueryNode) node;
+      CharSequence text = prefixWildcardNode.getText();
+
+      prefixWildcardNode.setText(text.subSequence(0, text.length() - 1));
+
+    }
+
+    return node;
+
+  }
+
+  protected QueryNode preProcessNode(QueryNode node) throws QueryNodeException {
+
+    return node;
+
+  }
+
+  protected List<QueryNode> setChildrenOrder(List<QueryNode> children)
+      throws QueryNodeException {
+
+    return children;
+
+  }
+
+}

Propchange: lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/PrefixWildcardQueryNodeProcessor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/RemoveEmptyNonLeafQueryNodeProcessor.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/RemoveEmptyNonLeafQueryNodeProcessor.java?rev=800191&view=auto
==============================================================================
--- lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/RemoveEmptyNonLeafQueryNodeProcessor.java (added)
+++ lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/RemoveEmptyNonLeafQueryNodeProcessor.java Mon Aug  3 03:38:44 2009
@@ -0,0 +1,112 @@
+package org.apache.lucene.queryParser.original.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.LinkedList;
+import java.util.List;
+
+import org.apache.lucene.queryParser.core.QueryNodeException;
+import org.apache.lucene.queryParser.core.nodes.GroupQueryNode;
+import org.apache.lucene.queryParser.core.nodes.MatchNoDocsQueryNode;
+import org.apache.lucene.queryParser.core.nodes.ModifierQueryNode;
+import org.apache.lucene.queryParser.core.nodes.QueryNode;
+import org.apache.lucene.queryParser.core.processors.QueryNodeProcessorImpl;
+
+/**
+ * This processor removes every {@link QueryNode} that is not a leaf and has not
+ * children. If after processing the entire tree the root node is not a leaf and
+ * has no children, a {@link MatchNoDocsQueryNode} object is returned. <br/>
+ * <br/>
+ * This processor is used at the end of a pipeline to avoid invalid query node
+ * tree structures like a {@link GroupQueryNode} or {@link ModifierQueryNode}
+ * with no children. <br/>
+ * 
+ * @see QueryNode
+ * @see MatchNoDocsQueryNode
+ */
+public class RemoveEmptyNonLeafQueryNodeProcessor extends
+    QueryNodeProcessorImpl {
+
+  private LinkedList<QueryNode> childrenBuffer = new LinkedList<QueryNode>();
+
+  public RemoveEmptyNonLeafQueryNodeProcessor() {
+    // empty constructor
+  }
+
+  public QueryNode process(QueryNode queryTree) throws QueryNodeException {
+    queryTree = super.process(queryTree);
+
+    if (!queryTree.isLeaf()) {
+
+      List<QueryNode> children = queryTree.getChildren();
+
+      if (children == null || children.size() == 0) {
+        return new MatchNoDocsQueryNode();
+      }
+
+    }
+
+    return queryTree;
+
+  }
+
+  protected QueryNode postProcessNode(QueryNode node) throws QueryNodeException {
+
+    return node;
+
+  }
+
+  protected QueryNode preProcessNode(QueryNode node) throws QueryNodeException {
+
+    return node;
+
+  }
+
+  protected List<QueryNode> setChildrenOrder(List<QueryNode> children)
+      throws QueryNodeException {
+
+    try {
+
+      for (QueryNode child : children) {
+
+        if (!child.isLeaf()) {
+
+          List<QueryNode> grandChildren = child.getChildren();
+
+          if (grandChildren != null && grandChildren.size() > 0) {
+            this.childrenBuffer.add(child);
+          }
+
+        } else {
+          this.childrenBuffer.add(child);
+        }
+
+      }
+
+      children.clear();
+      children.addAll(this.childrenBuffer);
+
+    } finally {
+      this.childrenBuffer.clear();
+    }
+
+    return children;
+
+  }
+
+}

Propchange: lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/RemoveEmptyNonLeafQueryNodeProcessor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/package.html
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/package.html?rev=800191&view=auto
==============================================================================
--- lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/package.html (added)
+++ lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/package.html Mon Aug  3 03:38:44 2009
@@ -0,0 +1,33 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<!--
+ 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.
+-->
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</head>
+<body>
+
+<h2>Lucene Query Node Processors</h2>
+<p>
+The package org.apache.lucene.queryParser.original.processors contains every processor needed to assembly a pipeline
+that modifies the query node tree according to the actual Lucene queries.
+</p>
+<p>
+This processors are already assembled correctly in the OriginalQueryNodeProcessorPipeline. 
+</p>
+</body>
+</html>

Propchange: lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/original/processors/package.html
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/package.html
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/package.html?rev=800191&view=auto
==============================================================================
--- lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/package.html (added)
+++ lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/package.html Mon Aug  3 03:38:44 2009
@@ -0,0 +1,131 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<!--
+ 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.
+-->
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</head>
+<body>
+
+<h2>Flexible Query Parser</h2>
+<p>
+Features:
+    <ol>
+        <li>Full support for lucene 2.4.2 syntax</li>
+        <li>Full support for boolean logic (not enabled)</li>
+        <li>QueryNode Trees - support for several syntaxes, 
+            that can be converted into similar syntax QueryNode trees.</li>
+        <li>QueryNode Processors - Optimize, validate, rewrite the 
+            QueryNode trees</li>
+		<li>Processors Pipelines - Select your favorite Processor
+		    and build a processor pipeline, to implement the features you need</li>
+        <li>Config Interfaces - Allow the consumer of the Query Parser to implement
+            a diff Config Handler Objects to suite their needs.</li>
+        <li>Original Builders - convert QueryNode's into several lucene 
+            representations. Supported conversion is using a 2.4 compatible logic</li>
+        <li>QueryNode tree's can be converted to a lucene 2.4 syntax string, using toQueryString</li>                          
+    </ol>
+</p>
+
+<tt>
+<p>
+This new query parser was designed to have very generic
+architecture, so that it can be easily used for different
+products with varying query syntaxes. This code is much more 
+flexible and extensible than the Lucene query parser in 2.4.X.
+</p>
+<p>
+The new query parser  goal is to separate syntax and semantics of a query. E.g. 'a AND
+b', '+a +b', 'AND(a,b)' could be different syntaxes for the same query.
+It distinguishes the semantics of the different query components, e.g.
+whether and how to tokenize/lemmatize/normalize the different terms or
+which Query objects to create for the terms. It allows to
+write a parser with a new syntax, while reusing the underlying
+semantics, as quickly as possible.
+</p>
+<p>
+The query parser has three layers and its core is what we call the
+QueryNode tree. It is a tree that initially represents the syntax of the
+original query, e.g. for 'a AND b':
+</p>
+<p>
+  AND<br/>
+ /   \<br/>
+A     B<br/>
+</p>
+<p>
+The three layers are:<br/>
+1. QueryParser<br/>
+2. QueryNodeProcessor<br/>
+3. QueryBuilder<br/>
+</p>
+<p>
+1. This layer is the text parsing layer which simply transforms the
+query text string into a {@link org.apache.lucene.queryParser.core.nodes.QueryNode} tree. Every text parser
+must implement the interface {@link org.apache.lucene.queryParser.core.parser.SyntaxParser}.
+Lucene default implementations implements it using JavaCC.
+</p>
+2. The query node processors do most of the work. It is in fact a
+configurable chain of processors. Each processors can walk the tree and
+modify nodes or even the tree's structure. That makes it possible to
+e.g. do query optimization before the query is executed or to tokenize
+terms.
+</p>
+<p>
+3. The third layer is a configurable map of builders, which map {@link org.apache.lucene.queryParser.core.nodes.QueryNode} types to its specific 
+builder that will transform the QueryNode into Lucene Query object.
+</p>
+<p>
+Furthermore, the query parser uses flexible configuration objects, which
+are based on AttributeSource/Attribute. It also uses message classes that
+allow to attach resource bundles. This makes it possible to translate
+messages, which is an important feature of a query parser.
+</p>
+<p>
+This design allows to develop different query syntaxes very quickly.
+</p>
+<p>
+A original lucene-compatible syntax is implemented using this new query parser
+API and is located under org.apache.lucene.queryParser.original.
+<p>
+To make it simpler to use the new query parser 
+the class {@link org.apache.lucene.queryParser.original.OriginalQueryParserHelper} may be helpful,
+specially for people that do not want to extend the Query Parser.
+It uses the default Lucene query processors, text parser and builders, so
+you don't need to worry about dealing with those.
+
+{@link org.apache.lucene.queryParser.original.OriginalQueryParserHelper} usage:
+<ul>
+OriginalQueryParserHelper qpHelper = new OriginalQueryParserHelper();
+
+<br/><br/>
+OriginalQueryConfigHandler config =  qpHelper.getQueryConfigHandler();
+<br/><br/>
+config.setAllowLeadingWildcard(true);
+<br/><br/>
+config.setAnalyzer(new WhitespaceAnalyzer());
+<br/><br/>
+Query query = qpHelper.parse("apache AND lucene", "defaultField");
+</ul>
+To make it easy for people who are using current Lucene's query parser to switch to
+the new one, there is a {@link org.apache.lucene.queryParser.original.QueryParserWrapper} under org.apache.lucene.queryParser.original
+that keeps the old query parser interface, but uses the new query parser infrastructure.
+</p>
+</p>
+</tt>
+</body>
+</html>

Propchange: lucene/java/trunk/contrib/queryparser/src/java/org/apache/lucene/queryParser/package.html
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/java/trunk/contrib/queryparser/src/java/overview.html
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queryparser/src/java/overview.html?rev=800191&view=auto
==============================================================================
--- lucene/java/trunk/contrib/queryparser/src/java/overview.html (added)
+++ lucene/java/trunk/contrib/queryparser/src/java/overview.html Mon Aug  3 03:38:44 2009
@@ -0,0 +1,39 @@
+<html>
+<!--
+ 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.
+-->
+<head>
+   <title>Apache Lucene Flexible Query Parser</title>
+</head>
+<body>
+
+<h2>Apache Lucene Flexible Query Parser</h2>
+
+<p>
+This contrib project contains the new Lucene query parser implementation, which is going to replace the old query parser on Lucene 3.0. 
+</p>
+
+<p>
+It's currently divided in 3 main packages:
+<ul>
+<li>{@link org.apache.lucene.messages}: it contains the API to defined lazily loaded messages. This message API is used by the new query parser to support localized messages.</li>
+<li>{@link org.apache.lucene.queryParser.core}: it contains the query parser API classes, which should be extended by query parser implementations. </li>
+<li>{@link org.apache.lucene.queryParser.original}: it contains the current Lucene query parser implementation using the new query parser API.</li>
+</ul>
+</p>
+
+</body>
+</html>

Propchange: lucene/java/trunk/contrib/queryparser/src/java/overview.html
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/java/trunk/contrib/queryparser/src/test/org/apache/lucene/messages/MessagesTestBundle.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queryparser/src/test/org/apache/lucene/messages/MessagesTestBundle.java?rev=800191&view=auto
==============================================================================
--- lucene/java/trunk/contrib/queryparser/src/test/org/apache/lucene/messages/MessagesTestBundle.java (added)
+++ lucene/java/trunk/contrib/queryparser/src/test/org/apache/lucene/messages/MessagesTestBundle.java Mon Aug  3 03:38:44 2009
@@ -0,0 +1,40 @@
+package org.apache.lucene.messages;
+
+/**
+ * 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.
+ */
+
+public class MessagesTestBundle extends NLS {
+
+  private static final String BUNDLE_NAME = MessagesTestBundle.class.getName();
+
+  private MessagesTestBundle() {
+    // should never be instantiated
+  }
+
+  static {
+    // register all string ids with NLS class and initialize static string
+    // values
+    NLS.initializeMessages(BUNDLE_NAME, MessagesTestBundle.class);
+  }
+
+  // static string must match the strings in the property files.
+  public static String Q0001E_INVALID_SYNTAX;
+  public static String Q0004E_INVALID_SYNTAX_ESCAPE_UNICODE_TRUNCATION;
+
+  // this message is missing from the properties file
+  public static String Q0005E_MESSAGE_NOT_IN_BUNDLE;
+}

Propchange: lucene/java/trunk/contrib/queryparser/src/test/org/apache/lucene/messages/MessagesTestBundle.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/java/trunk/contrib/queryparser/src/test/org/apache/lucene/messages/MessagesTestBundle.properties
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queryparser/src/test/org/apache/lucene/messages/MessagesTestBundle.properties?rev=800191&view=auto
==============================================================================
--- lucene/java/trunk/contrib/queryparser/src/test/org/apache/lucene/messages/MessagesTestBundle.properties (added)
+++ lucene/java/trunk/contrib/queryparser/src/test/org/apache/lucene/messages/MessagesTestBundle.properties Mon Aug  3 03:38:44 2009
@@ -0,0 +1,3 @@
+Q0001E_INVALID_SYNTAX = Syntax Error: {0}
+
+Q0004E_INVALID_SYNTAX_ESCAPE_UNICODE_TRUNCATION = Truncated unicode escape sequence.

Propchange: lucene/java/trunk/contrib/queryparser/src/test/org/apache/lucene/messages/MessagesTestBundle.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/java/trunk/contrib/queryparser/src/test/org/apache/lucene/messages/MessagesTestBundle_ja.properties
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queryparser/src/test/org/apache/lucene/messages/MessagesTestBundle_ja.properties?rev=800191&view=auto
==============================================================================
--- lucene/java/trunk/contrib/queryparser/src/test/org/apache/lucene/messages/MessagesTestBundle_ja.properties (added)
+++ lucene/java/trunk/contrib/queryparser/src/test/org/apache/lucene/messages/MessagesTestBundle_ja.properties Mon Aug  3 03:38:44 2009
@@ -0,0 +1,3 @@
+Q0001E_INVALID_SYNTAX = \u69cb\u6587\u30a8\u30e9\u30fc: {0}
+
+Q0004E_INVALID_SYNTAX_ESCAPE_UNICODE_TRUNCATION = \u5207\u308a\u6368\u3066\u3089\u308c\u305f\u30e6\u30cb\u30b3\u30fc\u30c9\u30fb\u30a8\u30b9\u30b1\u30fc\u30d7\u30fb\u30b7\u30fc\u30b1\u30f3\u30b9\u3002

Propchange: lucene/java/trunk/contrib/queryparser/src/test/org/apache/lucene/messages/MessagesTestBundle_ja.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/java/trunk/contrib/queryparser/src/test/org/apache/lucene/messages/TestNLS.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queryparser/src/test/org/apache/lucene/messages/TestNLS.java?rev=800191&view=auto
==============================================================================
--- lucene/java/trunk/contrib/queryparser/src/test/org/apache/lucene/messages/TestNLS.java (added)
+++ lucene/java/trunk/contrib/queryparser/src/test/org/apache/lucene/messages/TestNLS.java Mon Aug  3 03:38:44 2009
@@ -0,0 +1,81 @@
+package org.apache.lucene.messages;
+
+/**
+ * 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.Locale;
+
+import junit.framework.TestCase;
+
+/**
+ */
+public class TestNLS extends TestCase {
+  public void testMessageLoading() {
+    Message invalidSyntax = new MessageImpl(
+        MessagesTestBundle.Q0001E_INVALID_SYNTAX, "XXX");
+    assertEquals("Syntax Error: XXX", invalidSyntax.getLocalizedMessage());
+  }
+
+  public void testMessageLoading_ja() {
+    Message invalidSyntax = new MessageImpl(
+        MessagesTestBundle.Q0001E_INVALID_SYNTAX, "XXX");
+    assertEquals("構文エラー: XXX", invalidSyntax
+        .getLocalizedMessage(Locale.JAPANESE));
+  }
+
+  public void testNLSLoading() {
+    String message = NLS
+        .getLocalizedMessage(MessagesTestBundle.Q0004E_INVALID_SYNTAX_ESCAPE_UNICODE_TRUNCATION);
+    assertEquals("Truncated unicode escape sequence.", message);
+
+    message = NLS.getLocalizedMessage(MessagesTestBundle.Q0001E_INVALID_SYNTAX,
+        "XXX");
+    assertEquals("Syntax Error: XXX", message);
+  }
+
+  public void testNLSLoading_ja() {
+    String message = NLS.getLocalizedMessage(
+        MessagesTestBundle.Q0004E_INVALID_SYNTAX_ESCAPE_UNICODE_TRUNCATION,
+        Locale.JAPANESE);
+    assertEquals("切り捨てられたユニコード・エスケープ・シーケンス。", message);
+
+    message = NLS.getLocalizedMessage(MessagesTestBundle.Q0001E_INVALID_SYNTAX,
+        Locale.JAPANESE, "XXX");
+    assertEquals("構文エラー: XXX", message);
+  }
+
+  public void testNLSLoading_xx_XX() {
+    Locale locale = new Locale("xx", "XX", "");
+    String message = NLS.getLocalizedMessage(
+        MessagesTestBundle.Q0004E_INVALID_SYNTAX_ESCAPE_UNICODE_TRUNCATION,
+        locale);
+    assertEquals("Truncated unicode escape sequence.", message);
+
+    message = NLS.getLocalizedMessage(MessagesTestBundle.Q0001E_INVALID_SYNTAX,
+        locale, "XXX");
+    assertEquals("Syntax Error: XXX", message);
+  }
+
+  public void testMissingMessage() {
+    Locale locale = Locale.ENGLISH;
+    String message = NLS.getLocalizedMessage(
+        MessagesTestBundle.Q0005E_MESSAGE_NOT_IN_BUNDLE, locale);
+
+    assertEquals("Message with key:Q0005E_MESSAGE_NOT_IN_BUNDLE and locale: "
+        + locale.toString() + " not found.", message);
+  }
+}

Propchange: lucene/java/trunk/contrib/queryparser/src/test/org/apache/lucene/messages/TestNLS.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/java/trunk/contrib/queryparser/src/test/org/apache/lucene/queryParser/original/TestMultiAnalyzerQPHelper.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queryparser/src/test/org/apache/lucene/queryParser/original/TestMultiAnalyzerQPHelper.java?rev=800191&view=auto
==============================================================================
--- lucene/java/trunk/contrib/queryparser/src/test/org/apache/lucene/queryParser/original/TestMultiAnalyzerQPHelper.java (added)
+++ lucene/java/trunk/contrib/queryparser/src/test/org/apache/lucene/queryParser/original/TestMultiAnalyzerQPHelper.java Mon Aug  3 03:38:44 2009
@@ -0,0 +1,326 @@
+package org.apache.lucene.queryParser.original;
+
+/**
+ * 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.io.IOException;
+import java.io.Reader;
+
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.LowerCaseFilter;
+import org.apache.lucene.analysis.Token;
+import org.apache.lucene.analysis.TokenFilter;
+import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.standard.StandardTokenizer;
+import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
+import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
+import org.apache.lucene.analysis.tokenattributes.TermAttribute;
+import org.apache.lucene.analysis.tokenattributes.TypeAttribute;
+import org.apache.lucene.queryParser.core.QueryNodeException;
+import org.apache.lucene.queryParser.original.OriginalQueryParserHelper;
+import org.apache.lucene.queryParser.original.config.DefaultOperatorAttribute.Operator;
+import org.apache.lucene.util.LuceneTestCase;
+
+/**
+ * This test case is a copy of the core Lucene query parser test, it was adapted
+ * to use new QueryParserHelper instead of the old query parser.
+ * 
+ * Test QueryParser's ability to deal with Analyzers that return more than one
+ * token per position or that return tokens with a position increment &gt; 1.
+ */
+public class TestMultiAnalyzerQPHelper extends LuceneTestCase {
+
+  private static int multiToken = 0;
+
+  public void testMultiAnalyzer() throws QueryNodeException {
+
+    OriginalQueryParserHelper qp = new OriginalQueryParserHelper();
+    qp.setAnalyzer(new MultiAnalyzer());
+
+    // trivial, no multiple tokens:
+    assertEquals("foo", qp.parse("foo", "").toString());
+    assertEquals("foo", qp.parse("\"foo\"", "").toString());
+    assertEquals("foo foobar", qp.parse("foo foobar", "").toString());
+    assertEquals("\"foo foobar\"", qp.parse("\"foo foobar\"", "").toString());
+    assertEquals("\"foo foobar blah\"", qp.parse("\"foo foobar blah\"", "")
+        .toString());
+
+    // two tokens at the same position:
+    assertEquals("(multi multi2) foo", qp.parse("multi foo", "").toString());
+    assertEquals("foo (multi multi2)", qp.parse("foo multi", "").toString());
+    assertEquals("(multi multi2) (multi multi2)", qp.parse("multi multi", "")
+        .toString());
+    assertEquals("+(foo (multi multi2)) +(bar (multi multi2))", qp.parse(
+        "+(foo multi) +(bar multi)", "").toString());
+    assertEquals("+(foo (multi multi2)) field:\"bar (multi multi2)\"", qp
+        .parse("+(foo multi) field:\"bar multi\"", "").toString());
+
+    // phrases:
+    assertEquals("\"(multi multi2) foo\"", qp.parse("\"multi foo\"", "")
+        .toString());
+    assertEquals("\"foo (multi multi2)\"", qp.parse("\"foo multi\"", "")
+        .toString());
+    assertEquals("\"foo (multi multi2) foobar (multi multi2)\"", qp.parse(
+        "\"foo multi foobar multi\"", "").toString());
+
+    // fields:
+    assertEquals("(field:multi field:multi2) field:foo", qp.parse(
+        "field:multi field:foo", "").toString());
+    assertEquals("field:\"(multi multi2) foo\"", qp.parse(
+        "field:\"multi foo\"", "").toString());
+
+    // three tokens at one position:
+    assertEquals("triplemulti multi3 multi2", qp.parse("triplemulti", "")
+        .toString());
+    assertEquals("foo (triplemulti multi3 multi2) foobar", qp.parse(
+        "foo triplemulti foobar", "").toString());
+
+    // phrase with non-default slop:
+    assertEquals("\"(multi multi2) foo\"~10", qp.parse("\"multi foo\"~10", "")
+        .toString());
+
+    // phrase with non-default boost:
+    assertEquals("\"(multi multi2) foo\"^2.0", qp.parse("\"multi foo\"^2", "")
+        .toString());
+
+    // phrase after changing default slop
+    qp.setDefaultPhraseSlop(99);
+    assertEquals("\"(multi multi2) foo\"~99 bar", qp.parse("\"multi foo\" bar",
+        "").toString());
+    assertEquals("\"(multi multi2) foo\"~99 \"foo bar\"~2", qp.parse(
+        "\"multi foo\" \"foo bar\"~2", "").toString());
+    qp.setDefaultPhraseSlop(0);
+
+    // non-default operator:
+    qp.setDefaultOperator(Operator.AND);
+    assertEquals("+(multi multi2) +foo", qp.parse("multi foo", "").toString());
+
+  }
+
+  // public void testMultiAnalyzerWithSubclassOfQueryParser() throws
+  // ParseException {
+  // this test doesn't make sense when using the new QueryParser API
+  // DumbQueryParser qp = new DumbQueryParser("", new MultiAnalyzer());
+  // qp.setPhraseSlop(99); // modified default slop
+  //
+  // // direct call to (super's) getFieldQuery to demonstrate differnce
+  // // between phrase and multiphrase with modified default slop
+  // assertEquals("\"foo bar\"~99",
+  // qp.getSuperFieldQuery("","foo bar").toString());
+  // assertEquals("\"(multi multi2) bar\"~99",
+  // qp.getSuperFieldQuery("","multi bar").toString());
+  //
+  //    
+  // // ask sublcass to parse phrase with modified default slop
+  // assertEquals("\"(multi multi2) foo\"~99 bar",
+  // qp.parse("\"multi foo\" bar").toString());
+  //    
+  // }
+
+  public void testPosIncrementAnalyzer() throws QueryNodeException {
+    OriginalQueryParserHelper qp = new OriginalQueryParserHelper();
+    qp.setAnalyzer(new PosIncrementAnalyzer());
+
+    assertEquals("quick brown", qp.parse("the quick brown", "").toString());
+    assertEquals("\"quick brown\"", qp.parse("\"the quick brown\"", "")
+        .toString());
+    assertEquals("quick brown fox", qp.parse("the quick brown fox", "")
+        .toString());
+    assertEquals("\"quick brown fox\"", qp.parse("\"the quick brown fox\"", "")
+        .toString());
+  }
+
+  /**
+   * Expands "multi" to "multi" and "multi2", both at the same position, and
+   * expands "triplemulti" to "triplemulti", "multi3", and "multi2".
+   */
+  private class MultiAnalyzer extends Analyzer {
+
+    public MultiAnalyzer() {
+    }
+
+    public TokenStream tokenStream(String fieldName, Reader reader) {
+      TokenStream result = new StandardTokenizer(reader);
+      result = new TestFilter(result);
+      result = new LowerCaseFilter(result);
+      return result;
+    }
+  }
+
+  private final class TestFilter extends TokenFilter {
+
+    private String prevType;
+    private int prevStartOffset;
+    private int prevEndOffset;
+
+    TermAttribute termAtt;
+    PositionIncrementAttribute posIncrAtt;
+    OffsetAttribute offsetAtt;
+    TypeAttribute typeAtt;
+
+    public TestFilter(TokenStream in) {
+      super(in);
+      termAtt = (TermAttribute) addAttribute(TermAttribute.class);
+      posIncrAtt = (PositionIncrementAttribute) addAttribute(PositionIncrementAttribute.class);
+      offsetAtt = (OffsetAttribute) addAttribute(OffsetAttribute.class);
+      typeAtt = (TypeAttribute) addAttribute(TypeAttribute.class);
+
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.apache.lucene.analysis.TokenStream#next(org.apache.lucene.analysis
+     * .Token)
+     */
+    @Override
+    public Token next(Token reusableToken) throws IOException {
+
+      if (multiToken > 0) {
+        reusableToken.setTermBuffer("multi" + (multiToken + 1));
+        reusableToken.setStartOffset(prevStartOffset);
+        reusableToken.setEndOffset(prevEndOffset);
+        reusableToken.setType(prevType);
+        reusableToken.setPositionIncrement(0);
+        multiToken--;
+        return reusableToken;
+      } else {
+        boolean next = (reusableToken = input.next(token)) != null;
+        if (next == false) {
+          return null;
+        }
+        prevType = reusableToken.type();
+        prevStartOffset = reusableToken.startOffset();
+        prevEndOffset = reusableToken.endOffset();
+        String text = reusableToken.term();
+        if (text.equals("triplemulti")) {
+          multiToken = 2;
+          return reusableToken;
+        } else if (text.equals("multi")) {
+          multiToken = 1;
+          return reusableToken;
+        } else {
+          return reusableToken;
+        }
+      }
+
+    }
+
+    private Token token = new Token();
+
+    public final boolean incrementToken() throws java.io.IOException {
+      if (multiToken > 0) {
+        termAtt.setTermBuffer("multi" + (multiToken + 1));
+        offsetAtt.setOffset(prevStartOffset, prevEndOffset);
+        typeAtt.setType(prevType);
+        posIncrAtt.setPositionIncrement(0);
+        multiToken--;
+        return true;
+      } else {
+        boolean next = input.incrementToken();
+        if (next == false) {
+          return false;
+        }
+        prevType = typeAtt.type();
+        prevStartOffset = offsetAtt.startOffset();
+        prevEndOffset = offsetAtt.endOffset();
+        String text = termAtt.term();
+        if (text.equals("triplemulti")) {
+          multiToken = 2;
+          return true;
+        } else if (text.equals("multi")) {
+          multiToken = 1;
+          return true;
+        } else {
+          return true;
+        }
+      }
+    }
+
+  }
+
+  /**
+   * Analyzes "the quick brown" as: quick(incr=2) brown(incr=1). Does not work
+   * correctly for input other than "the quick brown ...".
+   */
+  private class PosIncrementAnalyzer extends Analyzer {
+
+    public PosIncrementAnalyzer() {
+    }
+
+    public TokenStream tokenStream(String fieldName, Reader reader) {
+      TokenStream result = new StandardTokenizer(reader);
+      result = new TestPosIncrementFilter(result);
+      result = new LowerCaseFilter(result);
+      return result;
+    }
+  }
+
+  private class TestPosIncrementFilter extends TokenFilter {
+
+    TermAttribute termAtt;
+    PositionIncrementAttribute posIncrAtt;
+
+    public TestPosIncrementFilter(TokenStream in) {
+      super(in);
+      termAtt = (TermAttribute) addAttribute(TermAttribute.class);
+      posIncrAtt = (PositionIncrementAttribute) addAttribute(PositionIncrementAttribute.class);
+    }
+
+    private Token token = new Token();
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.lucene.analysis.TokenStream#next()
+     */
+    @Override
+    public Token next(Token reusableToken) throws IOException {
+      while (null != (reusableToken = input.next(token))) {
+        String term = reusableToken.term();
+        if (term.equals("the")) {
+          // stopword, do nothing
+        } else if (term.equals("quick")) {
+          reusableToken.setPositionIncrement(2);
+          return reusableToken;
+        } else {
+          reusableToken.setPositionIncrement(1);
+          return reusableToken;
+        }
+      }
+      return null;
+    }
+
+    public final boolean incrementToken() throws java.io.IOException {
+      while (input.incrementToken()) {
+        if (termAtt.term().equals("the")) {
+          // stopword, do nothing
+        } else if (termAtt.term().equals("quick")) {
+          posIncrAtt.setPositionIncrement(2);
+          return true;
+        } else {
+          posIncrAtt.setPositionIncrement(1);
+          return true;
+        }
+      }
+      return false;
+    }
+
+  }
+
+}

Propchange: lucene/java/trunk/contrib/queryparser/src/test/org/apache/lucene/queryParser/original/TestMultiAnalyzerQPHelper.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message