lucene-java-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ehatc...@apache.org
Subject svn commit: r209183 [2/2] - in /lucene/java/trunk/contrib/surround: ./ src/ src/java/ src/java/org/ src/java/org/apache/ src/java/org/apache/lucene/ src/java/org/apache/lucene/queryParser/ src/java/org/apache/lucene/queryParser/surround/ src/java/org/a...
Date Tue, 05 Jul 2005 02:29:06 GMT
Added: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/parser/TokenMgrError.java
URL: http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/parser/TokenMgrError.java?rev=209183&view=auto
==============================================================================
--- lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/parser/TokenMgrError.java (added)
+++ lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/parser/TokenMgrError.java Mon Jul  4 19:29:03 2005
@@ -0,0 +1,133 @@
+/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 3.0 */
+package org.apache.lucene.queryParser.surround.parser;
+
+public class TokenMgrError extends Error
+{
+   /*
+    * Ordinals for various reasons why an Error of this type can be thrown.
+    */
+
+   /**
+    * Lexical error occured.
+    */
+   static final int LEXICAL_ERROR = 0;
+
+   /**
+    * An attempt wass made to create a second instance of a static token manager.
+    */
+   static final int STATIC_LEXER_ERROR = 1;
+
+   /**
+    * Tried to change to an invalid lexical state.
+    */
+   static final int INVALID_LEXICAL_STATE = 2;
+
+   /**
+    * Detected (and bailed out of) an infinite loop in the token manager.
+    */
+   static final int LOOP_DETECTED = 3;
+
+   /**
+    * Indicates the reason why the exception is thrown. It will have
+    * one of the above 4 values.
+    */
+   int errorCode;
+
+   /**
+    * Replaces unprintable characters by their espaced (or unicode escaped)
+    * equivalents in the given string
+    */
+   protected static final String addEscapes(String str) {
+      StringBuffer retval = new StringBuffer();
+      char ch;
+      for (int i = 0; i < str.length(); i++) {
+        switch (str.charAt(i))
+        {
+           case 0 :
+              continue;
+           case '\b':
+              retval.append("\\b");
+              continue;
+           case '\t':
+              retval.append("\\t");
+              continue;
+           case '\n':
+              retval.append("\\n");
+              continue;
+           case '\f':
+              retval.append("\\f");
+              continue;
+           case '\r':
+              retval.append("\\r");
+              continue;
+           case '\"':
+              retval.append("\\\"");
+              continue;
+           case '\'':
+              retval.append("\\\'");
+              continue;
+           case '\\':
+              retval.append("\\\\");
+              continue;
+           default:
+              if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
+                 String s = "0000" + Integer.toString(ch, 16);
+                 retval.append("\\u" + s.substring(s.length() - 4, s.length()));
+              } else {
+                 retval.append(ch);
+              }
+              continue;
+        }
+      }
+      return retval.toString();
+   }
+
+   /**
+    * Returns a detailed message for the Error when it is thrown by the
+    * token manager to indicate a lexical error.
+    * Parameters : 
+    *    EOFSeen     : indicates if EOF caused the lexicl error
+    *    curLexState : lexical state in which this error occured
+    *    errorLine   : line number when the error occured
+    *    errorColumn : column number when the error occured
+    *    errorAfter  : prefix that was seen before this error occured
+    *    curchar     : the offending character
+    * Note: You can customize the lexical error message by modifying this method.
+    */
+   protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) {
+      return("Lexical error at line " +
+           errorLine + ", column " +
+           errorColumn + ".  Encountered: " +
+           (EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") +
+           "after : \"" + addEscapes(errorAfter) + "\"");
+   }
+
+   /**
+    * You can also modify the body of this method to customize your error messages.
+    * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
+    * of end-users concern, so you can return something like : 
+    *
+    *     "Internal Error : Please file a bug report .... "
+    *
+    * from this method for such cases in the release version of your parser.
+    */
+   public String getMessage() {
+      return super.getMessage();
+   }
+
+   /*
+    * Constructors of various flavors follow.
+    */
+
+   public TokenMgrError() {
+   }
+
+   public TokenMgrError(String message, int reason) {
+      super(message);
+      errorCode = reason;
+   }
+
+   public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) {
+      this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
+   }
+}

Added: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/AndQuery.java
URL: http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/AndQuery.java?rev=209183&view=auto
==============================================================================
--- lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/AndQuery.java (added)
+++ lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/AndQuery.java Mon Jul  4 19:29:03 2005
@@ -0,0 +1,32 @@
+package org.apache.lucene.queryParser.surround.query;
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.search.Query;
+import org.apache.lucene.search.BooleanClause;
+
+public class AndQuery extends ComposedQuery { 
+  public AndQuery(List queries, boolean inf, String opName) { 
+    super(queries, inf, opName);
+  }
+  
+  public Query makeLuceneQueryFieldNoBoost(String fieldName, BasicQueryFactory qf) {
+    return SrndBooleanQuery.makeBooleanQuery( /* subqueries can be individually boosted */
+      makeLuceneSubQueriesField(fieldName, qf), BooleanClause.Occur.MUST);
+  }
+}

Added: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/BasicQueryFactory.java
URL: http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/BasicQueryFactory.java?rev=209183&view=auto
==============================================================================
--- lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/BasicQueryFactory.java (added)
+++ lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/BasicQueryFactory.java Mon Jul  4 19:29:03 2005
@@ -0,0 +1,64 @@
+package org.apache.lucene.queryParser.surround.query;
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+/* Create basic queries to be used during rewrite.
+ * The basic queries are TermQuery and SpanTermQuery.
+ * An exception can be thrown when too many of these are used.
+ * SpanTermQuery and TermQuery use IndexReader.termEnum(Term), which causes the buffer usage.
+ *
+ * Use this class to limit the buffer usage for reading terms from an index.
+ * Default is 1024, the same as the max. number of subqueries for a BooleanQuery.
+ */
+ 
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.search.spans.SpanTermQuery;
+
+public class BasicQueryFactory {
+  public BasicQueryFactory(int maxBasicQueries) {
+    this.maxBasicQueries = maxBasicQueries;
+    this.queriesMade = 0;
+  }
+  
+  public BasicQueryFactory() {
+    this(1024);
+  }
+  
+  private int maxBasicQueries;
+  private int queriesMade;
+  
+  public int getNrQueriesMade() {return queriesMade;}
+  public int getMaxBasicQueries() {return maxBasicQueries;}
+  
+  private synchronized void checkMax() throws TooManyBasicQueries {
+    if (queriesMade >= maxBasicQueries)
+      throw new TooManyBasicQueries(getMaxBasicQueries());
+    queriesMade++;
+  }
+  
+  public TermQuery newTermQuery(Term term) throws TooManyBasicQueries {
+    checkMax();
+    return new TermQuery(term);
+  }
+  
+  public SpanTermQuery newSpanTermQuery(Term term) throws TooManyBasicQueries {
+    checkMax();
+    return new SpanTermQuery(term);
+  }
+}
+
+

