add --shared
[pylucene.git] / lucene-java-3.4.0 / lucene / src / java / org / apache / lucene / store / Directory.java
1 package org.apache.lucene.store;
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.io.FileNotFoundException;
21 import java.io.IOException;
22 import java.io.Closeable;
23 import java.util.Collection;
24
25 import org.apache.lucene.index.IndexFileNameFilter;
26 import org.apache.lucene.util.IOUtils;
27
28 /** A Directory is a flat list of files.  Files may be written once, when they
29  * are created.  Once a file is created it may only be opened for read, or
30  * deleted.  Random access is permitted both when reading and writing.
31  *
32  * <p> Java's i/o APIs not used directly, but rather all i/o is
33  * through this API.  This permits things such as: <ul>
34  * <li> implementation of RAM-based indices;
35  * <li> implementation indices stored in a database, via JDBC;
36  * <li> implementation of an index as a single file;
37  * </ul>
38  *
39  * Directory locking is implemented by an instance of {@link
40  * LockFactory}, and can be changed for each Directory
41  * instance using {@link #setLockFactory}.
42  *
43  */
44 public abstract class Directory implements Closeable {
45
46   volatile protected boolean isOpen = true;
47
48   /** Holds the LockFactory instance (implements locking for
49    * this Directory instance). */
50   protected LockFactory lockFactory;
51
52   /**
53    * Returns an array of strings, one for each file in the directory.
54    * 
55    * @throws NoSuchDirectoryException if the directory is not prepared for any
56    *         write operations (such as {@link #createOutput(String)}).
57    * @throws IOException in case of other IO errors
58    */
59   public abstract String[] listAll() throws IOException;
60
61   /** Returns true iff a file with the given name exists. */
62   public abstract boolean fileExists(String name)
63        throws IOException;
64
65   /** Returns the time the named file was last modified. */
66   public abstract long fileModified(String name)
67        throws IOException;
68
69   /** Set the modified time of an existing file to now.
70    *
71    *  @deprecated Lucene never uses this API; it will be
72    *  removed in 4.0. */
73   @Deprecated
74   public abstract void touchFile(String name)
75        throws IOException;
76
77   /** Removes an existing file in the directory. */
78   public abstract void deleteFile(String name)
79        throws IOException;
80
81   /**
82    * Returns the length of a file in the directory. This method follows the
83    * following contract:
84    * <ul>
85    * <li>Throws {@link FileNotFoundException} if the file does not exist
86    * <li>Returns a value &ge;0 if the file exists, which specifies its length.
87    * </ul>
88    * 
89    * @param name the name of the file for which to return the length.
90    * @throws FileNotFoundException if the file does not exist.
91    * @throws IOException if there was an IO error while retrieving the file's
92    *         length.
93    */
94   public abstract long fileLength(String name) throws IOException;
95
96
97   /** Creates a new, empty file in the directory with the given name.
98       Returns a stream writing this file. */
99   public abstract IndexOutput createOutput(String name)
100        throws IOException;
101
102   /**
103    * Ensure that any writes to this file are moved to
104    * stable storage.  Lucene uses this to properly commit
105    * changes to the index, to prevent a machine/OS crash
106    * from corrupting the index.
107    * @deprecated use {@link #sync(Collection)} instead.
108    * For easy migration you can change your code to call
109    * sync(Collections.singleton(name))
110    */
111   @Deprecated
112   public void sync(String name) throws IOException { // TODO 4.0 kill me
113   }
114
115   /**
116    * Ensure that any writes to these files are moved to
117    * stable storage.  Lucene uses this to properly commit
118    * changes to the index, to prevent a machine/OS crash
119    * from corrupting the index.<br/>
120    * <br/>
121    * NOTE: Clients may call this method for same files over
122    * and over again, so some impls might optimize for that.
123    * For other impls the operation can be a noop, for various
124    * reasons.
125    */
126   public void sync(Collection<String> names) throws IOException { // TODO 4.0 make me abstract
127     for (String name : names)
128       sync(name);
129   }
130
131   /** Returns a stream reading an existing file. */
132   public abstract IndexInput openInput(String name)
133     throws IOException;
134
135   /** Returns a stream reading an existing file, with the
136    * specified read buffer size.  The particular Directory
137    * implementation may ignore the buffer size.  Currently
138    * the only Directory implementations that respect this
139    * parameter are {@link FSDirectory} and {@link
140    * org.apache.lucene.index.CompoundFileReader}.
141   */
142   public IndexInput openInput(String name, int bufferSize) throws IOException {
143     return openInput(name);
144   }
145
146   /** Construct a {@link Lock}.
147    * @param name the name of the lock file
148    */
149   public Lock makeLock(String name) {
150       return lockFactory.makeLock(name);
151   }
152   /**
153    * Attempt to clear (forcefully unlock and remove) the
154    * specified lock.  Only call this at a time when you are
155    * certain this lock is no longer in use.
156    * @param name name of the lock to be cleared.
157    */
158   public void clearLock(String name) throws IOException {
159     if (lockFactory != null) {
160       lockFactory.clearLock(name);
161     }
162   }
163
164   /** Closes the store. */
165   public abstract void close()
166        throws IOException;
167
168   /**
169    * Set the LockFactory that this Directory instance should
170    * use for its locking implementation.  Each * instance of
171    * LockFactory should only be used for one directory (ie,
172    * do not share a single instance across multiple
173    * Directories).
174    *
175    * @param lockFactory instance of {@link LockFactory}.
176    */
177   public void setLockFactory(LockFactory lockFactory) throws IOException {
178     assert lockFactory != null;
179     this.lockFactory = lockFactory;
180     lockFactory.setLockPrefix(this.getLockID());
181   }
182
183   /**
184    * Get the LockFactory that this Directory instance is
185    * using for its locking implementation.  Note that this
186    * may be null for Directory implementations that provide
187    * their own locking implementation.
188    */
189   public LockFactory getLockFactory() {
190       return this.lockFactory;
191   }
192
193   /**
194    * Return a string identifier that uniquely differentiates
195    * this Directory instance from other Directory instances.
196    * This ID should be the same if two Directory instances
197    * (even in different JVMs and/or on different machines)
198    * are considered "the same index".  This is how locking
199    * "scopes" to the right index.
200    */
201   public String getLockID() {
202       return this.toString();
203   }
204
205   @Override
206   public String toString() {
207     return super.toString() + " lockFactory=" + getLockFactory();
208   }
209
210   /**
211    * Copies the file <i>src</i> to {@link Directory} <i>to</i> under the new
212    * file name <i>dest</i>.
213    * <p>
214    * If you want to copy the entire source directory to the destination one, you
215    * can do so like this:
216    * 
217    * <pre>
218    * Directory to; // the directory to copy to
219    * for (String file : dir.listAll()) {
220    *   dir.copy(to, file, newFile); // newFile can be either file, or a new name
221    * }
222    * </pre>
223    * <p>
224    * <b>NOTE:</b> this method does not check whether <i>dest<i> exist and will
225    * overwrite it if it does.
226    */
227   public void copy(Directory to, String src, String dest) throws IOException {
228     IndexOutput os = null;
229     IndexInput is = null;
230     IOException priorException = null;
231     try {
232       os = to.createOutput(dest);
233       is = openInput(src);
234       is.copyBytes(os, is.length());
235     } catch (IOException ioe) {
236       priorException = ioe;
237     } finally {
238       IOUtils.closeWhileHandlingException(priorException, os, is);
239     }
240   }
241
242   /**
243    * Copy contents of a directory src to a directory dest. If a file in src
244    * already exists in dest then the one in dest will be blindly overwritten.
245    * <p>
246    * <b>NOTE:</b> the source directory cannot change while this method is
247    * running. Otherwise the results are undefined and you could easily hit a
248    * FileNotFoundException.
249    * <p>
250    * <b>NOTE:</b> this method only copies files that look like index files (ie,
251    * have extensions matching the known extensions of index files).
252    * 
253    * @param src source directory
254    * @param dest destination directory
255    * @param closeDirSrc if <code>true</code>, call {@link #close()} method on 
256    *        source directory
257    * @deprecated should be replaced with calls to
258    *             {@link #copy(Directory, String, String)} for every file that
259    *             needs copying. You can use the following code:
260    * 
261    * <pre>
262    * IndexFileNameFilter filter = IndexFileNameFilter.getFilter();
263    * for (String file : src.listAll()) {
264    *   if (filter.accept(null, file)) {
265    *     src.copy(dest, file, file);
266    *   }
267    * }
268    * </pre>
269    */
270   @Deprecated
271   public static void copy(Directory src, Directory dest, boolean closeDirSrc) throws IOException {
272     IndexFileNameFilter filter = IndexFileNameFilter.getFilter();
273     for (String file : src.listAll()) {
274       if (filter.accept(null, file)) {
275         src.copy(dest, file, file);
276       }
277     }
278     if (closeDirSrc) {
279       src.close();
280     }
281   }
282
283   /**
284    * @throws AlreadyClosedException if this Directory is closed
285    */
286   protected final void ensureOpen() throws AlreadyClosedException {
287     if (!isOpen)
288       throw new AlreadyClosedException("this Directory is closed");
289   }
290 }