pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / contrib / queryparser / src / java / org / apache / lucene / queryParser / standard / nodes / AbstractRangeQueryNode.java
1 package org.apache.lucene.queryParser.standard.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.ArrayList;
21
22 import org.apache.lucene.queryParser.core.nodes.FieldValuePairQueryNode;
23 import org.apache.lucene.queryParser.core.nodes.QueryNode;
24 import org.apache.lucene.queryParser.core.nodes.QueryNodeImpl;
25 import org.apache.lucene.queryParser.core.nodes.RangeQueryNode;
26 import org.apache.lucene.queryParser.core.parser.EscapeQuerySyntax;
27 import org.apache.lucene.queryParser.core.util.StringUtils;
28
29 /**
30  * This class should be extended by nodes intending to represent range queries.
31  * 
32  * @param <T>
33  *          the type of the range query bounds (lower and upper)
34  */
35 public abstract class AbstractRangeQueryNode<T extends FieldValuePairQueryNode<?>>
36     extends QueryNodeImpl implements RangeQueryNode<FieldValuePairQueryNode<?>> {
37   
38   private static final long serialVersionUID = 4475492120315147792L;
39   
40   private boolean lowerInclusive, upperInclusive;
41   
42   /**
43    * Constructs an {@link AbstractRangeQueryNode}, it should be invoked only by
44    * its extenders.
45    */
46   protected AbstractRangeQueryNode() {
47     setLeaf(false);
48     allocate();
49   }
50   
51   /**
52    * Returns the field associated with this node.
53    * 
54    * @return the field associated with this node
55    * 
56    * @see org.apache.lucene.queryParser.core.nodes.FieldableNode
57    */
58   public CharSequence getField() {
59     CharSequence field = null;
60     T lower = getLowerBound();
61     T upper = getUpperBound();
62     
63     if (lower != null) {
64       field = lower.getField();
65       
66     } else if (upper != null) {
67       field = upper.getField();
68     }
69     
70     return field;
71     
72   }
73   
74   /**
75    * Sets the field associated with this node.
76    * 
77    * @param fieldName the field associated with this node
78    */
79   public void setField(CharSequence fieldName) {
80     T lower = getLowerBound();
81     T upper = getUpperBound();
82     
83     if (lower != null) {
84       lower.setField(fieldName);
85     }
86     
87     if (upper != null) {
88       upper.setField(fieldName);
89     }
90     
91   }
92   
93   /**
94    * Returns the lower bound node.
95    * 
96    * @return the lower bound node.
97    */
98   @SuppressWarnings("unchecked")
99   public T getLowerBound() {
100     return (T) getChildren().get(0);
101   }
102   
103   /**
104    * Returns the upper bound node.
105    * 
106    * @return the upper bound node.
107    */
108   @SuppressWarnings("unchecked")
109   public T getUpperBound() {
110     return (T) getChildren().get(1);
111   }
112   
113   /**
114    * Returns whether the lower bound is inclusive or exclusive.
115    * 
116    * @return <code>true</code> if the lower bound is inclusive, otherwise, <code>false</code>
117    */
118   public boolean isLowerInclusive() {
119     return lowerInclusive;
120   }
121   
122   /**
123    * Returns whether the upper bound is inclusive or exclusive.
124    * 
125    * @return <code>true</code> if the upper bound is inclusive, otherwise, <code>false</code>
126    */
127   public boolean isUpperInclusive() {
128     return upperInclusive;
129   }
130   
131   /**
132    * Sets the lower and upper bounds.
133    * 
134    * @param lower the lower bound, <code>null</code> if lower bound is open
135    * @param upper the upper bound, <code>null</code> if upper bound is open
136    * @param lowerInclusive <code>true</code> if the lower bound is inclusive, otherwise, <code>false</code>
137    * @param upperInclusive <code>true</code> if the upper bound is inclusive, otherwise, <code>false</code>
138    * 
139    * @see #getLowerBound()
140    * @see #getUpperBound()
141    * @see #isLowerInclusive()
142    * @see #isUpperInclusive()
143    */
144   public void setBounds(T lower, T upper, boolean lowerInclusive,
145       boolean upperInclusive) {
146     
147     if (lower != null && upper != null) {
148       String lowerField = StringUtils.toString(lower.getField());
149       String upperField = StringUtils.toString(upper.getField());
150       
151       if ((upperField != null || lowerField != null)
152           && ((upperField != null && !upperField.equals(lowerField)) || !lowerField
153               .equals(upperField))) {
154         throw new IllegalArgumentException(
155             "lower and upper bounds should have the same field name!");
156       }
157       
158       this.lowerInclusive = lowerInclusive;
159       this.upperInclusive = upperInclusive;
160       
161       ArrayList<QueryNode> children = new ArrayList<QueryNode>(2);
162       children.add(lower);
163       children.add(upper);
164       
165       set(children);
166       
167     }
168     
169   }
170   
171   public CharSequence toQueryString(EscapeQuerySyntax escapeSyntaxParser) {
172     StringBuilder sb = new StringBuilder();
173     
174     T lower = getLowerBound();
175     T upper = getUpperBound();
176     
177     if (lowerInclusive) {
178       sb.append('[');
179       
180     } else {
181       sb.append('{');
182     }
183     
184     if (lower != null) {
185       sb.append(lower.toQueryString(escapeSyntaxParser));
186       
187     } else {
188       sb.append("...");
189     }
190     
191     sb.append(' ');
192     
193     if (upper != null) {
194       sb.append(upper.toQueryString(escapeSyntaxParser));
195       
196     } else {
197       sb.append("...");
198     }
199     
200     if (upperInclusive) {
201       sb.append(']');
202       
203     } else {
204       sb.append('}');
205     }
206     
207     return sb.toString();
208     
209   }
210   
211 }