Added: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/ComposedQuery.java
URL: http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/ComposedQuery.java?rev=209183&view=auto
==============================================================================
--- lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/ComposedQuery.java (added)
+++ lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/ComposedQuery.java Mon Jul  4 19:29:03 2005
@@ -0,0 +1,116 @@
+package org.apache.lucene.queryParser.surround.query;
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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 java.util.ArrayList;
+import java.util.Iterator;
+
+public abstract class ComposedQuery extends SrndQuery { 
+  
+  public ComposedQuery(List qs, boolean operatorInfix, String opName) {
+    recompose(qs);
+    this.operatorInfix = operatorInfix;
+    this.opName = opName;
+  }
+  
+  protected void recompose(List queries) {
+    if (queries.size() < 2) throw new AssertionError("Too few subqueries"); 
+    this.queries = queries;
+  }
+  
+  private String opName;
+  public String getOperatorName() {return opName;}
+  
+  private List queries;
+  
+  public Iterator getSubQueriesIterator() {return queries.listIterator();}
+
+  public int getNrSubQueries() {return queries.size();}
+  
+  public SrndQuery getSubQuery(int qn) {return (SrndQuery) queries.get(qn);}
+
+  private boolean operatorInfix; 
+  public boolean isOperatorInfix() { return operatorInfix; } /* else prefix operator */
+  
+  public List makeLuceneSubQueriesField(String fn, BasicQueryFactory qf) {
+    ArrayList luceneSubQueries = new ArrayList();
+    Iterator sqi = getSubQueriesIterator();
+    while (sqi.hasNext()) {
+      luceneSubQueries.add( ((SrndQuery) sqi.next()).makeLuceneQueryField(fn, qf));
+    }
+    return luceneSubQueries;
+  }
+
+  public String toString() {
+    StringBuffer r = new StringBuffer();
+    if (isOperatorInfix()) {
+      infixToString(r);
+    } else {
+      prefixToString(r);
+    }
+    weightToString(r);
+    return r.toString();
+  }
+
+  /* Override for different spacing */
+  protected String getPrefixSeparator() { return ", ";}
+  protected String getBracketOpen() { return "(";}
+  protected String getBracketClose() { return ")";}
+  
+  protected void infixToString(StringBuffer r) {
+    /* Brackets are possibly redundant in the result. */
+    Iterator sqi = getSubQueriesIterator();
+    r.append(getBracketOpen());
+    if (sqi.hasNext()) {
+      r.append(sqi.next().toString());
+      while (sqi.hasNext()) {
+        r.append(" ");
+        r.append(getOperatorName()); /* infix operator */
+        r.append(" ");
+        r.append(sqi.next().toString());
+      }
+    }
+    r.append(getBracketClose());
+  }
+
+  protected void prefixToString(StringBuffer r) {
+    Iterator sqi = getSubQueriesIterator();
+    r.append(getOperatorName()); /* prefix operator */
+    r.append(getBracketOpen());
+    if (sqi.hasNext()) {
+      r.append(sqi.next().toString());
+      while (sqi.hasNext()) {
+        r.append(getPrefixSeparator());
+        r.append(sqi.next().toString());
+      }
+    }
+    r.append(getBracketClose());
+  }
+  
+  
+  public boolean isFieldsSubQueryAcceptable() {
+    /* at least one subquery should be acceptable */
+    Iterator sqi = getSubQueriesIterator();
+    while (sqi.hasNext()) {
+      if (((SrndQuery) sqi.next()).isFieldsSubQueryAcceptable()) {
+        return true;
+      }
+    }
+    return false;
+  }
+}
+

Added: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/DistanceQuery.java
URL: http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/DistanceQuery.java?rev=209183&view=auto
==============================================================================
--- lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/DistanceQuery.java (added)
+++ lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/DistanceQuery.java Mon Jul  4 19:29:03 2005
@@ -0,0 +1,117 @@
+package org.apache.lucene.queryParser.surround.query;
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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 java.util.Iterator;
+
+import java.io.IOException;
+
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.spans.SpanNearQuery;
+import org.apache.lucene.search.spans.SpanQuery;
+
+public class DistanceQuery extends ComposedQuery implements DistanceSubQuery {
+  public DistanceQuery(
+      List queries,
+      boolean infix,
+      int opDistance,
+      String opName,
+      boolean ordered) {
+    super(queries, infix, opName);
+    this.opDistance = opDistance; /* the distance indicated in the operator */
+    this.ordered = ordered;
+  }
+
+  private int opDistance;
+  public int getOpDistance() {return opDistance;}
+  
+  private boolean ordered;
+  public boolean subQueriesOrdered() {return ordered;}
+  
+  public String distanceSubQueryNotAllowed() {
+    Iterator sqi = getSubQueriesIterator();
+    while (sqi.hasNext()) {
+      Object leq = sqi.next();
+      if (leq instanceof DistanceSubQuery) {
+        DistanceSubQuery dsq = (DistanceSubQuery) leq;
+        String m = dsq.distanceSubQueryNotAllowed();
+        if (m != null) {
+          return m; 
+        }
+      } else {
+        return "Operator " + getOperatorName() + " does not allow subquery " + leq.toString();
+      }
+    }
+    return null; /* subqueries acceptable */
+  }
+
+  
+  public void addSpanQueries(SpanNearClauseFactory sncf) throws IOException {
+    Query snq = getSpanNearQuery(sncf.getIndexReader(),
+                                  sncf.getFieldName(),
+                                  getWeight(),
+                                  sncf.getBasicQueryFactory());
+    sncf.addSpanNearQuery(snq);
+  }
+
+  public Query makeLuceneQueryFieldNoBoost(final String fieldName, final BasicQueryFactory qf) {
+    return new Query () {
+      
+      public String toString(String fn) {
+        return getClass().toString() + " " + fieldName + " (" + fn + "?)";
+      }
+      
+      public Query rewrite(IndexReader reader) throws IOException {
+        return getSpanNearQuery(reader, fieldName, getBoost(), qf);
+      }
+      
+    };
+  }
+  
+  public Query getSpanNearQuery(
+          IndexReader reader,
+          String fieldName,
+          float boost,
+          BasicQueryFactory qf) throws IOException {
+    SpanQuery[] spanNearClauses = new SpanQuery[getNrSubQueries()];
+    Iterator sqi = getSubQueriesIterator();
+    int qi = 0;
+    while (sqi.hasNext()) {
+      SpanNearClauseFactory sncf = new SpanNearClauseFactory(reader, fieldName, qf);
+      
+      ((DistanceSubQuery)sqi.next()).addSpanQueries(sncf);
+      if (sncf.size() == 0) { /* distance operator requires all sub queries */
+        while (sqi.hasNext()) { /* produce evt. error messages but ignore results */
+          ((DistanceSubQuery)sqi.next()).addSpanQueries(sncf);
+          sncf.clear();
+        }
+        return SrndQuery.theEmptyLcnQuery;
+      }
+      
+      spanNearClauses[qi] = sncf.makeSpanNearClause();
+
+      qi++;
+    }
+    
+    SpanNearQuery r = new SpanNearQuery(spanNearClauses, getOpDistance() - 1, subQueriesOrdered());
+    r.setBoost(boost);
+    return r;
+  }
+}
+

Added: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/DistanceSubQuery.java
URL: http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/DistanceSubQuery.java?rev=209183&view=auto
==============================================================================
--- lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/DistanceSubQuery.java (added)
+++ lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/DistanceSubQuery.java Mon Jul  4 19:29:03 2005
@@ -0,0 +1,30 @@
+package org.apache.lucene.queryParser.surround.query;
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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;
+
+public interface DistanceSubQuery {
+  /** When distanceSubQueryNotAllowed() returns non null, the reason why the subquery
+   * is not allowed as a distance subquery is returned.
+   * <br>When distanceSubQueryNotAllowed() returns null addSpanNearQueries() can be used
+   * in the creation of the span near clause for the subquery.
+   */
+  String distanceSubQueryNotAllowed();
+    
+  void addSpanQueries(SpanNearClauseFactory sncf) throws IOException;
+}
+

Added: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/FieldsQuery.java
URL: http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/FieldsQuery.java?rev=209183&view=auto
==============================================================================
--- lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/FieldsQuery.java (added)
+++ lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/FieldsQuery.java Mon Jul  4 19:29:03 2005
@@ -0,0 +1,93 @@
+package org.apache.lucene.queryParser.surround.query;
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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 java.util.Iterator;
+
+import org.apache.lucene.search.Query;
+
+public class FieldsQuery extends SrndQuery { /* mostly untested */
+  private SrndQuery q;
+  private ArrayList fieldNames;
+  private final char fieldOp;
+  private final String OrOperatorName = "OR"; /* for expanded queries, not normally visible */
+  
+  public FieldsQuery(SrndQuery q, ArrayList fieldNames, char fieldOp) {
+    this.q = q;
+    this.fieldNames = fieldNames;
+    this.fieldOp = fieldOp;
+  }
+  
+  public FieldsQuery(SrndQuery q, String fieldName, char fieldOp) {
+    this.q = q;
+    fieldNames = new ArrayList();
+    fieldNames.add(fieldName);
+    this.fieldOp = fieldOp;
+  }
+  
+  public boolean isFieldsSubQueryAcceptable() {
+    return false;
+  }
+  
+  public Query makeLuceneQueryNoBoost(BasicQueryFactory qf) {
+    if (fieldNames.size() == 1) { /* single field name: no new queries needed */
+      return q.makeLuceneQueryFieldNoBoost((String) fieldNames.get(0), qf);
+    } else { /* OR query over the fields */
+      ArrayList queries = new ArrayList();
+      Iterator fni = getFieldNames().listIterator();
+      SrndQuery qc;
+      while (fni.hasNext()) {
+        qc = (SrndQuery) q.clone();
+        queries.add( new FieldsQuery( qc, (String) fni.next(), fieldOp));
+      }
+      boolean infix = true;
+      OrQuery oq = new OrQuery(queries,
+                              true /* infix OR for field names */,
+                              OrOperatorName);
+      System.out.println(getClass().toString() + ", fields expanded: " + oq.toString()); /* needs testing */
+      return oq.makeLuceneQueryField(null, qf);
+    }
+  }
+
+  public Query makeLuceneQueryFieldNoBoost(String fieldName, BasicQueryFactory qf) {
+    return makeLuceneQueryNoBoost(qf); /* use this.fieldNames instead of fieldName */
+  }
+
+  
+  public List getFieldNames() {return fieldNames;}
+
+  public char getFieldOperator() { return fieldOp;}
+  
+  public String toString() {
+    StringBuffer r = new StringBuffer();
+    r.append("(");
+    fieldNamesToString(r);
+    r.append(q.toString());
+    r.append(")");
+    return r.toString();
+  }
+  
+  protected void fieldNamesToString(StringBuffer r) {
+    Iterator fni = getFieldNames().listIterator();
+    while (fni.hasNext()) {
+      r.append((String) fni.next());
+      r.append(getFieldOperator());
+    }
+  }
+}
+

