[ http://issues.apache.org/jira/browse/LUCENE-84?page=all ] Otis Gospodnetic resolved LUCENE-84: ------------------------------------
Fix Version: 1.9 Resolution: Fixed It looks like this old issue was fixed at some point, as FSDirectory now has the following method: public static void setDisableLocks(boolean doDisableLocks) { ... > Enhanced FSDirectory that allow lock disable via API > ---------------------------------------------------- > > Key: LUCENE-84 > URL: http://issues.apache.org/jira/browse/LUCENE-84 > Project: Lucene - Java > Type: Improvement > Components: Store > Versions: CVS Nightly - Specify date in submission > Environment: Operating System: All > Platform: PC > Reporter: John Methot > Assignee: Otis Gospodnetic > Priority: Minor > Fix For: 1.9 > Attachments: FSDirectory.java, FSDirectory.java > > Below is a new version of FSDirectory.java. It is based on 1/30/2003 source. > I have added one new version each of getDirectory(File) and getDirectory > (String). They take a new third argument 'boolean useLocks'. > The previous 'private static final boolean DISABLE_LOCKS' has been changed > to 'private static boolean _disableLocks' and is initialized to false. I also > added a new method 'private boolean locksDisabledByProp' that checks > the 'disableLuceneLocks' system property. > Method makeLock now checks the static _disableLocks as the first term in an > OR > clause, the second of which is a call to locksDisabledByProp. This allows use > in an applet that does not have write access to the local filesystem, and > when > the API is used in that way prevents the query of the system property that is > also disallowed in an applet by default (at least in Mozilla/Netscape). > From my applet, I can now invoke: > Searcher searcher = new IndexSearcher( > IndexReader.open(FSDirectory.getDirectory(indexFile, false, false))); > and I get an IndexSearcher that will work in the applet with no special > permissions other than applet JAR signing. > Obviously, email me ([EMAIL PROTECTED]) if you have any questions. > ************************* FSDirectory.java ******************************* > package org.apache.lucene.store; > /* ==================================================================== > * The Apache Software License, Version 1.1 > * > * Copyright (c) 2001 The Apache Software Foundation. All rights > * reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions > * are met: > * > * 1. Redistributions of source code must retain the above copyright > * notice, this list of conditions and the following disclaimer. > * > * 2. Redistributions in binary form must reproduce the above copyright > * notice, this list of conditions and the following disclaimer in > * the documentation and/or other materials provided with the > * distribution. > * > * 3. The end-user documentation included with the redistribution, > * if any, must include the following acknowledgment: > * "This product includes software developed by the > * Apache Software Foundation (http://www.apache.org/)." > * Alternately, this acknowledgment may appear in the software itself, > * if and wherever such third-party acknowledgments normally appear. > * > * 4. The names "Apache" and "Apache Software Foundation" and > * "Apache Lucene" must not be used to endorse or promote products > * derived from this software without prior written permission. For > * written permission, please contact [EMAIL PROTECTED] > * > * 5. Products derived from this software may not be called "Apache", > * "Apache Lucene", nor may "Apache" appear in their name, without > * prior written permission of the Apache Software Foundation. > * > * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED > * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES > * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE > * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR > * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, > * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT > * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF > * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND > * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, > * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT > * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF > * SUCH DAMAGE. > * ==================================================================== > * > * This software consists of voluntary contributions made by many > * individuals on behalf of the Apache Software Foundation. For more > * information on the Apache Software Foundation, please see > * <http://www.apache.org/>. > */ > import java.io.IOException; > import java.io.File; > import java.io.RandomAccessFile; > import java.util.Hashtable; > import org.apache.lucene.util.Constants; > /** > * Straightforward implementation of [EMAIL PROTECTED] Directory} as a > directory of files. > * <p>If the system property 'disableLuceneLocks' has the String value of > * "true", lock creation will be disabled. > * > * @see Directory > * @author Doug Cutting > */ > public final class FSDirectory extends Directory { > /** This cache of directories ensures that there is a unique Directory > * instance per path, so that synchronization on the Directory can be used > to > * synchronize access between readers and writers. > * > * This should be a WeakHashMap, so that entries can be GC'd, but that would > * require Java 1.2. Instead we use refcounts... */ > private static final Hashtable DIRECTORIES = new Hashtable(); > private static boolean _disableLocks = false; > private boolean locksDisabledByProp() > { > return Boolean.getBoolean("disableLuceneLocks") || Constants.JAVA_1_1; > } > /** Returns the directory instance for the named location, with option of > * disabled locking. > * > * <p>Directories are cached, so that, for a given canonical path, the same > * FSDirectory instance will always be returned. This permits > * synchronization on directories. > * > * @param path the path to the directory. > * @param create if true, create, or erase any existing contents. > * @param useLocks if false, don't use locks during index reads. Useful in > * read-only filesystems or from applets. > * @return the FSDirectory for the named file. */ > public static FSDirectory getDirectory(String path, boolean create, boolean > useLocks) > throws IOException { > _disableLocks = !useLocks; > return getDirectory(new File(path), create); > } > /** Returns the directory instance for the named location. > * > * <p>Directories are cached, so that, for a given canonical path, the same > * FSDirectory instance will always be returned. This permits > * synchronization on directories. > * > * @param path the path to the directory. > * @param create if true, create, or erase any existing contents. > * @return the FSDirectory for the named file. */ > public static FSDirectory getDirectory(String path, boolean create) > throws IOException { > return getDirectory(new File(path), create); > } > /** Returns the directory instance for the named location, with option of > * disabled locking. > * > * <p>Directories are cached, so that, for a given canonical path, the same > * FSDirectory instance will always be returned. This permits > * synchronization on directories. > * > * @param file the path to the directory. > * @param create if true, create, or erase any existing contents. > * @param useLocks if false, don't use locks during index reads. Useful in > * read-only filesystems or from applets. > * @return the FSDirectory for the named file. */ > public static FSDirectory getDirectory(File file, boolean create, boolean > useLocks) > throws IOException { > _disableLocks = !useLocks; > return getDirectory(file, create); > } > /** Returns the directory instance for the named location. > * > * <p>Directories are cached, so that, for a given canonical path, the same > * FSDirectory instance will always be returned. This permits > * synchronization on directories. > * > * @param file the path to the directory. > * @param create if true, create, or erase any existing contents. > * @return the FSDirectory for the named file. */ > public static FSDirectory getDirectory(File file, boolean create) > throws IOException { > file = new File(file.getCanonicalPath()); > FSDirectory dir; > synchronized (DIRECTORIES) { > dir = (FSDirectory)DIRECTORIES.get(file); > if (dir == null) { > dir = new FSDirectory(file, create); > DIRECTORIES.put(file, dir); > } else if (create) { > dir.create(); > } > } > synchronized (dir) { > dir.refCount++; > } > return dir; > } > private File directory = null; > private int refCount; > private FSDirectory(File path, boolean create) throws IOException { > directory = path; > if (create) > create(); > if (!directory.isDirectory()) > throw new IOException(path + " not a directory"); > } > private synchronized void create() throws IOException { > if (!directory.exists()) > if (!directory.mkdir()) > throw new IOException("Cannot create directory: " + directory); > String[] files = directory.list(); // clear old files > for (int i = 0; i < files.length; i++) { > File file = new File(directory, files[i]); > if (!file.delete()) > throw new IOException("couldn't delete " + files[i]); > } > } > /** Returns an array of strings, one for each file in the directory. */ > public final String[] list() throws IOException { > return directory.list(); > } > /** Returns true iff a file with the given name exists. */ > public final boolean fileExists(String name) throws IOException { > File file = new File(directory, name); > return file.exists(); > } > /** Returns the time the named file was last modified. */ > public final long fileModified(String name) throws IOException { > File file = new File(directory, name); > return file.lastModified(); > } > /** Returns the time the named file was last modified. */ > public static final long fileModified(File directory, String name) > throws IOException { > File file = new File(directory, name); > return file.lastModified(); > } > /** Set the modified time of an existing file to now. */ > public void touchFile(String name) throws IOException { > File file = new File(directory, name); > file.setLastModified(System.currentTimeMillis()); > } > /** Returns the length in bytes of a file in the directory. */ > public final long fileLength(String name) throws IOException { > File file = new File(directory, name); > return file.length(); > } > /** Removes an existing file in the directory. */ > public final void deleteFile(String name) throws IOException { > File file = new File(directory, name); > if (!file.delete()) > throw new IOException("couldn't delete " + name); > } > /** Renames an existing file in the directory. */ > public final synchronized void renameFile(String from, String to) > throws IOException { > File old = new File(directory, from); > File nu = new File(directory, to); > /* This is not atomic. If the program crashes between the call to > delete() and the call to renameTo() then we're screwed, but I've > been unable to figure out how else to do this... */ > if (nu.exists()) > if (!nu.delete()) > throw new IOException("couldn't delete " + to); > if (!old.renameTo(nu)) > throw new IOException("couldn't rename " + from + " to " + to); > } > /** Creates a new, empty file in the directory with the given name. > Returns a stream writing this file. */ > public final OutputStream createFile(String name) throws IOException { > return new FSOutputStream(new File(directory, name)); > } > /** Returns a stream reading an existing file. */ > public final InputStream openFile(String name) throws IOException { > return new FSInputStream(new File(directory, name)); > } > /** Constructs a [EMAIL PROTECTED] Lock} with the specified name. Locks > are implemented > * with [EMAIL PROTECTED] File#createNewFile() }. > * > * <p>In JDK 1.1 or if system property <I>disableLuceneLocks</I> is the > * string "true", locks are disabled. Assigning this property any other > * string will <B>not</B> prevent creation of lock files. Locks are also > * disabled if getDirectory was invoked with the optional third argument > * useLocks set to false. > * Disabling locks is useful when using Lucene on read-only medium, such > * as CD-ROM, or from an applet that does not have filesystem write > * permission. > * > * @param name the name of the lock file > * @return an instance of <code>Lock</code> holding the lock > */ > public final Lock makeLock(String name) { > final File lockFile = new File(directory, name); > if (_disableLocks || locksDisabledByProp()) > { > return new Lock() { > public boolean obtain() throws IOException { > return true; > } > public void release() { > return; > } > public String toString() { > return "[EMAIL PROTECTED]"; > } > }; > } > else > { > return new Lock() { > public boolean obtain() throws IOException { > return lockFile.createNewFile(); > } > public void release() { > lockFile.delete(); > } > public String toString() { > return "Lock@" + lockFile; > } > }; > } > } > /** Closes the store to future operations. */ > public final synchronized void close() throws IOException { > if (--refCount <= 0) { > synchronized (DIRECTORIES) { > DIRECTORIES.remove(directory); > } > } > } > /** For debug output. */ > public String toString() { > return "FSDirectory@" + directory; > } > } > final class FSInputStream extends InputStream { > private class Descriptor extends RandomAccessFile { > public long position; > public Descriptor(File file, String mode) throws IOException { > super(file, mode); > } > } > Descriptor file = null; > boolean isClone; > public FSInputStream(File path) throws IOException { > file = new Descriptor(path, "r"); > length = file.length(); > } > /** InputStream methods */ > protected final void readInternal(byte[] b, int offset, int len) > throws IOException { > synchronized (file) { > long position = getFilePointer(); > if (position != file.position) { > file.seek(position); > file.position = position; > } > int total = 0; > do { > int i = file.read(b, offset+total, len-total); > if (i == -1) > throw new IOException("read past EOF"); > file.position += i; > total += i; > } while (total < len); > } > } > public final void close() throws IOException { > if (!isClone) > file.close(); > } > /** Random-access methods */ > protected final void seekInternal(long position) throws IOException { > } > protected final void finalize() throws IOException { > close(); // close the file > } > public Object clone() { > FSInputStream clone = (FSInputStream)super.clone(); > clone.isClone = true; > return clone; > } > } > final class FSOutputStream extends OutputStream { > RandomAccessFile file = null; > public FSOutputStream(File path) throws IOException { > file = new RandomAccessFile(path, "rw"); > } > /** output methods: */ > public final void flushBuffer(byte[] b, int size) throws IOException { > file.write(b, 0, size); > } > public final void close() throws IOException { > super.close(); > file.close(); > } > /** Random-access methods */ > public final void seek(long pos) throws IOException { > super.seek(pos); > file.seek(pos); > } > public final long length() throws IOException { > return file.length(); > } > protected final void finalize() throws IOException { > file.close(); // close the file > } > } -- This message is automatically generated by JIRA. - If you think it was sent incorrectly contact one of the administrators: http://issues.apache.org/jira/secure/Administrators.jspa - For more information on JIRA, see: http://www.atlassian.com/software/jira --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]