Home » lucene-3.0.1-src » org.apache.lucene.queryParser.core.nodes » [javadoc | source]

    1   package org.apache.lucene.queryParser.core.nodes;
    2   
    3   /**
    4    * Licensed to the Apache Software Foundation (ASF) under one or more
    5    * contributor license agreements.  See the NOTICE file distributed with
    6    * this work for additional information regarding copyright ownership.
    7    * The ASF licenses this file to You under the Apache License, Version 2.0
    8    * (the "License"); you may not use this file except in compliance with
    9    * the License.  You may obtain a copy of the License at
   10    *
   11    *     http://www.apache.org/licenses/LICENSE-2.0
   12    *
   13    * Unless required by applicable law or agreed to in writing, software
   14    * distributed under the License is distributed on an "AS IS" BASIS,
   15    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   16    * See the License for the specific language governing permissions and
   17    * limitations under the License.
   18    */
   19   
   20   import java.util.List;
   21   
   22   import org.apache.lucene.messages.MessageImpl;
   23   import org.apache.lucene.queryParser.core.QueryNodeError;
   24   import org.apache.lucene.queryParser.core.messages.QueryParserMessages;
   25   import org.apache.lucene.queryParser.core.parser.EscapeQuerySyntax;
   26   
   27   /**
   28    * A {@link ProximityQueryNode} represents a query where the terms should meet
   29    * specific distance conditions. (a b c) WITHIN [SENTENCE|PARAGRAPH|NUMBER]
   30    * [INORDER] ("a" "b" "c") WITHIN [SENTENCE|PARAGRAPH|NUMBER] [INORDER]
   31    * 
   32    * TODO: Add this to the future standard Lucene parser/processor/builder
   33    */
   34   public class ProximityQueryNode extends BooleanQueryNode {
   35   
   36     private static final long serialVersionUID = 9018220596680832916L;
   37   
   38     public enum Type {
   39       PARAGRAPH {
   40         @Override
   41         CharSequence toQueryString() { return "WITHIN PARAGRAPH"; } 
   42       },
   43       SENTENCE  { 
   44         @Override
   45         CharSequence toQueryString() { return "WITHIN SENTENCE";  }
   46       },
   47       NUMBER    {
   48         @Override
   49         CharSequence toQueryString() { return "WITHIN";           }
   50       };
   51   
   52       abstract CharSequence toQueryString();
   53     }
   54   
   55     // utility class
   56     static public class ProximityType {
   57       int pDistance = 0;
   58   
   59       Type pType = null;
   60   
   61       public ProximityType(Type type) {
   62         this(type, 0);
   63       }
   64   
   65       public ProximityType(Type type, int distance) {
   66         this.pType = type;
   67         this.pDistance = distance;
   68       }
   69     }
   70   
   71     private Type proximityType = Type.SENTENCE;
   72     private int distance = -1;
   73     private boolean inorder = false;
   74     private CharSequence field = null;
   75   
   76     /**
   77      * @param clauses
   78      *          - QueryNode children
   79      * @param field
   80      *          - field name
   81      * @param type
   82      *          - type of proximity query
   83      * @param distance
   84      *          - positive integer that specifies the distance
   85      * @param inorder
   86      *          - true, if the tokens should be matched in the order of the
   87      *          clauses
   88      */
   89     public ProximityQueryNode(List<QueryNode> clauses, CharSequence field,
   90         Type type, int distance, boolean inorder) {
   91       super(clauses);
   92       setLeaf(false);
   93       this.proximityType = type;
   94       this.inorder = inorder;
   95       this.field = field;
   96       if (type == Type.NUMBER) {
   97         if (distance <= 0) {
   98           throw new QueryNodeError(new MessageImpl(
   99               QueryParserMessages.PARAMETER_VALUE_NOT_SUPPORTED, "distance",
  100               distance));
  101   
  102         } else {
  103           this.distance = distance;
  104         }
  105   
  106       }
  107       clearFields(clauses, field);
  108     }
  109   
  110     /**
  111      * @param clauses
  112      *          - QueryNode children
  113      * @param field
  114      *          - field name
  115      * @param type
  116      *          - type of proximity query
  117      * @param inorder
  118      *          - true, if the tokens should be matched in the order of the
  119      *          clauses
  120      */
  121     public ProximityQueryNode(List<QueryNode> clauses, CharSequence field,
  122         Type type, boolean inorder) {
  123       this(clauses, field, type, -1, inorder);
  124     }
  125   
  126     static private void clearFields(List<QueryNode> nodes, CharSequence field) {
  127       if (nodes == null || nodes.size() == 0)
  128         return;
  129   
  130       for (QueryNode clause : nodes) {
  131   
  132         if (clause instanceof FieldQueryNode) {
  133           ((FieldQueryNode) clause).toQueryStringIgnoreFields = true;
  134           ((FieldQueryNode) clause).setField(field);
  135         }
  136       }
  137     }
  138   
  139     public Type getProximityType() {
  140       return this.proximityType;
  141     }
  142   
  143     @Override
  144     public String toString() {
  145       String distanceSTR = ((this.distance == -1) ? ("")
  146           : (" distance='" + this.distance) + "'");
  147   
  148       if (getChildren() == null || getChildren().size() == 0)
  149         return "<proximity field='" + this.field + "' inorder='" + this.inorder
  150             + "' type='" + this.proximityType.toString() + "'" + distanceSTR
  151             + "/>";
  152       StringBuilder sb = new StringBuilder();
  153       sb.append("<proximity field='" + this.field + "' inorder='" + this.inorder
  154           + "' type='" + this.proximityType.toString() + "'" + distanceSTR + ">");
  155       for (QueryNode child : getChildren()) {
  156         sb.append("\n");
  157         sb.append(child.toString());
  158       }
  159       sb.append("\n</proximity>");
  160       return sb.toString();
  161     }
  162   
  163     @Override
  164     public CharSequence toQueryString(EscapeQuerySyntax escapeSyntaxParser) {
  165       String withinSTR = this.proximityType.toQueryString()
  166           + ((this.distance == -1) ? ("") : (" " + this.distance))
  167           + ((this.inorder) ? (" INORDER") : (""));
  168   
  169       StringBuilder sb = new StringBuilder();
  170       if (getChildren() == null || getChildren().size() == 0) {
  171         // no children case
  172       } else {
  173         String filler = "";
  174         for (QueryNode child : getChildren()) {
  175           sb.append(filler).append(child.toQueryString(escapeSyntaxParser));
  176           filler = " ";
  177         }
  178       }
  179   
  180       if (isDefaultField(this.field)) {
  181         return "( " + sb.toString() + " ) " + withinSTR;
  182       } else {
  183         return this.field + ":(( " + sb.toString() + " ) " + withinSTR + ")";
  184       }
  185     }
  186   
  187     @Override
  188     public QueryNode cloneTree() throws CloneNotSupportedException {
  189       ProximityQueryNode clone = (ProximityQueryNode) super.cloneTree();
  190   
  191       clone.proximityType = this.proximityType;
  192       clone.distance = this.distance;
  193       clone.field = this.field;
  194   
  195       return clone;
  196     }
  197   
  198     /**
  199      * @return the distance
  200      */
  201     public int getDistance() {
  202       return this.distance;
  203     }
  204   
  205     /**
  206      * returns null if the field was not specified in the query string
  207      * 
  208      * @return the field
  209      */
  210     public CharSequence getField() {
  211       return this.field;
  212     }
  213   
  214     /**
  215      * returns null if the field was not specified in the query string
  216      * 
  217      * @return the field
  218      */
  219     public String getFieldAsString() {
  220       if (this.field == null)
  221         return null;
  222       else
  223         return this.field.toString();
  224     }
  225   
  226     /**
  227      * @param field
  228      *          the field to set
  229      */
  230     public void setField(CharSequence field) {
  231       this.field = field;
  232     }
  233   
  234     /**
  235      * @return terms must be matched in the specified order
  236      */
  237     public boolean isInOrder() {
  238       return this.inorder;
  239     }
  240   
  241   }

Home » lucene-3.0.1-src » org.apache.lucene.queryParser.core.nodes » [javadoc | source]