Added: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/NotQuery.java
URL: http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/NotQuery.java?rev=209183&view=auto
==============================================================================
--- lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/NotQuery.java (added)
+++ lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/NotQuery.java Mon Jul  4 19:29:03 2005
@@ -0,0 +1,37 @@
+package org.apache.lucene.queryParser.surround.query;
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.search.Query;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.BooleanClause;
+
+public class NotQuery extends ComposedQuery { 
+  public NotQuery(List queries, String opName) { super(queries, true /* infix */, opName); }
+  
+  public Query makeLuceneQueryFieldNoBoost(String fieldName, BasicQueryFactory qf) {
+    List luceneSubQueries = makeLuceneSubQueriesField(fieldName, qf);
+    BooleanQuery bq = new BooleanQuery();
+    bq.add( (Query) luceneSubQueries.get(0), BooleanClause.Occur.MUST);
+    SrndBooleanQuery.addQueriesToBoolean(bq,
+            // FIXME: do not allow weights on prohibited subqueries.
+            luceneSubQueries.subList(1, luceneSubQueries.size()),
+            // later subqueries: not required, prohibited
+            BooleanClause.Occur.MUST_NOT);
+    return bq;
+  }
+}

Added: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/OrQuery.java
URL: http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/OrQuery.java?rev=209183&view=auto
==============================================================================
--- lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/OrQuery.java (added)
+++ lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/OrQuery.java Mon Jul  4 19:29:03 2005
@@ -0,0 +1,59 @@
+package org.apache.lucene.queryParser.surround.query;
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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 java.util.Iterator;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.BooleanClause;
+
+import java.io.IOException;
+
+public class OrQuery extends ComposedQuery implements DistanceSubQuery { 
+  public OrQuery(List queries, boolean infix, String opName) {
+    super(queries, infix, opName);
+  }
+  
+  public Query makeLuceneQueryFieldNoBoost(String fieldName, BasicQueryFactory qf) {
+    return SrndBooleanQuery.makeBooleanQuery(
+      /* subqueries can be individually boosted */
+      makeLuceneSubQueriesField(fieldName, qf), BooleanClause.Occur.SHOULD);
+  }
+  
+  public String distanceSubQueryNotAllowed() {
+    Iterator sqi = getSubQueriesIterator();
+    while (sqi.hasNext()) {
+      SrndQuery leq = (SrndQuery) sqi.next();
+      if (leq instanceof DistanceSubQuery) {
+        String m = ((DistanceSubQuery)leq).distanceSubQueryNotAllowed();
+        if (m != null) {
+          return m;
+        }
+      } else {
+        return "subquery not allowed: " + leq.toString();
+      }
+    }
+    return null;
+  }
+    
+  public void addSpanQueries(SpanNearClauseFactory sncf) throws IOException {
+    Iterator sqi = getSubQueriesIterator();
+    while (sqi.hasNext()) {
+      ((DistanceSubQuery)sqi.next()).addSpanQueries(sncf);
+    }
+  }
+}
+

Added: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SimpleTerm.java
URL: http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SimpleTerm.java?rev=209183&view=auto
==============================================================================
--- lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SimpleTerm.java (added)
+++ lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SimpleTerm.java Mon Jul  4 19:29:03 2005
@@ -0,0 +1,109 @@
+package org.apache.lucene.queryParser.surround.query;
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.io.IOException;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.BooleanClause;
+
+public abstract class SimpleTerm
+  extends SrndQuery
+  implements DistanceSubQuery, Comparable
+{
+  public SimpleTerm(boolean q) {quoted = q;}
+  
+  private boolean quoted;
+  boolean isQuoted() {return quoted;}
+  
+  public String getQuote() {return "\"";}
+  public String getFieldOperator() {return "/";}
+  
+  public abstract String toStringUnquoted();
+  
+  public int compareTo(Object o) {
+    /* for ordering terms and prefixes before using an index, not used */
+    SimpleTerm ost = (SimpleTerm) o;
+    return this.toStringUnquoted().compareTo( ost.toStringUnquoted());
+  }
+  
+  protected void suffixToString(StringBuffer r) {;} /* override for prefix query */
+  
+  public String toString() {
+    StringBuffer r = new StringBuffer();
+    if (isQuoted()) {
+      r.append(getQuote());
+    }
+    r.append(toStringUnquoted());
+    if (isQuoted()) {
+      r.append(getQuote());
+    }
+    suffixToString(r);
+    weightToString(r);
+    return r.toString();
+  }
+  
+  public abstract void visitMatchingTerms(
+                            IndexReader reader,
+                            String fieldName,
+                            MatchingTermVisitor mtv) throws IOException;
+  
+  public interface MatchingTermVisitor {
+    void visitMatchingTerm(Term t)throws IOException;
+  }
+
+  public String distanceSubQueryNotAllowed() {return null;}
+
+  
+  public Query makeLuceneQueryFieldNoBoost(final String fieldName, final BasicQueryFactory qf) {
+    return new Query() {
+      public String toString(String fn) {
+        return getClass().toString() + " " + fieldName + " (" + fn + "?)";
+      }
+      
+      public Query rewrite(IndexReader reader) throws IOException {
+        final ArrayList luceneSubQueries = new ArrayList();
+        visitMatchingTerms( reader, fieldName,
+            new MatchingTermVisitor() {
+              public void visitMatchingTerm(Term term) throws IOException {
+                luceneSubQueries.add(qf.newTermQuery(term));
+              }
+            });
+        return  (luceneSubQueries.size() == 0) ? SrndQuery.theEmptyLcnQuery
+              : (luceneSubQueries.size() == 1) ? (Query) luceneSubQueries.get(0)
+              : SrndBooleanQuery.makeBooleanQuery(
+                  /* luceneSubQueries all have default weight */
+                  luceneSubQueries, BooleanClause.Occur.SHOULD); /* OR the subquery terms */ 
+      }
+    };
+  }
+    
+  public void addSpanQueries(final SpanNearClauseFactory sncf) throws IOException {
+    visitMatchingTerms(
+          sncf.getIndexReader(),
+          sncf.getFieldName(),
+          new MatchingTermVisitor() {
+            public void visitMatchingTerm(Term term) throws IOException {
+              sncf.addTermWeighted(term, getWeight());
+            }
+          });
+  }
+}
+
+
+

