KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > lucene > index > CompoundFileReader


1 package org.apache.lucene.index;
2
3 /**
4  * Copyright 2004 The Apache Software Foundation
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18
19 import org.apache.lucene.store.Directory;
20 import org.apache.lucene.store.IndexInput;
21 import org.apache.lucene.store.BufferedIndexInput;
22 import org.apache.lucene.store.IndexOutput;
23 import org.apache.lucene.store.Lock;
24
25 import java.util.HashMap JavaDoc;
26 import java.io.IOException JavaDoc;
27
28
29 /**
30  * Class for accessing a compound stream.
31  * This class implements a directory, but is limited to only read operations.
32  * Directory methods that would normally modify data throw an exception.
33  *
34  * @author Dmitry Serebrennikov
35  * @version $Id: CompoundFileReader.java 208905 2005-07-03 10:40:01Z dnaber $
36  */

37 class CompoundFileReader extends Directory {
38
39     private static final class FileEntry {
40         long offset;
41         long length;
42     }
43
44
45     // Base info
46
private Directory directory;
47     private String JavaDoc fileName;
48
49     private IndexInput stream;
50     private HashMap JavaDoc entries = new HashMap JavaDoc();
51
52
53     public CompoundFileReader(Directory dir, String JavaDoc name)
54     throws IOException JavaDoc
55     {
56         directory = dir;
57         fileName = name;
58
59         boolean success = false;
60
61         try {
62             stream = dir.openInput(name);
63
64             // read the directory and init files
65
int count = stream.readVInt();
66             FileEntry entry = null;
67             for (int i=0; i<count; i++) {
68                 long offset = stream.readLong();
69                 String JavaDoc id = stream.readString();
70
71                 if (entry != null) {
72                     // set length of the previous entry
73
entry.length = offset - entry.offset;
74                 }
75
76                 entry = new FileEntry();
77                 entry.offset = offset;
78                 entries.put(id, entry);
79             }
80
81             // set the length of the final entry
82
if (entry != null) {
83                 entry.length = stream.length() - entry.offset;
84             }
85
86             success = true;
87
88         } finally {
89             if (! success && (stream != null)) {
90                 try {
91                     stream.close();
92                 } catch (IOException JavaDoc e) { }
93             }
94         }
95     }
96
97     public Directory getDirectory() {
98         return directory;
99     }
100
101     public String JavaDoc getName() {
102         return fileName;
103     }
104
105     public synchronized void close() throws IOException JavaDoc {
106         if (stream == null)
107             throw new IOException JavaDoc("Already closed");
108
109         entries.clear();
110         stream.close();
111         stream = null;
112     }
113
114     public synchronized IndexInput openInput(String JavaDoc id)
115     throws IOException JavaDoc
116     {
117         if (stream == null)
118             throw new IOException JavaDoc("Stream closed");
119
120         FileEntry entry = (FileEntry) entries.get(id);
121         if (entry == null)
122             throw new IOException JavaDoc("No sub-file with id " + id + " found");
123
124         return new CSIndexInput(stream, entry.offset, entry.length);
125     }
126
127     /** Returns an array of strings, one for each file in the directory. */
128     public String JavaDoc[] list() {
129         String JavaDoc res[] = new String JavaDoc[entries.size()];
130         return (String JavaDoc[]) entries.keySet().toArray(res);
131     }
132
133     /** Returns true iff a file with the given name exists. */
134     public boolean fileExists(String JavaDoc name) {
135         return entries.containsKey(name);
136     }
137
138     /** Returns the time the compound file was last modified. */
139     public long fileModified(String JavaDoc name) throws IOException JavaDoc {
140         return directory.fileModified(fileName);
141     }
142
143     /** Set the modified time of the compound file to now. */
144     public void touchFile(String JavaDoc name) throws IOException JavaDoc {
145         directory.touchFile(fileName);
146     }
147
148     /** Not implemented
149      * @throws UnsupportedOperationException */

150     public void deleteFile(String JavaDoc name)
151     {
152         throw new UnsupportedOperationException JavaDoc();
153     }
154
155     /** Not implemented
156      * @throws UnsupportedOperationException */

157     public void renameFile(String JavaDoc from, String JavaDoc to)
158     {
159         throw new UnsupportedOperationException JavaDoc();
160     }
161
162     /** Returns the length of a file in the directory.
163      * @throws IOException if the file does not exist */

164     public long fileLength(String JavaDoc name)
165     throws IOException JavaDoc
166     {
167         FileEntry e = (FileEntry) entries.get(name);
168         if (e == null)
169             throw new IOException JavaDoc("File " + name + " does not exist");
170         return e.length;
171     }
172
173     /** Not implemented
174      * @throws UnsupportedOperationException */

175     public IndexOutput createOutput(String JavaDoc name)
176     {
177         throw new UnsupportedOperationException JavaDoc();
178     }
179
180     /** Not implemented
181      * @throws UnsupportedOperationException */

182     public Lock makeLock(String JavaDoc name)
183     {
184         throw new UnsupportedOperationException JavaDoc();
185     }
186
187     /** Implementation of an IndexInput that reads from a portion of the
188      * compound file. The visibility is left as "package" *only* because
189      * this helps with testing since JUnit test cases in a different class
190      * can then access package fields of this class.
191      */

192     static final class CSIndexInput extends BufferedIndexInput {
193
194         IndexInput base;
195         long fileOffset;
196         long length;
197
198         CSIndexInput(final IndexInput base, final long fileOffset, final long length)
199         {
200             this.base = base;
201             this.fileOffset = fileOffset;
202             this.length = length;
203         }
204
205         /** Expert: implements buffer refill. Reads bytes from the current
206          * position in the input.
207          * @param b the array to read bytes into
208          * @param offset the offset in the array to start storing bytes
209          * @param len the number of bytes to read
210          */

211         protected void readInternal(byte[] b, int offset, int len)
212         throws IOException JavaDoc
213         {
214             synchronized (base) {
215               long start = getFilePointer();
216               if(start + len > length)
217                 throw new IOException JavaDoc("read past EOF");
218               base.seek(fileOffset + start);
219               base.readBytes(b, offset, len);
220             }
221         }
222
223         /** Expert: implements seek. Sets current position in this file, where
224          * the next {@link #readInternal(byte[],int,int)} will occur.
225          * @see #readInternal(byte[],int,int)
226          */

227         protected void seekInternal(long pos) {}
228
229         /** Closes the stream to further operations. */
230         public void close() {}
231
232         public long length() {
233           return length;
234         }
235
236
237     }
238     
239 }
240
Popular Tags