Field.java
001 package gate.creole.annic.apache.lucene.document;
002 
003 /**
004  * Copyright 2004 The Apache Software Foundation
005  *
006  * Licensed under the Apache License, Version 2.0 (the "License");
007  * you may not use this file except in compliance with the License.
008  * You may obtain a copy of the License at
009  *
010  *     http://www.apache.org/licenses/LICENSE-2.0
011  *
012  * Unless required by applicable law or agreed to in writing, software
013  * distributed under the License is distributed on an "AS IS" BASIS,
014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015  * See the License for the specific language governing permissions and
016  * limitations under the License.
017  */
018 
019 import java.io.Reader;
020 import java.util.Date;
021 import gate.creole.annic.apache.lucene.index.IndexReader;       // for javadoc
022 import gate.creole.annic.apache.lucene.search.Similarity;       // for javadoc
023 import gate.creole.annic.apache.lucene.search.Hits;             // for javadoc
024 
025 /**
026   A field is a section of a Document.  Each field has two parts, a name and a
027   value.  Values may be free text, provided as a String or as a Reader, or they
028   may be atomic keywords, which are not further processed.  Such keywords may
029   be used to represent dates, urls, etc.  Fields are optionally stored in the
030   index, so that they may be returned with hits on the document.
031   */
032 
033 @SuppressWarnings("serial")
034 public final class Field implements java.io.Serializable {
035   private String name = "body";
036   private String stringValue = null;
037   private boolean storeTermVector = false;
038   private Reader readerValue = null;
039   private boolean isStored = false;
040   private boolean isIndexed = true;
041   private boolean isTokenized = true;
042 
043   private float boost = 1.0f;
044 
045   /** Sets the boost factor hits on this field.  This value will be
046    * multiplied into the score of all hits on this this field of this
047    * document.
048    *
049    <p>The boost is multiplied by {@link Document#getBoost()} of the document
050    * containing this field.  If a document has multiple fields with the same
051    * name, all such values are multiplied together.  This product is then
052    * multipled by the value {@link Similarity#lengthNorm(String,int)}, and
053    * rounded by {@link Similarity#encodeNorm(float)} before it is stored in the
054    * index.  One should attempt to ensure that this product does not overflow
055    * the range of that encoding.
056    *
057    @see Document#setBoost(float)
058    @see Similarity#lengthNorm(String, int)
059    @see Similarity#encodeNorm(float)
060    */
061   public void setBoost(float boost) {
062     this.boost = boost;
063   }
064 
065   /** Returns the boost factor for hits on any field of this document.
066    *
067    <p>The default value is 1.0.
068    *
069    <p>Note: this value is not stored directly with the document in the index.
070    * Documents returned from {@link IndexReader#document(int)} and {@link
071    * Hits#doc(int)} may thus not have the same value present as when this field
072    * was indexed.
073    *
074    @see #setBoost(float)
075    */
076   public float getBoost() {
077     return boost;
078   }
079 
080   /** Constructs a String-valued Field that is not tokenized, but is indexed
081     and stored.  Useful for non-text fields, e.g. date or url.
082    */
083   public static final Field Keyword(String name, String value) {
084     return new Field(name, value, true, true, false);
085   }
086 
087   /** Constructs a String-valued Field that is not tokenized nor indexed,
088     but is stored in the index, for return with hits. */
089   public static final Field UnIndexed(String name, String value) {
090     return new Field(name, value, true, false, false);
091   }
092 
093   /** Constructs a String-valued Field that is tokenized and indexed,
094     and is stored in the index, for return with hits.  Useful for short text
095     fields, like "title" or "subject". Term vector will not be stored for this field. */
096   public static final Field Text(String name, String value) {
097     return Text(name, value, false);
098   }
099 
100   /** Constructs a Date-valued Field that is not tokenized and is indexed,
101       and stored in the index, for return with hits. */
102   public static final Field Keyword(String name, Date value) {
103     return new Field(name, DateField.dateToString(value), true, true, false);
104   }
105 
106   /** Constructs a String-valued Field that is tokenized and indexed,
107     and is stored in the index, for return with hits.  Useful for short text
108     fields, like "title" or "subject". */
109   public static final Field Text(String name, String value, boolean storeTermVector) {
110     return new Field(name, value, true, true, true, storeTermVector);
111   }
112 
113   /** Constructs a String-valued Field that is tokenized and indexed,
114     but that is not stored in the index.  Term vector will not be stored for this field. */
115   public static final Field UnStored(String name, String value) {
116     return UnStored(name, value, false);
117   }
118 
119   /** Constructs a String-valued Field that is tokenized and indexed,
120     but that is not stored in the index. */
121   public static final Field UnStored(String name, String value, boolean storeTermVector) {
122     return new Field(name, value, false, true, true, storeTermVector);
123   }
124 
125   /** Constructs a Reader-valued Field that is tokenized and indexed, but is
126     not stored in the index verbatim.  Useful for longer text fields, like
127     "body". Term vector will not be stored for this field. */
128   public static final Field Text(String name, Reader value) {
129     return Text(name, value, false);
130   }
131 
132   /** Constructs a Reader-valued Field that is tokenized and indexed, but is
133     not stored in the index verbatim.  Useful for longer text fields, like
134     "body". */
135   public static final Field Text(String name, Reader value, boolean storeTermVector) {
136     Field f = new Field(name, value);
137     f.storeTermVector = storeTermVector;
138     return f;
139   }
140 
141   /** The name of the field (e.g., "date", "subject", "title", or "body")
142     as an interned string. */
143   public String name()     { return name; }
144 
145   /** The value of the field as a String, or null.  If null, the Reader value
146     is used.  Exactly one of stringValue() and readerValue() must be set. */
147   public String stringValue()    { return stringValue; }
148   /** The value of the field as a Reader, or null.  If null, the String value
149     is used.  Exactly one of stringValue() and readerValue() must be set. */
150   public Reader readerValue()  { return readerValue; }
151 
152 
153   /** Create a field by specifying all parameters except for <code>storeTermVector</code>,
154    *  which is set to <code>false</code>.
155    */
156   public Field(String name, String string,
157          boolean store, boolean index, boolean token) {
158     this(name, string, store, index, token, false);
159   }
160 
161   /**
162    *
163    @param name The name of the field
164    @param string The string to process
165    @param store true if the field should store the string
166    @param index true if the field should be indexed
167    @param token true if the field should be tokenized
168    @param storeTermVector true if we should store the Term Vector info
169    */
170   public Field(String name, String string,
171          boolean store, boolean index, boolean token, boolean storeTermVector) {
172     if (name == null)
173       throw new IllegalArgumentException("name cannot be null");
174     if (string == null)
175       throw new IllegalArgumentException("value cannot be null");
176     if (!index && storeTermVector)
177       throw new IllegalArgumentException("cannot store a term vector for fields that are not indexed.");
178 
179     this.name = name.intern();        // field names are interned
180     this.stringValue = string;
181     this.isStored = store;
182     this.isIndexed = index;
183     this.isTokenized = token;
184     this.storeTermVector = storeTermVector;
185   }
186 
187   Field(String name, Reader reader) {
188     if (name == null)
189       throw new IllegalArgumentException("name cannot be null");
190     if (reader == null)
191       throw new IllegalArgumentException("value cannot be null");
192 
193     this.name = name.intern();        // field names are interned
194     this.readerValue = reader;
195   }
196 
197   /** True iff the value of the field is to be stored in the index for return
198     with search hits.  It is an error for this to be true if a field is
199     Reader-valued. */
200   public final boolean  isStored()   { return isStored; }
201 
202   /** True iff the value of the field is to be indexed, so that it may be
203     searched on. */
204   public final boolean   isIndexed()   { return isIndexed; }
205 
206   /** True iff the value of the field should be tokenized as text prior to
207     indexing.  Un-tokenized fields are indexed as a single word and may not be
208     Reader-valued. */
209   public final boolean   isTokenized()   { return isTokenized; }
210 
211   /** True iff the term or terms used to index this field are stored as a term
212    *  vector, available from {@link IndexReader#getTermFreqVector(int,String)}.
213    *  These methods do not provide access to the original content of the field,
214    *  only to terms used to index it. If the original content must be
215    *  preserved, use the <code>stored</code> attribute instead.
216    *
217    @see IndexReader#getTermFreqVector(int, String)
218    */
219   public final boolean isTermVectorStored() { return storeTermVector; }
220 
221   /** Prints a Field for human consumption. */
222   @Override
223   public final String toString() {
224     if (isStored && isIndexed && !isTokenized)
225       return "Keyword<" + name + ":" + stringValue + ">";
226     else if (isStored && !isIndexed && !isTokenized)
227       return "Unindexed<" + name + ":" + stringValue + ">";
228     else if (isStored && isIndexed && isTokenized && stringValue!=null)
229       return "Text<" + name + ":" + stringValue + ">";
230     else if (!isStored && isIndexed && isTokenized && readerValue!=null)
231       return "Text<" + name + ":" + readerValue + ">";
232     else if (!isStored && isIndexed && isTokenized)
233     {
234       return "UnStored<" + name + ">";
235     }
236     else
237     {
238       return super.toString();
239     }
240   }
241 
242 }