Added: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SpanNearClauseFactory.java
URL: http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SpanNearClauseFactory.java?rev=209183&view=auto
==============================================================================
--- lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SpanNearClauseFactory.java (added)
+++ lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SpanNearClauseFactory.java Mon Jul  4 19:29:03 2005
@@ -0,0 +1,153 @@
+package org.apache.lucene.queryParser.surround.query;
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+/*
+SpanNearClauseFactory:
+
+Operations:
+
+- create for a field name and an indexreader.
+
+- add a weighted Term
+  this should add a corresponding SpanTermQuery, or
+  increase the weight of an existing one.
+  
+- add a weighted subquery SpanNearQuery 
+
+- create a clause for SpanNearQuery from the things added above.
+  For this, create an array of SpanQuery's from the added ones.
+  The clause normally is a SpanOrQuery over the added subquery SpanNearQuery
+  the SpanTermQuery's for the added Term's
+*/
+
+/* When  it is necessary to suppress double subqueries as much as possible:
+   hashCode() and equals() on unweighted SpanQuery are needed (possibly via getTerms(),
+   the terms are individually hashable).
+   Idem SpanNearQuery: hash on the subqueries and the slop.
+   Evt. merge SpanNearQuery's by adding the weights of the corresponding subqueries.
+ */
+ 
+/* To be determined:
+   Are SpanQuery weights handled correctly during search by Lucene?
+   Should the resulting SpanOrQuery be sorted?
+   Could other SpanQueries be added for use in this factory:
+   - SpanOrQuery: in principle yes, but it only has access to it's terms
+                  via getTerms(); are the corresponding weights available?
+   - SpanFirstQuery: treat similar to subquery SpanNearQuery. (ok?)
+   - SpanNotQuery: treat similar to subquery SpanNearQuery. (ok?)
+ */
+
+import java.util.HashMap;
+import java.util.Iterator;
+
+import java.util.Comparator;
+import java.util.Arrays;
+
+import java.io.IOException;
+
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.index.TermEnum;
+
+import org.apache.lucene.search.Query;
+
+import org.apache.lucene.search.spans.SpanQuery;
+import org.apache.lucene.search.spans.SpanNearQuery;
+import org.apache.lucene.search.spans.SpanOrQuery;
+import org.apache.lucene.search.spans.SpanTermQuery;
+
+
+public class SpanNearClauseFactory {
+  public SpanNearClauseFactory(IndexReader reader, String fieldName, BasicQueryFactory qf) {
+    this.reader = reader;
+    this.fieldName = fieldName;
+    this.weightBySpanQuery = new HashMap(); 
+    this.qf = qf;
+  }
+  private IndexReader reader;
+  private String fieldName;
+  private HashMap weightBySpanQuery;
+  private BasicQueryFactory qf;
+  
+  public IndexReader getIndexReader() {return reader;}
+  
+  public String getFieldName() {return fieldName;}
+
+  public BasicQueryFactory getBasicQueryFactory() {return qf;}
+  
+  public TermEnum getTermEnum(String termText) throws IOException {
+    return getIndexReader().terms(new Term(getFieldName(), termText));
+  }
+  
+  public int size() {return weightBySpanQuery.size();}
+  
+  public void clear() {weightBySpanQuery.clear();}
+
+  protected void addSpanQueryWeighted(SpanQuery sq, float weight) {
+    Float w = (Float) weightBySpanQuery.get(sq);
+    if (w != null)
+      w = new Float(w.floatValue() + weight);
+    else
+      w = new Float(weight);
+    weightBySpanQuery.put(sq, w); 
+  }
+  
+  public void addTermWeighted(Term t, float weight) throws IOException {   
+    SpanTermQuery stq = qf.newSpanTermQuery(t);
+    /* CHECKME: wrap in Hashable...? */
+    addSpanQueryWeighted(stq, weight);
+  }
+  
+  public void addSpanNearQuery(Query q) {
+    if (q == SrndQuery.theEmptyLcnQuery)
+      return;
+    if (! (q instanceof SpanNearQuery))
+      throw new AssertionError("Expected SpanNearQuery: " + q.toString(getFieldName()));
+    /* CHECKME: wrap in Hashable...? */
+    addSpanQueryWeighted((SpanNearQuery)q, q.getBoost());
+  }
+  
+  public SpanQuery makeSpanNearClause() {
+    SpanQuery [] spanQueries = new SpanQuery[size()];
+    Iterator sqi = weightBySpanQuery.keySet().iterator();
+    int i = 0;
+    while (sqi.hasNext()) {
+      SpanQuery sq = (SpanQuery) sqi.next();
+      sq.setBoost(((Float)weightBySpanQuery.get(sq)).floatValue());
+      spanQueries[i++] = sq;
+    }
+    
+    /* CHECKME: Does the underlying implementation of SpanQuery need sorting? */
+    if (false) /* true when sorting needed */
+      Arrays.sort(spanQueries, new Comparator() { 
+        public int compare(Object o1, Object o2) {
+          SpanQuery sq1 = (SpanQuery) o1;
+          SpanQuery sq2 = (SpanQuery) o2;
+          /* compare the text of the first term of each SpanQuery */
+          return  ((Term)sq1.getTerms().iterator().next()).text().compareTo(
+                  ((Term)sq2.getTerms().iterator().next()).text());
+        }
+        public boolean equals(Object o) {return false;}
+      });
+       
+    if (spanQueries.length == 1)
+      return spanQueries[0];
+    else
+      return new SpanOrQuery(spanQueries);
+  }
+}
+

Added: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SrndBooleanQuery.java
URL: http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SrndBooleanQuery.java?rev=209183&view=auto
==============================================================================
--- lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SrndBooleanQuery.java (added)
+++ lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SrndBooleanQuery.java Mon Jul  4 19:29:03 2005
@@ -0,0 +1,44 @@
+package org.apache.lucene.queryParser.surround.query;
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.search.Query;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.BooleanClause;
+
+class SrndBooleanQuery {
+  public static void addQueriesToBoolean(
+          BooleanQuery bq,
+          List queries,
+          BooleanClause.Occur occur) {
+    for (int i = 0; i < queries.size(); i++) {
+      bq.add( (Query) queries.get(i), occur);
+    }
+  }
+  
+  public static Query makeBooleanQuery(
+          List queries,
+          BooleanClause.Occur occur) {
+    if (queries.size() <= 1) {
+      throw new AssertionError("Too few subqueries: " + queries.size());
+    }
+    BooleanQuery bq = new BooleanQuery();
+    addQueriesToBoolean(bq, queries.subList(0, queries.size()), occur);
+    return bq;
+  }
+}

Added: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SrndPrefixQuery.java
URL: http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SrndPrefixQuery.java?rev=209183&view=auto
==============================================================================
--- lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SrndPrefixQuery.java (added)
+++ lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SrndPrefixQuery.java Mon Jul  4 19:29:03 2005
@@ -0,0 +1,75 @@
+package org.apache.lucene.queryParser.surround.query;
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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 org.apache.lucene.index.Term;
+import org.apache.lucene.index.TermEnum;
+import org.apache.lucene.index.IndexReader;
+
+import java.io.IOException;
+
+
+public class SrndPrefixQuery extends SimpleTerm {
+  public SrndPrefixQuery(String prefix, boolean quoted, char truncator) {
+    super(quoted);
+    this.prefix = prefix;
+    this.truncator = truncator;
+  }
+
+  private final String prefix;
+  public String getPrefix() {return prefix;}
+  
+  private final char truncator;
+  public char getSuffixOperator() {return truncator;}
+  
+  public Term getLucenePrefixTerm(String fieldName) {
+    return new Term(fieldName, getPrefix());
+  }
+  
+  public String toStringUnquoted() {return getPrefix();}
+  
+  protected void suffixToString(StringBuffer r) {r.append(getSuffixOperator());}
+  
+  public void visitMatchingTerms(
+    IndexReader reader,
+    String fieldName,
+    MatchingTermVisitor mtv) throws IOException
+  {
+    /* inspired by PrefixQuery.rewrite(): */
+    TermEnum enumerator = reader.terms(getLucenePrefixTerm(fieldName));
+    boolean expanded = false;
+    try {
+      do {
+        Term term = enumerator.term();
+        if ((term != null)
+            && term.text().startsWith(getPrefix())
+            && term.field().equals(fieldName)) {
+          mtv.visitMatchingTerm(term);
+          expanded = true;
+        } else {
+          break;
+        }
+      } while (enumerator.next());
+    } finally {
+      enumerator.close();
+    }
+    if (! expanded) {
+      System.out.println("No terms in " + fieldName + " field for: " + toString());
+    }
+  }
+}

