/*
* Copyright 2004 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.
*/
using System;
using Document = Lucene.Net.Documents.Document;
using Field = Lucene.Net.Documents.Field;
using Directory = Lucene.Net.Store.Directory;
using InputStream = Lucene.Net.Store.InputStream;
using OutputStream = Lucene.Net.Store.OutputStream;
namespace Lucene.Net.Index
{
/// Access to the Field Info file that describes document fields and whether or
/// not they are indexed. Each segment has a separate Field Info file. Objects
/// of this class are thread-safe for multiple readers, but only one thread can
/// be adding documents at a time, with no other reader or writer threads
/// accessing this object.
///
sealed public class FieldInfos
{
private System.Collections.ArrayList byNumber = new System.Collections.ArrayList();
private System.Collections.Hashtable byName = new System.Collections.Hashtable();
public /*internal*/ FieldInfos()
{
Add("", false);
}
/// Construct a FieldInfos object using the directory and the name of the file
/// InputStream
///
/// The directory to open the InputStream from
///
/// The name of the file to open the InputStream from in the Directory
///
/// IOException
///
///
///
///
public /*internal*/ FieldInfos(Directory d, System.String name)
{
InputStream input = d.OpenFile(name);
try
{
Read(input);
}
finally
{
input.Close();
}
}
/// Adds Field info for a Document.
public void Add(Document doc)
{
foreach (Field field in doc.Fields())
{
Add(field.Name(), field.IsIndexed(), field.IsTermVectorStored());
}
}
/// The names of the fields
///
/// Whether the fields store term vectors or not
///
public void AddIndexed(System.Collections.ICollection names, bool storeTermVectors)
{
System.Collections.IEnumerator i = names.GetEnumerator();
int j = 0;
while (i.MoveNext())
{
System.Collections.DictionaryEntry t = (System.Collections.DictionaryEntry) i.Current;
Add((System.String) t.Key, true, storeTermVectors);
}
}
/// Assumes the Field is not storing term vectors
/// The names of the fields
///
/// Whether the fields are indexed or not
///
///
///
///
public void Add(System.Collections.ICollection names, bool isIndexed)
{
System.Collections.IEnumerator i = names.GetEnumerator();
int j = 0;
while (i.MoveNext())
{
System.Collections.DictionaryEntry t = (System.Collections.DictionaryEntry) i.Current;
Add((System.String) t.Key, isIndexed);
}
}
/// Calls three parameter add with false for the storeTermVector parameter
/// The name of the Field
///
/// true if the Field is indexed
///
///
///
public void Add(System.String name, bool isIndexed)
{
Add(name, isIndexed, false);
}
/// If the Field is not yet known, adds it. If it is known, checks to make
/// sure that the isIndexed flag is the same as was given previously for this
/// Field. If not - marks it as being indexed. Same goes for storeTermVector
///
///
/// The name of the Field
///
/// true if the Field is indexed
///
/// true if the term vector should be stored
///
public void Add(System.String name, bool isIndexed, bool storeTermVector)
{
FieldInfo fi = FieldInfo(name);
if (fi == null)
{
AddInternal(name, isIndexed, storeTermVector);
}
else
{
if (fi.isIndexed != isIndexed)
{
fi.isIndexed = true; // once indexed, always index
}
if (fi.storeTermVector != storeTermVector)
{
fi.storeTermVector = true; // once vector, always vector
}
}
}
private void AddInternal(System.String name, bool isIndexed, bool storeTermVector)
{
FieldInfo fi = new FieldInfo(name, isIndexed, byNumber.Count, storeTermVector);
byNumber.Add(fi);
byName[name] = fi;
}
public int FieldNumber(System.String fieldName)
{
FieldInfo fi = FieldInfo(fieldName);
if (fi != null)
return fi.number;
else
return - 1;
}
public FieldInfo FieldInfo(System.String fieldName)
{
return (FieldInfo) byName[fieldName];
}
public System.String FieldName(int fieldNumber)
{
return FieldInfo(fieldNumber).name;
}
public FieldInfo FieldInfo(int fieldNumber)
{
return (FieldInfo) byNumber[fieldNumber];
}
public int Size()
{
return byNumber.Count;
}
public bool HasVectors()
{
bool hasVectors = false;
for (int i = 0; i < Size(); i++)
{
if (FieldInfo(i).storeTermVector)
hasVectors = true;
}
return hasVectors;
}
public void Write(Directory d, System.String name)
{
OutputStream output = d.CreateFile(name);
try
{
Write(output);
}
finally
{
output.Close();
}
}
public void Write(OutputStream output)
{
output.WriteVInt(Size());
for (int i = 0; i < Size(); i++)
{
FieldInfo fi = FieldInfo(i);
byte bits = (byte) (0x0);
if (fi.isIndexed)
bits |= (byte) (0x1);
if (fi.storeTermVector)
bits |= (byte) (0x2);
output.WriteString(fi.name);
//Was REMOVE
//output.writeByte((byte)(fi.isIndexed ? 1 : 0));
output.WriteByte(bits);
}
}
private void Read(InputStream input)
{
int size = input.ReadVInt(); //read in the size
for (int i = 0; i < size; i++)
{
System.String name = String.Intern(input.ReadString());
byte bits = input.ReadByte();
bool isIndexed = (bits & 0x1) != 0;
bool storeTermVector = (bits & 0x2) != 0;
AddInternal(name, isIndexed, storeTermVector);
}
}
}
}