Added: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SrndQuery.java
URL: http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SrndQuery.java?rev=209183&view=auto
==============================================================================
--- lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SrndQuery.java (added)
+++ lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SrndQuery.java Mon Jul  4 19:29:03 2005
@@ -0,0 +1,86 @@
+package org.apache.lucene.queryParser.surround.query;
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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 java.util.Iterator;
+
+import java.io.IOException;
+
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.BooleanClause;
+
+public abstract class SrndQuery implements Cloneable {
+  public SrndQuery() {}
+  
+  private float weight = (float) 1.0;
+  private boolean weighted = false;
+
+  public void setWeight(float w) {
+    weight = w; /* as parsed from the query text */
+    weighted = true;
+  } 
+  public boolean isWeighted() {return weighted;}
+  public float getWeight() { return weight; }
+  public String getWeightString() {return Float.toString(getWeight());}
+
+  public String getWeightOperator() {return "^";}
+
+  protected void weightToString(StringBuffer r) { /* append the weight part of a query */
+    if (isWeighted()) {
+      r.append(getWeightOperator());
+      r.append(getWeightString());
+    }
+  }
+  
+  public Query makeLuceneQueryField(String fieldName, BasicQueryFactory qf){
+    Query q = makeLuceneQueryFieldNoBoost(fieldName, qf);
+    if (isWeighted()) {
+      q.setBoost(getWeight() * q.getBoost()); /* weight may be at any level in a SrndQuery */
+    }
+    return q;
+  }
+  
+  public abstract Query makeLuceneQueryFieldNoBoost(String fieldName, BasicQueryFactory qf);
+  
+  public abstract String toString();
+  
+  public boolean isFieldsSubQueryAcceptable() {return true;}
+    
+  public Object clone() {
+    try {
+      return super.clone();
+    } catch (CloneNotSupportedException cns) {
+      throw new Error(cns);
+    }
+  }
+  
+/* An empty Lucene query */
+  public final static Query theEmptyLcnQuery = new BooleanQuery() { /* no changes allowed */
+    public void setBoost(float boost) {
+      throw new UnsupportedOperationException();
+    }
+    public void add(BooleanClause clause) {
+      throw new UnsupportedOperationException();
+    }
+    public void add(Query query, BooleanClause.Occur occur) {
+      throw new UnsupportedOperationException();
+    }
+  };
+}
+

Added: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SrndTermQuery.java
URL: http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SrndTermQuery.java?rev=209183&view=auto
==============================================================================
--- lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SrndTermQuery.java (added)
+++ lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SrndTermQuery.java Mon Jul  4 19:29:03 2005
@@ -0,0 +1,67 @@
+package org.apache.lucene.queryParser.surround.query;
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.search.Query;
+import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.index.TermEnum;
+
+import org.apache.lucene.index.IndexReader;
+import java.io.IOException;
+
+ 
+public class SrndTermQuery extends SimpleTerm {
+  public SrndTermQuery(String termText, boolean quoted) {
+    super(quoted);
+    this.termText = termText;
+  }
+
+  private final String termText;
+  public String getTermText() {return termText;}
+        
+  public Term getLuceneTerm(String fieldName) {
+    return new Term(fieldName, getTermText());
+  }
+  
+  public String toStringUnquoted() {return getTermText();}
+  
+  public void visitMatchingTerms(
+    IndexReader reader,
+    String fieldName,
+    MatchingTermVisitor mtv) throws IOException
+  {
+    /* check term presence in index here for symmetry with other SimpleTerm's */
+    TermEnum enumerator = reader.terms(getLuceneTerm(fieldName));
+    try {
+      Term it= enumerator.term(); /* same or following index term */
+      if ((it != null)
+          && it.text().equals(getTermText())
+          && it.field().equals(fieldName)) {
+        mtv.visitMatchingTerm(it);
+      } else {
+        System.out.println("No term in " + fieldName + " field for: " + toString());
+      }
+    } finally {
+      enumerator.close();
+    }
+  }
+}
+  
+
+

Added: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SrndTruncQuery.java
URL: http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SrndTruncQuery.java?rev=209183&view=auto
==============================================================================
--- lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SrndTruncQuery.java (added)
+++ lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SrndTruncQuery.java Mon Jul  4 19:29:03 2005
@@ -0,0 +1,111 @@
+package org.apache.lucene.queryParser.surround.query;
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.index.Term;
+import org.apache.lucene.index.TermEnum;
+import org.apache.lucene.index.IndexReader;
+
+import java.io.IOException;
+
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+
+public class SrndTruncQuery extends SimpleTerm {
+  public SrndTruncQuery(String truncated, char unlimited, char mask) {
+    super(false); /* not quoted */
+    this.truncated = truncated;
+    this.unlimited = unlimited;
+    this.mask = mask;
+    truncatedToPrefixAndPattern();
+  }
+  
+  private final String truncated;
+  private final char unlimited;
+  private final char mask;
+  
+  private String prefix;
+  private Pattern pattern;
+  
+  
+  public String getTruncated() {return truncated;}
+  
+  public String toStringUnquoted() {return getTruncated();}
+
+  
+  protected boolean matchingChar(char c) {
+    return (c != unlimited) && (c != mask);
+  }
+
+  protected void appendRegExpForChar(char c, StringBuffer re) {
+    if (c == unlimited)
+      re.append(".*");
+    else if (c == mask)
+      re.append(".");
+    else
+      re.append(c);
+  }
+  
+  protected void truncatedToPrefixAndPattern() {
+    int i = 0;
+    while ((i < truncated.length()) && matchingChar(truncated.charAt(i))) {
+      i++;
+    }
+    prefix = truncated.substring(0, i);
+    
+    StringBuffer re = new StringBuffer();
+    while (i < truncated.length()) {
+      appendRegExpForChar(truncated.charAt(i), re);
+      i++;
+    }
+    pattern = Pattern.compile(re.toString());
+  }
+  
+  public void visitMatchingTerms(
+    IndexReader reader,
+    String fieldName,
+    MatchingTermVisitor mtv) throws IOException
+  {
+    boolean expanded = false;
+    int prefixLength = prefix.length();
+    TermEnum enumerator = reader.terms(new Term(fieldName, prefix));
+    Matcher matcher = pattern.matcher("");
+    try {
+      do {
+        Term term = enumerator.term();
+        if (term != null) {
+          String text = term.text();
+          if ((! text.startsWith(prefix)) || (! term.field().equals(fieldName))) {
+            break;
+          } else {
+            matcher.reset( text.substring(prefixLength));
+            if (matcher.matches()) {
+              mtv.visitMatchingTerm(term);
+              expanded = true;
+            }
+          }
+        }
+      } while (enumerator.next());
+    } finally {
+      enumerator.close();
+      matcher.reset();
+    }
+    if (! expanded) {
+      System.out.println("No terms in " + fieldName + " field for: " + toString());
+    }
+  }
+}

Added: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/TooManyBasicQueries.java
URL: http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/TooManyBasicQueries.java?rev=209183&view=auto
==============================================================================
--- lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/TooManyBasicQueries.java (added)
+++ lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/TooManyBasicQueries.java Mon Jul  4 19:29:03 2005
@@ -0,0 +1,26 @@
+package org.apache.lucene.queryParser.surround.query;
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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; /* subclass to be usable from within Query.rewrite() */
+
+public class TooManyBasicQueries extends IOException {
+  public TooManyBasicQueries(int maxBasicQueries) {
+    super("Exceeded maximum of " + maxBasicQueries + " basic queries.");
+  }
+}
+  
+

Added: lucene/java/trunk/contrib/surround/src/test/org/apache/lucene/queryParser/surround/query/BooleanQueryTest.java
URL: http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/surround/src/test/org/apache/lucene/queryParser/surround/query/BooleanQueryTest.java?rev=209183&view=auto
==============================================================================
--- lucene/java/trunk/contrib/surround/src/test/org/apache/lucene/queryParser/surround/query/BooleanQueryTest.java (added)
+++ lucene/java/trunk/contrib/surround/src/test/org/apache/lucene/queryParser/surround/query/BooleanQueryTest.java Mon Jul  4 19:29:03 2005
@@ -0,0 +1,94 @@
+package org.apache.lucene.queryParser.surround.query;
+
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Searcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.HitCollector;
+
+import org.apache.lucene.queryParser.surround.parser.QueryParser;
+
+import junit.framework.TestCase;
+
+public class BooleanQueryTest {
+  String queryText;
+  final int[] expectedDocNrs;
+  SingleFieldTestDb dBase;
+  String fieldName;
+  TestCase testCase;
+  BasicQueryFactory qf;
+  boolean verbose = true;
+
+  public BooleanQueryTest(
+      String queryText,
+      int[] expectedDocNrs,
+      SingleFieldTestDb dBase,
+      String fieldName,
+      TestCase testCase,
+      BasicQueryFactory qf) {
+    this.queryText = queryText;
+    this.expectedDocNrs = expectedDocNrs;
+    this.dBase = dBase;
+    this.fieldName = fieldName;
+    this.testCase = testCase;
+    this.qf = qf;
+  }
+  
+  public void setVerbose(boolean verbose) {this.verbose = verbose;}
+
+  class TestCollector extends HitCollector { // FIXME: use check hits from Lucene tests
+    int totalMatched;
+    boolean[] encountered;
+
+    TestCollector() {
+      totalMatched = 0;
+      encountered = new boolean[expectedDocNrs.length];
+    }
+
+    public void collect(int docNr, float score) {
+      /* System.out.println(docNr + " '" + dBase.getDocs()[docNr] + "': " + score); */
+      testCase.assertTrue(queryText + ": positive score", score > 0.0);
+      testCase.assertTrue(queryText + ": too many hits", totalMatched < expectedDocNrs.length);
+      int i;
+      for (i = 0; i < expectedDocNrs.length; i++) {
+        if ((! encountered[i]) && (expectedDocNrs[i] == docNr)) {
+          encountered[i] = true;
+          break;
+        }
+      }
+      if (i == expectedDocNrs.length) {
+        testCase.assertTrue(queryText + ": doc nr for hit not expected: " + docNr, false);
+      }
+      totalMatched++;
+    }
+
+    void checkNrHits() {
+      testCase.assertEquals(queryText + ": nr of hits", expectedDocNrs.length, totalMatched);
+    }
+  }
+
+  public void doTest() throws Exception {
+    QueryParser parser = new QueryParser();
+
+    if (verbose) {    
+        System.out.println("");
+        System.out.println("Query: " + queryText);
+    }
+    
+    SrndQuery lq = parser.parse(queryText);
+    
+    /* if (verbose) System.out.println("Srnd: " + lq.toString()); */
+    
+    Query query = lq.makeLuceneQueryField(fieldName, qf);
+    /* if (verbose) System.out.println("Lucene: " + query.toString()); */
+
+    TestCollector tc = new TestCollector();
+    Searcher searcher = new IndexSearcher(dBase.getDb());
+    try {
+      searcher.search(query, tc);
+    } finally {
+      searcher.close();
+    }
+    tc.checkNrHits();
+  }
+}
+

Added: lucene/java/trunk/contrib/surround/src/test/org/apache/lucene/queryParser/surround/query/ExceptionQueryTest.java
URL: http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/surround/src/test/org/apache/lucene/queryParser/surround/query/ExceptionQueryTest.java?rev=209183&view=auto
==============================================================================
--- lucene/java/trunk/contrib/surround/src/test/org/apache/lucene/queryParser/surround/query/ExceptionQueryTest.java (added)
+++ lucene/java/trunk/contrib/surround/src/test/org/apache/lucene/queryParser/surround/query/ExceptionQueryTest.java Mon Jul  4 19:29:03 2005
@@ -0,0 +1,55 @@
+package org.apache.lucene.queryParser.surround.query;
+
+import org.apache.lucene.search.Query;
+
+import org.apache.lucene.queryParser.surround.parser.QueryParser;
+import org.apache.lucene.queryParser.surround.parser.ParseException;
+
+import junit.framework.TestCase;
+
+
+public class ExceptionQueryTest {
+  private String queryText;
+  private boolean verbose;
+  private TestCase testCase;
+  
+  public ExceptionQueryTest(String queryText, boolean verbose) {
+    this.queryText = queryText;
+    this.verbose = verbose;
+    this.testCase = testCase;
+  }
+
+  public void doTest(StringBuffer failQueries) {
+    QueryParser parser = new QueryParser();
+    boolean pass = false;
+    SrndQuery lq = null;
+    try {
+      lq = parser.parse(queryText);
+      if (verbose) {
+        System.out.println("Query: " + queryText + "\nParsed as: " + lq.toString());
+      }
+    } catch (ParseException e) {
+      if (verbose) {
+        System.out.println("Parse exception for query:\n"
+                            + queryText + "\n"
+                            + e.getMessage());
+      }
+      pass = true;
+    }
+    if (! pass) {
+      failQueries.append(queryText);
+      failQueries.append("\nParsed as: ");
+      failQueries.append(lq.toString());
+      failQueries.append("\n");
+    }
+  }
+  
+  public static String getFailQueries(String[] exceptionQueries, boolean verbose) {
+    StringBuffer failQueries = new StringBuffer();
+    for (int i = 0; i < exceptionQueries.length; i++ ) {
+      new ExceptionQueryTest( exceptionQueries[i], verbose).doTest(failQueries);
+    }
+    return failQueries.toString();
+  }
+}
+

Added: lucene/java/trunk/contrib/surround/src/test/org/apache/lucene/queryParser/surround/query/SingleFieldTestDb.java
URL: http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/surround/src/test/org/apache/lucene/queryParser/surround/query/SingleFieldTestDb.java?rev=209183&view=auto
==============================================================================
--- lucene/java/trunk/contrib/surround/src/test/org/apache/lucene/queryParser/surround/query/SingleFieldTestDb.java (added)
+++ lucene/java/trunk/contrib/surround/src/test/org/apache/lucene/queryParser/surround/query/SingleFieldTestDb.java Mon Jul  4 19:29:03 2005
@@ -0,0 +1,39 @@
+package org.apache.lucene.queryParser.surround.query;
+
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.RAMDirectory;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.analysis.WhitespaceAnalyzer;
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.index.IndexWriter;
+
+public class SingleFieldTestDb {
+  private Directory db;
+  private String[] docs;
+  private String fieldName;
+  private String dbName = "testdb";
+  
+  public SingleFieldTestDb(String[] documents, String fName) {
+    try {
+      db = new RAMDirectory();
+      docs = documents;
+      fieldName = fName;
+      Analyzer analyzer = new WhitespaceAnalyzer();
+      IndexWriter writer = new IndexWriter(db, analyzer, true);
+      for (int j = 0; j < docs.length; j++) {
+        Document d = new Document();
+        d.add(new Field(fieldName, docs[j], Field.Store.NO, Field.Index.TOKENIZED));
+        writer.addDocument(d);
+      }
+      writer.close();
+    } catch (java.io.IOException ioe) {
+      throw new Error(ioe);
+    }
+  }
+  
+  Directory getDb() {return db;}
+  String[] getDocs() {return docs;}
+  String getFieldname() {return fieldName;}
+}
+

Added: lucene/java/trunk/contrib/surround/src/test/org/apache/lucene/queryParser/surround/query/Test01Exceptions.java
URL: http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/surround/src/test/org/apache/lucene/queryParser/surround/query/Test01Exceptions.java?rev=209183&view=auto
==============================================================================
--- lucene/java/trunk/contrib/surround/src/test/org/apache/lucene/queryParser/surround/query/Test01Exceptions.java (added)
+++ lucene/java/trunk/contrib/surround/src/test/org/apache/lucene/queryParser/surround/query/Test01Exceptions.java Mon Jul  4 19:29:03 2005
@@ -0,0 +1,51 @@
+package org.apache.lucene.queryParser.surround.query;
+
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+
+public class Test01Exceptions extends TestCase {
+  /** Main for running test case by itself. */
+  public static void main(String args[]) {
+    TestRunner.run(new TestSuite(Test01Exceptions.class));
+  }
+
+  boolean verbose = false; /* to show actual parsing error messages */
+  final String fieldName = "bi";
+
+  String[] exceptionQueries = {
+    "*",
+    "a*",
+    "ab*",
+    "?",
+    "a?",
+    "ab?",
+    "a???b",
+    "a?",
+    "a*b?",
+    "word1 word2",
+    "word2 AND",
+    "word1 OR",
+    "AND(word2)",
+    "AND(word2,)",
+    "AND(word2,word1,)",
+    "OR(word2)",
+    "OR(word2 ,",
+    "OR(word2 , word1 ,)",
+    "xx NOT",
+    "xx (a AND b)",
+    "(a AND b",
+    "a OR b)",
+    "or(word2+ not ord+, and xyz,def)",
+    ""
+  };
+
+  public void test01Exceptions() throws Exception {
+    String m = ExceptionQueryTest.getFailQueries(exceptionQueries, verbose);
+    if (m.length() > 0) {
+      fail("No ParseException for:\n" + m);
+    }
+  }
+}
+
+

Added: lucene/java/trunk/contrib/surround/src/test/org/apache/lucene/queryParser/surround/query/Test02Boolean.java
URL: http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/surround/src/test/org/apache/lucene/queryParser/surround/query/Test02Boolean.java?rev=209183&view=auto
==============================================================================
--- lucene/java/trunk/contrib/surround/src/test/org/apache/lucene/queryParser/surround/query/Test02Boolean.java (added)
+++ lucene/java/trunk/contrib/surround/src/test/org/apache/lucene/queryParser/surround/query/Test02Boolean.java Mon Jul  4 19:29:03 2005
@@ -0,0 +1,105 @@
+package org.apache.lucene.queryParser.surround.query;
+
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+
+
+public class Test02Boolean extends TestCase {
+  public static void main(String args[]) {
+    TestRunner.run(new TestSuite(Test02Boolean.class));
+  }
+
+  final String fieldName = "bi";
+  boolean verbose = false;
+  int maxBasicQueries = 16;
+
+  String[] docs1 = {
+    "word1 word2 word3",
+    "word4 word5",
+    "ord1 ord2 ord3",
+    "orda1 orda2 orda3 word2 worda3",
+    "a c e a b c"
+  };
+
+  SingleFieldTestDb db1 = new SingleFieldTestDb(docs1, fieldName);
+
+  public void normalTest1(String query, int[] expdnrs) throws Exception {
+    BooleanQueryTest bqt = new BooleanQueryTest( query, expdnrs, db1, fieldName, this,
+                                                new BasicQueryFactory(maxBasicQueries));
+    bqt.setVerbose(verbose);
+    bqt.doTest();
+  }
+
+  public void test02Terms01() throws Exception {
+    int[] expdnrs = {0}; normalTest1( "word1", expdnrs);
+  }
+  public void test02Terms02() throws Exception {
+    int[] expdnrs = {0, 1, 3}; normalTest1( "word*", expdnrs);
+  }
+  public void test02Terms03() throws Exception {
+    int[] expdnrs = {2}; normalTest1( "ord2", expdnrs);
+  }
+  public void test02Terms04() throws Exception {
+    int[] expdnrs = {}; normalTest1( "kxork*", expdnrs);
+  }
+  public void test02Terms05() throws Exception {
+    int[] expdnrs = {0, 1, 3}; normalTest1( "wor*", expdnrs);
+  }
+  public void test02Terms06() throws Exception {
+    int[] expdnrs = {}; normalTest1( "ab", expdnrs);
+  }
+  
+  public void test02Terms10() throws Exception {
+    int[] expdnrs = {}; normalTest1( "abc?", expdnrs);
+  }
+  public void test02Terms13() throws Exception {
+    int[] expdnrs = {0,1,3}; normalTest1( "word?", expdnrs);
+  }
+  public void test02Terms14() throws Exception {
+    int[] expdnrs = {0,1,3}; normalTest1( "w?rd?", expdnrs);
+  }
+  public void test02Terms20() throws Exception {
+    int[] expdnrs = {0,1,3}; normalTest1( "w*rd?", expdnrs);
+  }
+  public void test02Terms21() throws Exception {
+    int[] expdnrs = {3}; normalTest1( "w*rd??", expdnrs);
+  }
+  public void test02Terms22() throws Exception {
+    int[] expdnrs = {3}; normalTest1( "w*?da?", expdnrs);
+  }
+  public void test02Terms23() throws Exception {
+    int[] expdnrs = {}; normalTest1( "w?da?", expdnrs);
+  }
+  
+  public void test03And01() throws Exception {
+    int[] expdnrs = {0}; normalTest1( "word1 AND word2", expdnrs);
+  }
+  public void test03And02() throws Exception {
+    int[] expdnrs = {3}; normalTest1( "word* and ord*", expdnrs);
+  }
+  public void test03And03() throws Exception {
+    int[] expdnrs = {0}; normalTest1( "and(word1,word2)", expdnrs);
+  }
+  public void test04Or01() throws Exception {
+    int[] expdnrs = {0, 3}; normalTest1( "word1 or word2", expdnrs);
+  }
+  public void test04Or02() throws Exception {
+    int[] expdnrs = {0, 1, 2, 3}; normalTest1( "word* OR ord*", expdnrs);
+  }
+  public void test04Or03() throws Exception {
+    int[] expdnrs = {0, 3}; normalTest1( "OR (word1, word2)", expdnrs);
+  }
+  public void test05Not01() throws Exception {
+    int[] expdnrs = {3}; normalTest1( "word2 NOT word1", expdnrs);
+  }
+  public void test05Not02() throws Exception {
+    int[] expdnrs = {0}; normalTest1( "word2* not ord*", expdnrs);
+  }
+  public void test06AndOr01() throws Exception {
+    int[] expdnrs = {0}; normalTest1( "(word1 or ab)and or(word2,xyz, defg)", expdnrs);
+  }
+  public void test07AndOrNot02() throws Exception {
+    int[] expdnrs = {0}; normalTest1( "or( word2* not ord*, and(xyz,def))", expdnrs);
+  }
+}

Added: lucene/java/trunk/contrib/surround/src/test/org/apache/lucene/queryParser/surround/query/Test03Distance.java
URL: http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/surround/src/test/org/apache/lucene/queryParser/surround/query/Test03Distance.java?rev=209183&view=auto
==============================================================================
--- lucene/java/trunk/contrib/surround/src/test/org/apache/lucene/queryParser/surround/query/Test03Distance.java (added)
+++ lucene/java/trunk/contrib/surround/src/test/org/apache/lucene/queryParser/surround/query/Test03Distance.java Mon Jul  4 19:29:03 2005
@@ -0,0 +1,203 @@
+package org.apache.lucene.queryParser.surround.query;
+
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+
+public class Test03Distance extends TestCase {
+  public static void main(String args[]) {
+    TestRunner.run(new TestSuite(Test03Distance.class));
+  }
+  boolean verbose = false;
+  int maxBasicQueries = 16;
+  
+  String [] exceptionQueries = {
+    "(aa and bb) w cc",
+    "(aa or bb) w (cc and dd)",
+    "(aa opt bb) w cc",
+    "(aa not bb) w cc",
+    "(aa or bb) w (bi:cc)",
+    "(aa or bb) w bi:cc",
+    "(aa or bi:bb) w cc",
+    "(aa or (bi:bb)) w cc",
+    "(aa or (bb and dd)) w cc"
+  };
+  
+  public void test00Exceptions() throws Exception {
+    String m = ExceptionQueryTest.getFailQueries(exceptionQueries, verbose);
+    if (m.length() > 0) {
+      fail("No ParseException for:\n" + m);
+    }
+  }
+
+  final String fieldName = "bi";
+
+  String[] docs1 = {
+    "word1 word2 word3",
+    "word4 word5",
+    "ord1 ord2 ord3",
+    "orda1 orda2 orda3 word2 worda3",
+    "a c e a b c"
+  };
+
+  SingleFieldTestDb db1 = new SingleFieldTestDb(docs1, fieldName);
+
+  String[] docs2 = {
+    "w1 w2 w3 w4 w5",
+    "w1 w3 w2 w3",
+    ""
+  };
+
+  SingleFieldTestDb db2 = new SingleFieldTestDb(docs2, fieldName);
+
+  public void distanceTest1(String query, int[] expdnrs) throws Exception {
+    BooleanQueryTest bqt = new BooleanQueryTest( query, expdnrs, db1, fieldName, this,
+                                                new BasicQueryFactory(maxBasicQueries));
+    bqt.setVerbose(verbose);
+    bqt.doTest();
+  }
+
+  public void distanceTest2(String query, int[] expdnrs) throws Exception {
+    BooleanQueryTest bqt = new BooleanQueryTest( query, expdnrs, db2, fieldName, this,
+                                                new BasicQueryFactory(maxBasicQueries));
+    bqt.setVerbose(verbose);
+    bqt.doTest();
+  }
+  
+  public void test0W01() throws Exception {
+    int[] expdnrs = {0}; distanceTest1( "word1 w word2", expdnrs);
+  }
+  public void test0N01() throws Exception {
+    int[] expdnrs = {0}; distanceTest1( "word1 n word2", expdnrs);
+  }
+  public void test0N01r() throws Exception { /* r reverse */
+    int[] expdnrs = {0}; distanceTest1( "word2 n word1", expdnrs);
+  }
+  
+  public void test0W02() throws Exception {
+    int[] expdnrs = {}; distanceTest1( "word2 w word1", expdnrs);
+  }
+  
+  public void test0W03() throws Exception {
+    int[] expdnrs = {}; distanceTest1( "word2 2W word1", expdnrs);
+  }
+  public void test0N03() throws Exception {
+    int[] expdnrs = {0}; distanceTest1( "word2 2N word1", expdnrs);
+  }
+  public void test0N03r() throws Exception {
+    int[] expdnrs = {0}; distanceTest1( "word1 2N word2", expdnrs);
+  }
+  
+  public void test0W04() throws Exception {
+    int[] expdnrs = {}; distanceTest1( "word2 3w word1", expdnrs);
+  }
+
+  public void test0N04() throws Exception {
+    int[] expdnrs = {0}; distanceTest1( "word2 3n word1", expdnrs);
+  }
+  public void test0N04r() throws Exception {
+    int[] expdnrs = {0}; distanceTest1( "word1 3n word2", expdnrs);
+  }
+
+  public void test0W05() throws Exception {
+    int[] expdnrs = {}; distanceTest1( "orda1 w orda3", expdnrs);
+  }
+  public void test0W06() throws Exception {
+    int[] expdnrs = {3}; distanceTest1( "orda1 2w orda3", expdnrs);
+  }
+  
+  public void test1Wtrunc01() throws Exception {
+    int[] expdnrs = {0}; distanceTest1( "word1* w word2", expdnrs);
+  }
+  public void test1Wtrunc02() throws Exception {
+    int[] expdnrs = {0}; distanceTest1( "word* w word2", expdnrs);
+  }
+  public void test1Wtrunc02r() throws Exception {
+    int[] expdnrs = {0,3}; distanceTest1( "word2 w word*", expdnrs);
+  }
+  public void test1Ntrunc02() throws Exception {
+    int[] expdnrs = {0,3}; distanceTest1( "word* n word2", expdnrs);
+  }
+  public void test1Ntrunc02r() throws Exception {
+    int[] expdnrs = {0,3}; distanceTest1( "word2 n word*", expdnrs);
+  }
+
+  public void test1Wtrunc03() throws Exception {
+    int[] expdnrs = {0}; distanceTest1( "word1* w word2*", expdnrs);
+  }
+  public void test1Ntrunc03() throws Exception {
+    int[] expdnrs = {0}; distanceTest1( "word1* N word2*", expdnrs);
+  }
+  
+  public void test1Wtrunc04() throws Exception {
+    int[] expdnrs = {}; distanceTest1( "kxork* w kxor*", expdnrs);
+  }
+  public void test1Ntrunc04() throws Exception {
+    int[] expdnrs = {}; distanceTest1( "kxork* 99n kxor*", expdnrs);
+  }
+
+  public void test1Wtrunc05() throws Exception {
+    int[] expdnrs = {}; distanceTest1( "word2* 2W word1*", expdnrs);
+  }
+  public void test1Ntrunc05() throws Exception {
+    int[] expdnrs = {0}; distanceTest1( "word2* 2N word1*", expdnrs);
+  }
+
+  public void test1Wtrunc06() throws Exception {
+    int[] expdnrs = {3}; distanceTest1( "ord* W word*", expdnrs);
+  }
+  public void test1Ntrunc06() throws Exception {
+    int[] expdnrs = {3}; distanceTest1( "ord* N word*", expdnrs);
+  }
+  public void test1Ntrunc06r() throws Exception {
+    int[] expdnrs = {3}; distanceTest1( "word* N ord*", expdnrs);
+  }
+  
+  public void test1Wtrunc07() throws Exception {
+    int[] expdnrs = {3}; distanceTest1( "(orda2 OR orda3) W word*", expdnrs);
+  }
+  public void test1Wtrunc08() throws Exception {
+    int[] expdnrs = {3}; distanceTest1( "(orda2 OR orda3) W (word2 OR worda3)", expdnrs);
+  }
+  public void test1Wtrunc09() throws Exception {
+    int[] expdnrs = {3}; distanceTest1( "(orda2 OR orda3) 2W (word2 OR worda3)", expdnrs);
+  }
+  public void test1Ntrunc09() throws Exception {
+    int[] expdnrs = {3}; distanceTest1( "(orda2 OR orda3) 2N (word2 OR worda3)", expdnrs);
+  }
+  
+  public void test2Wprefix01() throws Exception {
+    int[] expdnrs = {0}; distanceTest2( "W (w1, w2, w3)", expdnrs);
+  }
+  public void test2Nprefix01a() throws Exception {
+    int[] expdnrs = {0,1}; distanceTest2( "N(w1, w2, w3)", expdnrs);
+  }
+  public void test2Nprefix01b() throws Exception {
+    int[] expdnrs = {0,1}; distanceTest2( "N(w3, w1, w2)", expdnrs);
+  }
+  
+  public void test2Wprefix02() throws Exception {
+    int[] expdnrs = {0,1}; distanceTest2( "2W(w1,w2,w3)", expdnrs);
+  }
+
+  public void test2Nprefix02a() throws Exception {
+    int[] expdnrs = {0,1}; distanceTest2( "2N(w1,w2,w3)", expdnrs);
+  }
+  public void test2Nprefix02b() throws Exception {
+    int[] expdnrs = {0,1}; distanceTest2( "2N(w2,w3,w1)", expdnrs);
+  }
+
+  public void test2Wnested01() throws Exception {
+    int[] expdnrs = {0}; distanceTest2( "w1 W w2 W w3", expdnrs);
+  }
+  public void test2Nnested01() throws Exception {
+    int[] expdnrs = {0}; distanceTest2( "w1 N w2 N w3", expdnrs);
+  }
+  
+  public void test2Wnested02() throws Exception {
+    int[] expdnrs = {0,1}; distanceTest2( "w1 2W w2 2W w3", expdnrs);
+  }
+  public void test2Nnested02() throws Exception {
+    int[] expdnrs = {0,1}; distanceTest2( "w1 2N w2 2N w3", expdnrs);
+  }
+}

Added: lucene/java/trunk/contrib/surround/surround.txt
URL: http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/surround/surround.txt?rev=209183&view=auto
==============================================================================
--- lucene/java/trunk/contrib/surround/surround.txt (added)
+++ lucene/java/trunk/contrib/surround/surround.txt Mon Jul  4 19:29:03 2005
@@ -0,0 +1,75 @@
+Description of Surround:
+
+Surround consists of operators (uppercase/lowercase):
+
+AND/OR/NOT/nW/nN/() as infix and
+AND/OR/nW/nN        as prefix.
+
+Distance operators W and N have default n=1, max 99.
+Implemented as SpanQuery with slop = (n - 1).
+An example prefix form is:
+
+20n(aa*, bb*, cc*)
+
+The name Surround was chosen because of this prefix form
+and because it uses the newly introduced span queries
+to implement the proximity operators.
+The names of the operators and the prefix and suffix
+forms have been borrowed from various other query
+languages described on the internet.
+
+
+Query terms from the Lucene standard query parser:
+
+field:termtext
+^ boost
+* internal and suffix truncation
+? one character
+
+
+Some examples:
+
+aa
+aa and bb
+aa and bb or cc        same effect as:  (aa and bb) or cc
+aa NOT bb NOT cc       same effect as:  (aa NOT bb) NOT cc
+
+and(aa,bb,cc)          aa and bb and cc
+99w(aa,bb,cc)          ordered span query with slop 98
+99n(aa,bb,cc)          unordered span query with slop 98
+
+20n(aa*,bb*)
+3w(a?a or bb?, cc+)
+
+title: text: aa
+title : text : aa or bb
+title:text: aa not bb
+title:aa not text:bb
+
+cc 3w dd               infix: dual.
+
+cc N dd N ee           same effect as:   (cc N dd) N ee
+
+text: aa 3d bb
+
+For examples on using the Surround language, see the
+test packages.
+
+
+Development status
+
+Not tested: multiple fields, internally mapped to OR queries,
+not compared to Lucene's MultipleFieldQuery.
+
+* suffix truncation is implemented very similar to Lucene's PrefixQuery.
+
+Wildcards (? and internal *) are implemented with regular expressions
+allow further variations. A reimplementation using
+WildCardTermEnum (correct name?) should be no problem.
+
+Warnings about missing terms are sent to System.out, this might
+be replaced by another stream.
+
+BooleanQueryTest.TestCollector uses a results checking method that should
+be replaced by the checking method from Lucene's TestBasics.java.
+



Mime
View raw message