You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by rh...@apache.org on 2014/04/22 15:25:38 UTC

svn commit: r1589124 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/io/ engine/org/apache/derby/impl/io/vfmem/ engine/org/apache/derby/io/ optional/org/apache/derby/optional/lucene/ testing/org/apache/derbyTesting/functionTests/tests/lang...

Author: rhillegas
Date: Tue Apr 22 13:25:37 2014
New Revision: 1589124

URL: http://svn.apache.org/r1589124
Log:
DERBY-590: Add support for creating Lucene indexes in in-memory databases; commit derby-590-24-ad-luceneDirectory.diff.

Added:
    db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/DerbyIndexInput.java   (with props)
    db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/DerbyIndexOutput.java   (with props)
    db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/DerbyLuceneDir.java   (with props)
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneInMemoryTest.java   (with props)
Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/io/DirRandomAccessFile.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/io/vfmem/VirtualRandomAccessFile.java
    db/derby/code/trunk/java/engine/org/apache/derby/io/StorageRandomAccessFile.java
    db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/LuceneListIndexesVTI.java
    db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/LuceneQueryVTI.java
    db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/LuceneSupport.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneCoarseAuthorizationTest.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneSuite.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneSupportPermsTest.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/CorruptRandomAccessFile.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/io/DirRandomAccessFile.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/io/DirRandomAccessFile.java?rev=1589124&r1=1589123&r2=1589124&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/io/DirRandomAccessFile.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/io/DirRandomAccessFile.java Tue Apr 22 13:25:37 2014
@@ -37,6 +37,9 @@ import java.io.FileNotFoundException;
  */
 class DirRandomAccessFile extends RandomAccessFile implements StorageRandomAccessFile
 {
+    // for cloning
+    private final   File    _name;
+    private final   String  _mode;
 
     /**
      * Construct a StorageRandomAccessFileImpl.
@@ -55,6 +58,20 @@ class DirRandomAccessFile extends Random
     DirRandomAccessFile( File name, String mode) throws FileNotFoundException
     {
         super( name, mode);
+        _name = name;
+        _mode = mode;
+    }
+
+    /** Clone this file abstaction */
+    public  DirRandomAccessFile clone()
+    {
+        try {
+            return new DirRandomAccessFile( _name, _mode );
+        }
+        catch (IOException ioe)
+        {
+            throw new RuntimeException( ioe.getMessage(), ioe );
+        }
     }
 
     /**

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/io/vfmem/VirtualRandomAccessFile.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/io/vfmem/VirtualRandomAccessFile.java?rev=1589124&r1=1589123&r2=1589124&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/io/vfmem/VirtualRandomAccessFile.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/io/vfmem/VirtualRandomAccessFile.java Tue Apr 22 13:25:37 2014
@@ -39,6 +39,8 @@ public class VirtualRandomAccessFile
 
     /** The source entry. */
     private final DataStoreEntry entry;
+    /** whether the file is read-only */
+    private final   boolean _readOnly;
     /** Current position / file pointer. */
     private long fp;
     /** Stream used to read from the source entry. */
@@ -68,6 +70,7 @@ public class VirtualRandomAccessFile
     public VirtualRandomAccessFile(DataStoreEntry entry, boolean readOnly)
             throws FileNotFoundException {
         this.entry = entry;
+        _readOnly = readOnly;
         bIn = entry.getInputStream();
         bIn.setPosition(0L);
         dIs = new DataInputStream(bIn);
@@ -82,6 +85,17 @@ public class VirtualRandomAccessFile
         }
     }
 
+    public  VirtualRandomAccessFile clone()
+    {
+        try {
+            return new VirtualRandomAccessFile( entry, _readOnly );
+        }
+        catch (IOException ioe)
+        {
+            throw new RuntimeException( ioe.getMessage(), ioe );
+        }
+    }
+
     public void close() throws IOException {
         dIs.close();
         // If opened in read-only mode, the output streams are null.

Modified: db/derby/code/trunk/java/engine/org/apache/derby/io/StorageRandomAccessFile.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/io/StorageRandomAccessFile.java?rev=1589124&r1=1589123&r2=1589124&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/io/StorageRandomAccessFile.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/io/StorageRandomAccessFile.java Tue Apr 22 13:25:37 2014
@@ -126,4 +126,7 @@ public interface StorageRandomAccessFile
      * <code>b.length - off</code>
      */
     public int read(byte[] b, int off, int len) throws IOException;
+
+    /** Clone this file abstraction */
+    public  StorageRandomAccessFile clone();
 }

Added: db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/DerbyIndexInput.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/DerbyIndexInput.java?rev=1589124&view=auto
==============================================================================
--- db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/DerbyIndexInput.java (added)
+++ db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/DerbyIndexInput.java Tue Apr 22 13:25:37 2014
@@ -0,0 +1,218 @@
+/*
+
+   Class org.apache.derby.optional.lucene.LuceneSupport
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+
+*/
+
+package org.apache.derby.optional.lucene;
+
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.sql.SQLException;
+import java.util.ArrayList;
+
+import org.apache.lucene.store.AlreadyClosedException;
+import org.apache.lucene.store.IndexInput;
+
+import org.apache.derby.io.StorageFile;
+import org.apache.derby.io.StorageRandomAccessFile;
+
+/**
+ * <p>
+ * Wrapper for a StorageRandomAccessFile which can serve as a
+ * Lucene IndexInput.
+ * </p>
+ */
+public  class DerbyIndexInput   extends IndexInput
+{
+    /////////////////////////////////////////////////////////////////////
+    //
+    //  CONSTANTS
+    //
+    /////////////////////////////////////////////////////////////////////
+
+    /////////////////////////////////////////////////////////////////////
+    //
+    //  STATE
+    //
+    /////////////////////////////////////////////////////////////////////
+
+    // constructor state
+    private StorageFile                     _file;
+    private StorageRandomAccessFile _sraf;
+    private final   ArrayList<DerbyIndexInput>  _clones = new ArrayList<DerbyIndexInput>();
+
+    // mutable state
+    private boolean _closed = false;
+
+    /////////////////////////////////////////////////////////////////////
+    //
+    //  CONSTRUCTOR
+    //
+    /////////////////////////////////////////////////////////////////////
+
+    /** Construct from a StorageRandomAccessFile */
+    DerbyIndexInput( StorageFile file )
+        throws IOException
+    {
+        super( file.getPath() );
+
+        try {
+            setConstructorFields( file );
+        }
+        catch (PrivilegedActionException pae) { wrapWithIOException( pae ); }
+    }
+
+    /** Set the constructor fields */
+    private void    setConstructorFields( final StorageFile file )
+        throws IOException, PrivilegedActionException
+    {
+        AccessController.doPrivileged
+            (
+             new PrivilegedExceptionAction<Object>()
+             {
+                public Object run() throws IOException
+                {
+                    _file = file;
+                    _sraf = _file.getRandomAccessFile( "r" );
+
+                    return null;
+                }
+             }
+             );
+    }
+
+    /////////////////////////////////////////////////////////////////////
+    //
+    //  IndexInput METHODS
+    //
+    /////////////////////////////////////////////////////////////////////
+
+    public  IndexInput  clone()
+    {
+        checkIfClosed();
+        
+        try {
+            DerbyIndexInput clone = new DerbyIndexInput( _file );
+            _clones.add( clone );
+
+            clone.seek( getFilePointer() );
+
+            return clone;
+        }
+        catch (IOException ioe) { throw wrap( ioe ); }
+    }
+
+    public void close() throws IOException
+    {
+        if ( !_closed )
+        {
+            _closed = true;
+            _sraf.close();
+
+            for ( DerbyIndexInput clone : _clones ) { clone.close(); }
+            _clones.clear();
+
+            _file = null;
+            _sraf = null;
+        }
+    }
+
+    public long getFilePointer()
+    {
+        checkIfClosed();
+
+        try {
+            return _sraf.getFilePointer();
+        }
+        catch (IOException ioe) { throw wrap( ioe ); }
+    }
+
+    public long length()
+    {
+        checkIfClosed();
+
+        try {
+            return _sraf.length();
+        }
+        catch (IOException ioe) { throw wrap( ioe ); }
+    }
+
+    public void seek( long pos )    throws IOException
+    {
+        checkIfClosed();
+        _sraf.seek( pos );
+    }
+
+    /////////////////////////////////////////////////////////////////////
+    //
+    //  DataInput METHODS
+    //
+    /////////////////////////////////////////////////////////////////////
+
+    public byte readByte()  throws IOException
+    {
+        checkIfClosed();
+        return _sraf.readByte();
+    }
+
+    public void readBytes( byte[] b, int offset, int len )
+        throws IOException
+    {
+        checkIfClosed();
+
+        int     bytesRead = 0;
+        while ( bytesRead < len )
+        {
+            int increment = _sraf.read( b, offset + bytesRead , len - bytesRead );
+            if ( increment < 0 ) { break; }
+
+            bytesRead += increment;
+        }
+    }
+
+    /////////////////////////////////////////////////////////////////////
+    //
+    //  MINIONS
+    //
+    /////////////////////////////////////////////////////////////////////
+
+    /** Raise a Lucene error if this object has been closed */
+    private void    checkIfClosed()
+    {
+        if ( _closed )
+        {
+            throw new AlreadyClosedException( toString() );
+        }
+    }
+
+    /** Wrap an exception in a Runtime exception */
+    private RuntimeException    wrap( Throwable t )
+    {
+        return new RuntimeException( t.getMessage(), t );
+    }
+
+    /** Wrap an exception in an IOException */
+    private IOException wrapWithIOException( Throwable t )
+    {
+        return new IOException( t.getMessage(), t );
+    }
+    
+}

Propchange: db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/DerbyIndexInput.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/DerbyIndexOutput.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/DerbyIndexOutput.java?rev=1589124&view=auto
==============================================================================
--- db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/DerbyIndexOutput.java (added)
+++ db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/DerbyIndexOutput.java Tue Apr 22 13:25:37 2014
@@ -0,0 +1,143 @@
+/*
+
+   Class org.apache.derby.optional.lucene.LuceneSupport
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+
+*/
+
+package org.apache.derby.optional.lucene;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+import org.apache.lucene.store.AlreadyClosedException;
+import org.apache.lucene.store.IndexOutput;
+
+import org.apache.derby.io.StorageFile;
+import org.apache.derby.io.StorageRandomAccessFile;
+
+/**
+ * <p>
+ * Wrapper for a StorageRandomAccessFile which can serve as a
+ * Lucene IndexOutput.
+ * </p>
+ */
+public  class DerbyIndexOutput   extends IndexOutput
+{
+    /////////////////////////////////////////////////////////////////////
+    //
+    //  CONSTANTS
+    //
+    /////////////////////////////////////////////////////////////////////
+
+    /////////////////////////////////////////////////////////////////////
+    //
+    //  STATE
+    //
+    /////////////////////////////////////////////////////////////////////
+
+    // constructor state
+    private StorageFile                     _file;
+    private DerbyLuceneDir              _parentDir;
+    private StorageRandomAccessFile _sraf;
+
+    /////////////////////////////////////////////////////////////////////
+    //
+    //  CONSTRUCTOR
+    //
+    /////////////////////////////////////////////////////////////////////
+
+    /** Construct from a StorageRandomAccessFile */
+    DerbyIndexOutput( StorageFile file, DerbyLuceneDir parentDir )
+        throws IOException
+    {
+        _file = file;
+        _parentDir = parentDir;
+        _sraf = _file.getRandomAccessFile( "rw" );
+    }
+
+    /////////////////////////////////////////////////////////////////////
+    //
+    //  IndexInput METHODS
+    //
+    /////////////////////////////////////////////////////////////////////
+
+    public void close() throws IOException
+    {
+        _sraf.close();
+        _parentDir.removeIndexOutput( _file.getName() );
+
+        _file = null;
+        _parentDir = null;
+        _sraf = null;
+    }
+
+    public long getFilePointer()
+    {
+        try {
+            return _sraf.getFilePointer();
+        }
+        catch (IOException ioe) { throw wrap( ioe ); }
+    }
+
+    @Deprecated
+    public void seek( long pos )    throws IOException
+    {
+        _sraf.seek( pos );
+    }
+
+    public  void flush()    throws IOException
+    {
+        _sraf.sync();
+    }
+
+    public long length()    throws IOException
+    {
+        return _sraf.length();
+    }
+
+    /////////////////////////////////////////////////////////////////////
+    //
+    //  DataInput METHODS
+    //
+    /////////////////////////////////////////////////////////////////////
+
+    public void writeByte(byte b)   throws IOException
+    {
+        _sraf.writeByte( b );
+    }
+
+    public void writeBytes(byte[] b, int offset, int length)
+        throws IOException
+    {
+        _sraf.write( b, offset, length );
+    }
+
+
+    /////////////////////////////////////////////////////////////////////
+    //
+    //  MINIONS
+    //
+    /////////////////////////////////////////////////////////////////////
+
+    /** Wrap an exception in a Runtime exception */
+    private RuntimeException    wrap( Throwable t )
+    {
+        return new RuntimeException( t.getMessage(), t );
+    }
+    
+}

Propchange: db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/DerbyIndexOutput.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/DerbyLuceneDir.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/DerbyLuceneDir.java?rev=1589124&view=auto
==============================================================================
--- db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/DerbyLuceneDir.java (added)
+++ db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/DerbyLuceneDir.java Tue Apr 22 13:25:37 2014
@@ -0,0 +1,350 @@
+/*
+
+   Class org.apache.derby.optional.lucene.LuceneSupport
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+
+*/
+
+package org.apache.derby.optional.lucene;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.HashMap;
+
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.IndexInput;
+import org.apache.lucene.store.IndexOutput;
+import org.apache.lucene.store.IOContext;
+import org.apache.lucene.store.SingleInstanceLockFactory;
+
+import org.apache.derby.io.StorageFactory;
+import org.apache.derby.io.StorageFile;
+import org.apache.derby.shared.common.reference.SQLState;
+
+/**
+ * <p>
+ * Derby implementation of Lucene Directory.
+ * </p>
+ */
+class DerbyLuceneDir extends Directory
+{
+    /////////////////////////////////////////////////////////////////////
+    //
+    //  CONSTANTS
+    //
+    /////////////////////////////////////////////////////////////////////
+
+    /////////////////////////////////////////////////////////////////////
+    //
+    //  STATE
+    //
+    /////////////////////////////////////////////////////////////////////
+
+    // constructor args
+    private final   StorageFactory  _storageFactory;
+    private final   StorageFile     _directory;
+
+    // files open for output which may need to be sync'd
+    private HashMap<String,DerbyIndexOutput>    _outputFiles = new HashMap<String,DerbyIndexOutput>();
+
+    private boolean _closed = false;
+
+    // only supply one DerbyLuceneDir per database
+    private static  HashMap<String,DerbyLuceneDir>  _openDirectories = new HashMap<String,DerbyLuceneDir>();
+
+    /////////////////////////////////////////////////////////////////////
+    //
+    //  CONSTRUCTOR AND FACTORY METHODS
+    //
+    /////////////////////////////////////////////////////////////////////
+
+    /**
+     * <p>
+     * Lookup a directory, creating its path as necessary.
+     * </p>
+     */
+    static  synchronized    DerbyLuceneDir  getDirectory( StorageFactory storageFactory, String directoryPath )
+        throws SQLException
+    {
+        try {
+            DerbyLuceneDir  candidate = new DerbyLuceneDir( storageFactory, directoryPath );
+            String              key = getKey( candidate );
+            DerbyLuceneDir  result = _openDirectories.get( key );
+
+            if ( result == null )
+            {
+                result = candidate;
+                result.setLockFactory( new SingleInstanceLockFactory() );
+                _openDirectories.put( key, result );
+            }
+
+            createPath( result._directory );
+
+            return result;
+        }
+        catch (IOException ioe) { throw LuceneSupport.wrap( ioe ); }
+        catch (PrivilegedActionException pae) { throw LuceneSupport.wrap( pae ); }
+    }
+
+    /**
+     * <p>
+     * Remove a directory from the map.
+     * </p>
+     */
+    private static  synchronized    void    removeDir( DerbyLuceneDir dir )
+    {
+        _openDirectories.remove( getKey( dir ) );
+    }
+
+    /** Get the key associated with a directory */
+    private static  String  getKey( DerbyLuceneDir dir ) { return dir._directory.getPath(); }
+    
+    /**
+     * <p>
+     * Construct from the database StorageFactory and a directory path
+     * of the form lucene/$schemaName/$tableName/$columnName.
+     * Creates the directory if it does not already exist.
+     * </p>
+     */
+    private DerbyLuceneDir( StorageFactory storageFactory, String directoryPath )
+    {
+        _storageFactory = storageFactory;
+        _directory = _storageFactory.newStorageFile( directoryPath );
+    }
+
+    /////////////////////////////////////////////////////////////////////
+    //
+    //  WRAPPERS FOR StorageFactory METHODS
+    //
+    /////////////////////////////////////////////////////////////////////
+
+    /**
+     * <p>
+     * Get a file in this directory.
+     * </p>
+     */
+    StorageFile     getFile( String fileName )
+    {
+        return _storageFactory.newStorageFile( _directory, fileName );
+    }
+
+    /**
+     * <p>
+     * Get the Derby directory backing this Lucene directory.
+     * </p>
+     */
+    StorageFile getDirectory()
+    {
+        return _directory;
+    }
+
+    /////////////////////////////////////////////////////////////////////
+    //
+    //  Directory METHODS
+    //
+    /////////////////////////////////////////////////////////////////////
+
+    /**
+     * <p>
+     * Close this directory and remove it from the map of open directories.
+     * </p>
+     */
+    public void close()    throws IOException
+    {
+        // close the output files
+        for ( String fileName : _outputFiles.keySet() )
+        {
+            _outputFiles.get( fileName ).close();
+        }
+
+        _outputFiles.clear();
+        _closed = true;
+        removeDir( this );
+    }
+
+    /**  Create a new, empty file for writing */
+    public DerbyIndexOutput createOutput
+        ( String name, IOContext context )
+        throws IOException
+    {
+        checkIfClosed();
+
+        DerbyIndexOutput    indexOutput = _outputFiles.get( name );
+        if ( indexOutput != null )
+        {
+            indexOutput.close();
+        }
+
+        StorageFile file = getStorageFile( name );
+        if ( file.exists() ) { deleteFile( name ); }
+        
+        indexOutput = new DerbyIndexOutput( file, this );
+        _outputFiles.put( name, indexOutput );
+
+        return indexOutput;
+    }
+
+    public void deleteFile( String name ) throws IOException
+    {
+        checkIfClosed();
+        
+        StorageFile file = getStorageFile( name );
+
+        if ( file.exists() )
+        {
+            if ( !file.delete() )
+            {
+                throw newIOException( SQLState.UNABLE_TO_DELETE_FILE, file.getPath() );
+            }
+        }
+    }
+
+    public boolean fileExists( String name )  throws IOException
+    {
+        checkIfClosed();
+        
+        return getStorageFile( name ).exists();
+    }
+
+    public long fileLength( String name ) throws IOException
+    {
+        checkIfClosed();
+        
+        DerbyIndexInput indexInput = openInput( name, null );
+
+        try {
+            return indexInput.length();
+        }
+        finally
+        {
+            indexInput.close();
+        }
+    }
+
+    public String[] listAll()   throws IOException
+    {
+        checkIfClosed();
+        
+        return _directory.list();
+    }
+
+    public DerbyIndexInput openInput
+        ( String name, IOContext context )
+        throws IOException
+    {
+        checkIfClosed();
+        
+        StorageFile file = getStorageFile( name );
+        if ( !file.exists() )
+        {
+            throw new FileNotFoundException( file.getPath() );
+        }
+
+        return getIndexInput( file );
+    }
+
+    public void sync( Collection<String> names )
+        throws IOException
+    {
+        for ( String name : names )
+        {
+            DerbyIndexOutput    indexOutput = _outputFiles.get( name );
+
+            if ( indexOutput != null )
+            {
+                indexOutput.flush();
+            }
+        }
+    }
+
+    /////////////////////////////////////////////////////////////////////
+    //
+    //  FOR USE WHEN CLOSING CHILD FILES
+    //
+    /////////////////////////////////////////////////////////////////////
+
+    /** Remove the named file from the list of output files */
+    void    removeIndexOutput( String name )
+    {
+        _outputFiles.remove( name );
+    }
+
+    /////////////////////////////////////////////////////////////////////
+    //
+    //  MINIONS
+    //
+    /////////////////////////////////////////////////////////////////////
+
+    /** Get a DerbyIndexInput on the named file */
+    private DerbyIndexInput getIndexInput( String name )
+        throws IOException
+    {
+        return getIndexInput( getStorageFile( name ) );
+    }
+    private DerbyIndexInput getIndexInput( StorageFile file )
+        throws IOException
+    {
+        return new DerbyIndexInput( file );
+    }
+
+    /** Turn a file name into a StorageFile handle */
+    private StorageFile getStorageFile( String name )
+    {
+        return _storageFactory.newStorageFile( _directory, name );
+    }
+
+    /** Make an IOException with the given SQLState and args */
+    private IOException newIOException( String sqlState, Object... args )
+    {
+        return new IOException( LuceneSupport.newSQLException( sqlState, args ).getMessage() );
+    }
+
+    /** Raise an exception if this directory is closed */
+    private void    checkIfClosed() throws IOException
+    {
+        if ( _closed )
+        {
+            throw newIOException( SQLState.DATA_CONTAINER_CLOSED );
+        }
+    }
+
+	/**
+	 * Create the path if necessary.
+	 */
+    private static void createPath( final StorageFile directory )
+        throws IOException, PrivilegedActionException
+    {
+        AccessController.doPrivileged
+            (
+             new PrivilegedExceptionAction<Object>()
+             {
+                 public Object run() throws IOException
+                 {
+                     directory.mkdirs();
+                     return null;
+                 }
+             }
+             );
+    }
+
+}
+

Propchange: db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/DerbyLuceneDir.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/LuceneListIndexesVTI.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/LuceneListIndexesVTI.java?rev=1589124&r1=1589123&r2=1589124&view=diff
==============================================================================
--- db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/LuceneListIndexesVTI.java (original)
+++ db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/LuceneListIndexesVTI.java Tue Apr 22 13:25:37 2014
@@ -21,8 +21,6 @@
 
 package org.apache.derby.optional.lucene;
 
-import java.io.File;
-import java.io.FileFilter;
 import java.io.IOException;
 import java.security.AccessController;
 import java.security.PrivilegedActionException;
@@ -34,6 +32,9 @@ import java.text.DateFormat;
 import java.util.ArrayList;
 import java.util.Properties;
 
+import org.apache.derby.io.StorageFactory;
+import org.apache.derby.io.StorageFile;
+
 import org.apache.derby.shared.common.reference.SQLState;
 import org.apache.derby.vti.StringColumnVTI;
 
@@ -45,7 +46,7 @@ import org.apache.derby.vti.StringColumn
 public class LuceneListIndexesVTI extends StringColumnVTI
 {
     private Connection  connection;
-	private File[] indexes;
+	private StorageFile[] indexes;
 	private int row = -1;
 
     private String      schema;
@@ -75,22 +76,21 @@ public class LuceneListIndexesVTI extend
               );
 		
         connection = LuceneSupport.getDefaultConnection();
-		String dir = LuceneSupport.getIndexLocation( connection, null, null, null );
+        StorageFactory  dir = LuceneSupport.getStorageFactory( connection );
 		
-		File luceneDir = new File(dir);
-        DirFilter   dirFilter = new DirFilter();
-        ArrayList<File> allIndexes = new ArrayList<File>();
+		StorageFile luceneDir = dir.newStorageFile( LuceneSupport.LUCENE_DIR );
+        ArrayList<StorageFile> allIndexes = new ArrayList<StorageFile>();
 
-        File[]  schemas = listFiles( luceneDir, dirFilter );
+        StorageFile[]  schemas = listDirectories( dir, luceneDir );
         if ( schemas != null )
         {
-            for ( File schema : schemas )
+            for ( StorageFile schema : schemas )
             {
-                File[]  tables = listFiles( schema, dirFilter );
-                for ( File table : tables )
+                StorageFile[]  tables = listDirectories( dir, schema );
+                for ( StorageFile table : tables )
                 {
-                    File[]  indexes = listFiles( table, dirFilter );
-                    for ( File index : indexes )
+                    StorageFile[]  indexes = listDirectories( dir, table );
+                    for ( StorageFile index : indexes )
                     {
                         allIndexes.add( index );
                     }
@@ -98,7 +98,7 @@ public class LuceneListIndexesVTI extend
             }
         }
 
-        indexes = new File[ allIndexes.size() ];
+        indexes = new StorageFile[ allIndexes.size() ];
         allIndexes.toArray( indexes );
 	}
 
@@ -177,23 +177,17 @@ public class LuceneListIndexesVTI extend
         catch (NumberFormatException nfe) { throw LuceneSupport.wrap( nfe ); }
     }
     
-	
-    public  static  class   DirFilter   implements  FileFilter
-    {
-        public  boolean accept( File file ) { return file.isDirectory(); }
-    }
-
     /** Fill in the schema, table, and column names */
     private void    readSchemaTableColumn()
         throws SQLException
     {
         if ( column != null ) { return; }
         
-        File    columnDir = indexes[ row ];
+        StorageFile    columnDir = indexes[ row ];
         column = columnDir.getName();
-        File    tableDir = columnDir.getParentFile();
+        StorageFile    tableDir = columnDir.getParentDir();
         table = tableDir.getName();
-        File    schemaDir = tableDir.getParentFile();
+        StorageFile    schemaDir = tableDir.getParentDir();
         schema = schemaDir.getName();
     }
 
@@ -212,7 +206,7 @@ public class LuceneListIndexesVTI extend
         {
             try {
                 readSchemaTableColumn();
-                File    indexPropertiesFile = LuceneSupport.getIndexPropertiesFile( connection, schema, table, column );
+                StorageFile    indexPropertiesFile = LuceneSupport.getIndexPropertiesFile( connection, schema, table, column );
                 rowProperties = readIndexProperties( indexPropertiesFile );
             }
             catch (IOException ioe) { throw LuceneSupport.wrap( ioe ); }
@@ -223,24 +217,35 @@ public class LuceneListIndexesVTI extend
     }
 
     /** List files */
-    private static  File[]  listFiles( final File file, final FileFilter fileFilter )
+    private static  StorageFile[]  listDirectories( final StorageFactory storageFactory, final StorageFile dir )
         throws IOException, PrivilegedActionException
     {
         return AccessController.doPrivileged
             (
-             new PrivilegedExceptionAction<File[]>()
+             new PrivilegedExceptionAction<StorageFile[]>()
              {
-                public File[] run() throws IOException
+                public StorageFile[] run() throws IOException
                 {
-                    if ( fileFilter == null )   { return file.listFiles(); }
-                    else { return file.listFiles( fileFilter ); }
+                    ArrayList<StorageFile>  subdirectories = new ArrayList<StorageFile>();
+                    String[]    fileNames = dir.list();
+
+                    for ( String fileName : fileNames )
+                    {
+                        StorageFile candidate = storageFactory.newStorageFile( dir, fileName );
+                        if ( candidate.isDirectory() ) { subdirectories.add( candidate ); }
+                    }
+
+                    StorageFile[]   result = new StorageFile[ subdirectories.size() ];
+                    subdirectories.toArray( result );
+                    
+                    return result;
                 }
              }
              );
     }
 
     /** Read the index properties file */
-    private static  Properties readIndexProperties( final File file )
+    private static  Properties readIndexProperties( final StorageFile file )
         throws IOException, PrivilegedActionException
     {
         return AccessController.doPrivileged

Modified: db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/LuceneQueryVTI.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/LuceneQueryVTI.java?rev=1589124&r1=1589123&r2=1589124&view=diff
==============================================================================
--- db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/LuceneQueryVTI.java (original)
+++ db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/LuceneQueryVTI.java Tue Apr 22 13:25:37 2014
@@ -21,7 +21,6 @@
 
 package org.apache.derby.optional.lucene;
 
-import java.io.File;
 import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -36,6 +35,7 @@ import java.sql.Time;
 import java.sql.Timestamp;
 import java.util.Properties;
 
+import org.apache.derby.io.StorageFile;
 import org.apache.derby.shared.common.reference.SQLState;
 import org.apache.derby.optional.api.LuceneUtils;
 import org.apache.derby.vti.RestrictedVTI;
@@ -429,16 +429,16 @@ public class LuceneQueryVTI extends Stri
             // make sure the user has SELECT privilege on all relevant columns of the underlying table
             vetPrivileges();
         
-            String          indexhome = LuceneSupport.getIndexLocation( _connection, _schema, _table, _column);
-            File            propertiesFile = LuceneSupport.getIndexPropertiesFile( _connection, _schema, _table, _column );
+            DerbyLuceneDir  derbyLuceneDir = LuceneSupport.getDerbyLuceneDir( _connection, _schema, _table, _column );
+            StorageFile propertiesFile = LuceneSupport.getIndexPropertiesFile( derbyLuceneDir );
             Properties  indexProperties = readIndexProperties( propertiesFile );
             String          analyzerMaker = indexProperties.getProperty( LuceneSupport.ANALYZER_MAKER );
             Analyzer    analyzer = getAnalyzer( analyzerMaker );
 
             vetLuceneVersion( indexProperties.getProperty( LuceneSupport.LUCENE_VERSION ) );
 
-            _indexReader = getIndexReader( new File( indexhome.toString() ) );
-            _searcher = new IndexSearcher(_indexReader);
+            _indexReader = getIndexReader( derbyLuceneDir );
+            _searcher = new IndexSearcher( _indexReader );
 
             QueryParser qp = getQueryParser
                 (
@@ -455,9 +455,8 @@ public class LuceneQueryVTI extends Stri
             if ( _scoreCeiling != 0 ) {
                 tsdc = TopScoreDocCollector.create( _windowSize, new ScoreDoc( 0, _scoreCeiling ), true );
             }
-            _searcher.search(luceneQuery, tsdc);
-            TopDocs topdocs = tsdc.topDocs();
-            _hits = topdocs.scoreDocs;
+
+            searchAndScore( luceneQuery, tsdc );
         }
         catch (IOException ioe) { throw LuceneSupport.wrap( ioe ); }
         catch (ParseException pe) { throw LuceneSupport.wrap( pe ); }
@@ -563,7 +562,7 @@ public class LuceneQueryVTI extends Stri
 	 * 
 	 * @param indexHome The directory holding the Lucene index.
 	 */
-	private static IndexReader getIndexReader( final File indexHome )
+	private static IndexReader getIndexReader( final DerbyLuceneDir dir )
         throws IOException, PrivilegedActionException
     {
         return AccessController.doPrivileged
@@ -572,14 +571,14 @@ public class LuceneQueryVTI extends Stri
              {
                  public IndexReader run() throws SQLException, IOException
                  {
-                     return DirectoryReader.open( FSDirectory.open( indexHome ) );
+                     return DirectoryReader.open( dir );
                  }
              }
              );
 	}
 	
     /** Read the index properties file */
-    private static  Properties readIndexProperties( final File file )
+    private static  Properties readIndexProperties( final StorageFile file )
         throws IOException, PrivilegedActionException
     {
         return AccessController.doPrivileged
@@ -615,4 +614,24 @@ public class LuceneQueryVTI extends Stri
              );
 	}
 	
+    /** Read the index properties file */
+    private void    searchAndScore( final Query luceneQuery, final TopScoreDocCollector tsdc )
+        throws IOException, PrivilegedActionException
+    {
+        AccessController.doPrivileged
+            (
+             new PrivilegedExceptionAction<Object>()
+             {
+                public Object run() throws IOException
+                {
+                    _searcher.search( luceneQuery, tsdc );
+                    TopDocs topdocs = tsdc.topDocs();
+                    _hits = topdocs.scoreDocs;
+
+                    return null;
+                }
+             }
+             );
+    }
+
 }

Modified: db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/LuceneSupport.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/LuceneSupport.java?rev=1589124&r1=1589123&r2=1589124&view=diff
==============================================================================
--- db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/LuceneSupport.java (original)
+++ db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/LuceneSupport.java Tue Apr 22 13:25:37 2014
@@ -22,9 +22,8 @@
 package org.apache.derby.optional.lucene;
 
 import java.io.File;
-import java.io.FileFilter;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -52,8 +51,13 @@ import org.apache.derby.iapi.sql.diction
 import org.apache.derby.iapi.sql.dictionary.OptionalTool;
 import org.apache.derby.iapi.error.PublicAPI;
 import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.reference.Property;
+import org.apache.derby.iapi.services.monitor.Monitor;
+import org.apache.derby.iapi.store.raw.data.DataFactory;
 import org.apache.derby.iapi.util.IdUtil;
 import org.apache.derby.impl.jdbc.EmbedConnection;
+import org.apache.derby.io.StorageFactory;
+import org.apache.derby.io.StorageFile;
 import org.apache.derby.shared.common.reference.SQLState;
 import org.apache.derby.optional.api.LuceneUtils;
 import org.apache.derby.vti.Restriction.ColumnQualifier;
@@ -95,7 +99,7 @@ public class LuceneSupport implements Op
     private static  final   String  UPDATE_INDEX = LUCENE_SCHEMA + "." + "updateIndex";
     private static  final   String  SEPARATOR = "__";
 
-    private static  final   String  LUCENE_DIR = "lucene";
+    static  final   String  LUCENE_DIR = "lucene";
 
     // names of columns in all query table functions
     private static  final   String  SCORE = "SCORE";
@@ -286,7 +290,9 @@ public class LuceneSupport implements Op
         // Now delete the Lucene subdirectory;
         //
         try {
-            deleteFile( new File( getLuceneDirectory( conn ) ) );
+            StorageFactory  storageFactory = getStorageFactory( conn );
+            StorageFile     luceneDir = storageFactory.newStorageFile( LUCENE_DIR );
+            if ( exists( luceneDir ) ) { deleteFile( luceneDir ); }
         }
         catch (IOException ioe) { throw wrap( ioe ); }
         catch (PrivilegedActionException pae) { throw wrap( pae ); }
@@ -461,7 +467,7 @@ public class LuceneSupport implements Op
         }
         
         int             keyCount = 0;
-        File            propertiesFile = getIndexPropertiesFile( conn, schema, table, textcol );
+        StorageFile propertiesFile = getIndexPropertiesFile( conn, schema, table, textcol );
 
         //
         // Drop the old index directory if we're recreating the index.
@@ -474,6 +480,9 @@ public class LuceneSupport implements Op
 
         Version luceneVersion = LuceneUtils.currentVersion();
 
+        // create the new directory
+        DerbyLuceneDir  derbyLuceneDir = getDerbyLuceneDir( conn, schema, table, textcol );
+
         // get the Analyzer. use the default if the user didn't specify an override
         if ( analyzerMaker == null ) { analyzerMaker = LuceneUtils.class.getName() + ".defaultAnalyzer"; }
         Analyzer    analyzer = getAnalyzer( analyzerMaker );
@@ -493,7 +502,7 @@ public class LuceneSupport implements Op
         ResultSet rs = null;
         IndexWriter iw = null;
         try {
-            iw = getIndexWriter( luceneVersion, analyzer, schema, table, textcol );
+            iw = getIndexWriter( luceneVersion, analyzer, derbyLuceneDir );
 
             // select all keys and the textcol from this column, add to lucene index
             StringBuilder query = new StringBuilder("select ");
@@ -601,16 +610,12 @@ public class LuceneSupport implements Op
 	private static void dropIndexDirectories( String schema, String table, String textcol )
         throws SQLException, IOException, PrivilegedActionException
     {
-		File indexDir = new File(getIndexLocation( getDefaultConnection(), schema, table, textcol ) );
-		File tableDir = indexDir.getParentFile();
-        File schemaDir = tableDir.getParentFile();
-		
-		if ( !isDirectory( indexDir ) )
-        {
-			throw newSQLException
-                ( SQLState.LUCENE_BAD_INDEX, indexDir.getAbsolutePath() );
-		}
+        DerbyLuceneDir  derbyLuceneDir = getDerbyLuceneDir( getDefaultConnection(), schema, table, textcol );
 
+        StorageFile indexDir = derbyLuceneDir.getDirectory();
+		StorageFile tableDir = indexDir.getParentDir();
+        StorageFile schemaDir = tableDir.getParentDir();
+		
         deleteFile( indexDir );
         if ( isEmpty( tableDir ) )
         {
@@ -1106,48 +1111,42 @@ public class LuceneSupport implements Op
      * Get the handle on the file holding the index properties.
      * </p>
      */
-	static File getIndexPropertiesFile( Connection conn, String schema, String table, String textcol )
+	static StorageFile getIndexPropertiesFile( Connection conn, String schema, String table, String textcol )
         throws SQLException, IOException, PrivilegedActionException
     {
-		File indexDir = new File( getIndexLocation( conn, schema, table, textcol ) );
-        File    propertiesFile = new File( indexDir, PROPERTIES_FILE_NAME );
-
-        return propertiesFile;
+        return getIndexPropertiesFile( getDerbyLuceneDir( conn, schema, table, textcol ) );
     }
     
-    /** Read the index properties file */
-    private static  Properties readIndexProperties( final File file )
-        throws IOException, PrivilegedActionException
+    /**
+     * <p>
+     * Get the handle on the file holding the index properties.
+     * </p>
+     */
+	static StorageFile getIndexPropertiesFile( DerbyLuceneDir dir )
+        throws SQLException, IOException, PrivilegedActionException
     {
-        return AccessController.doPrivileged
-            (
-             new PrivilegedExceptionAction<Properties>()
-             {
-                public Properties run() throws IOException
-                {
-                    return readIndexPropertiesNoPrivs( file );
-                }
-             }
-             );
-    }
+        StorageFile         propertiesFile = dir.getFile( PROPERTIES_FILE_NAME );
 
+        return propertiesFile;
+    }
+    
     /** Read the index properties file */
-    static  Properties readIndexPropertiesNoPrivs( File file )
+    static  Properties readIndexPropertiesNoPrivs( StorageFile file )
         throws IOException
     {
         if ( file == null ) { return null; }
         
         Properties  properties = new Properties();
-        FileInputStream fis = new FileInputStream( file );
+        InputStream is = file.getInputStream();
 
-        properties.load( fis );
-        fis.close();
+        properties.load( is );
+        is.close();
                         
         return properties;
     }
 
     /** Write the index properties file */
-    private static  void    writeIndexProperties( final File file, final Properties properties )
+    private static  void    writeIndexProperties( final StorageFile file, final Properties properties )
         throws IOException, PrivilegedActionException
     {
         AccessController.doPrivileged
@@ -1159,11 +1158,11 @@ public class LuceneSupport implements Op
                     if ( (file == null) || (properties == null) ) { return null; }
                     else
                     {
-                        FileOutputStream    fos = new FileOutputStream( file );
+                        OutputStream    os = file.getOutputStream();
 
-                        properties.store( fos, null );
-                        fos.flush();
-                        fos.close();
+                        properties.store( os, null );
+                        os.flush();
+                        os.close();
 
                         return null;
                     }
@@ -1349,26 +1348,6 @@ public class LuceneSupport implements Op
     	ddl.close();
     }
 	
-	private static String getDerbySystemHome() throws IOException {
-        try {
-            return AccessController
-                    .doPrivileged(new PrivilegedExceptionAction<String>() {
-                        public String run() throws IOException {
-                        	String dir = System.getProperty("derby.system.home");
-                        	if (dir == null) {
-                                return System.getProperty("user.dir");	
-                        	} else {
-                        		return dir;
-                        	}
-                        }
-                    });
-        } catch (PrivilegedActionException pae) {
-            throw (IOException) pae.getCause();
-        } catch (SecurityException se) {
-            throw (IOException) se.getCause();
-        }
-	}
-	
     /** Convert a raw string into a properly cased and escaped Derby identifier */
     private static  String  derbyIdentifier( String rawString )
         throws SQLException
@@ -1542,54 +1521,43 @@ public class LuceneSupport implements Op
     /////////////////////////////////////////////////////////////////////
 
     /** Return true if the directory is empty */
-    private static  boolean isEmpty( File dir )
+    private static  boolean isEmpty( final StorageFile dir )
         throws IOException, PrivilegedActionException
     {
-        File[]  contents = listFiles( dir, null );
+        String[]  contents = AccessController.doPrivileged
+            (
+             new PrivilegedExceptionAction<String[]>()
+             {
+                 public String[] run() throws IOException, SQLException
+                {
+                    return dir.list();
+                }
+             }
+             );
 
         if ( contents == null ) { return true; }
         else if ( contents.length == 0 ) { return true; }
         else { return false; }
     }
 
-    /**
-     * Delete a file. If it's a directory, recursively delete all directories
-     * and files underneath it first.
-     */
-    private static  boolean deleteFile( File file )
-        throws IOException, SQLException, PrivilegedActionException
-    {
-        boolean retval = true;
-
-        if ( !fileExists( file ) ) { return false; }
-        
-        if ( isDirectory( file ) )
-        {
-            for ( File child : listFiles( file, null ) ) { retval = retval && deleteFile( child ); }
-        }
-
-        return retval && clobberFile( file );
-    }
-
-    /** Return true if the file is a directory */
-    private static  boolean isDirectory( final File file )
+    /** Return true if the file exists */
+    private static  boolean exists( final StorageFile file )
         throws IOException, PrivilegedActionException
     {
         return AccessController.doPrivileged
             (
              new PrivilegedExceptionAction<Boolean>()
              {
-                public Boolean run() throws IOException
+                 public Boolean run() throws IOException, SQLException
                 {
-                    if ( file == null ) { return false; }
-                    else { return file.isDirectory(); }
+                    return file.exists();
                 }
              }
              ).booleanValue();
     }
 
     /** Really delete a file */
-    private static  boolean clobberFile( final File file )
+    private static  boolean deleteFile( final StorageFile file )
         throws IOException, SQLException, PrivilegedActionException
     {
         return AccessController.doPrivileged
@@ -1598,11 +1566,11 @@ public class LuceneSupport implements Op
              {
                  public Boolean run() throws IOException, SQLException
                 {
-                    boolean result = file.delete();
+                    boolean result = file.isDirectory() ? file.deleteAll() : file.delete();
 
                     if ( !result )
                     {
-                        throw newSQLException( SQLState.UNABLE_TO_DELETE_FILE, file.getAbsolutePath() );
+                        throw newSQLException( SQLState.UNABLE_TO_DELETE_FILE, file.getPath() );
                     }
 
                     return result;
@@ -1611,94 +1579,6 @@ public class LuceneSupport implements Op
              ).booleanValue();
     }
 
-    /** List files */
-    private static  File[]  listFiles( final File file, final FileFilter fileFilter )
-        throws IOException, PrivilegedActionException
-    {
-        return AccessController.doPrivileged
-            (
-             new PrivilegedExceptionAction<File[]>()
-             {
-                public File[] run() throws IOException
-                {
-                    if ( fileFilter == null )   { return file.listFiles(); }
-                    else { return file.listFiles( fileFilter ); }
-                }
-             }
-             );
-    }
-
-    /** Return true if the file exists */
-    private static  boolean fileExists( final File file )
-        throws IOException, PrivilegedActionException
-    {
-        return AccessController.doPrivileged
-            (
-             new PrivilegedExceptionAction<Boolean>()
-             {
-                public Boolean run() throws IOException
-                {
-                    if ( file == null ) { return false; }
-                    else { return file.exists(); }
-                }
-             }
-             ).booleanValue();
-    }
-
-	/**
-	 * Get the system property derby.system.home using the security manager.
-	 * @return Returns the value of the system property derby.system.home, or user.dir if not set.
-	 * @throws IOException
-	 */
-	/**
-	 * Provides the location of the directories used to name the individual Lucene index directories
-	 * for each column using the scheme 'schema_table_column'. The path should be inside the current
-	 * database directory.
-	 */
-	static String getIndexLocation( Connection conn, String schema, String table, String textcol )
-        throws IOException, SQLException
-    {
-		StringBuilder derbyHome = new StringBuilder();
-
-        derbyHome.append( getLuceneDirectory( conn ) );
-		
-        if ( schema != null )
-        {
-            schema = derbyIdentifier( schema );
-                
-            derbyHome.append(File.separator);
-            derbyHome.append(schema);
-
-            if ( table != null )
-            {
-                table = derbyIdentifier( table );
-                    
-                derbyHome.append(File.separator);
-                derbyHome.append(table);
-
-                if ( textcol != null )
-                {
-                    textcol = derbyIdentifier( textcol );
-                        
-                    derbyHome.append(File.separator);
-                    derbyHome.append(textcol);
-                }
-            }
-        }
-		
-        return derbyHome.toString();
-	}
-
-    /** Get the location of the Lucene subdirectory */
-    private static  String getLuceneDirectory( Connection conn )
-        throws IOException, SQLException
-    {
-        EmbedConnection embedConnection = (EmbedConnection) conn;
-        String dbname = embedConnection.getDBName();
-
-        return getDerbySystemHome() + File.separator + dbname + File.separator + LUCENE_DIR;
-    }
-    
     /** Forbid invalid character */
     private static  void    forbidCharacter( String schema, String table, String textcol, String invalidCharacter )
         throws SQLException
@@ -1730,9 +1610,7 @@ public class LuceneSupport implements Op
         (
          final Version  luceneVersion,
          final  Analyzer    analyzer,
-         final String schema,
-         final String table,
-         final String textcol
+         final DerbyLuceneDir   derbyLuceneDir
          )
         throws SQLException, IOException, PrivilegedActionException
     {
@@ -1742,11 +1620,9 @@ public class LuceneSupport implements Op
              {
                  public IndexWriter run() throws SQLException, IOException
                  {
-                     Directory dir = FSDirectory.open(new File( getIndexLocation( getDefaultConnection(), schema, table, textcol ) ) );
-
                      // allow this to be overridden in the configuration during load later.
                      IndexWriterConfig iwc = new IndexWriterConfig( luceneVersion, analyzer );
-                     IndexWriter iw = new IndexWriter( dir, iwc );
+                     IndexWriter iw = new IndexWriter( derbyLuceneDir, iwc );
 		
                      return iw;
                  }
@@ -1834,5 +1710,57 @@ public class LuceneSupport implements Op
                      
         return (Analyzer) method.invoke( null );
 	}
+
+    /////////////////////////////////////////////////////////////////////
+    //
+    //  DERBY STORE
+    //
+    /////////////////////////////////////////////////////////////////////
+
+    /**
+     * <p>
+     * Get the handle on the Lucene directory inside the database.
+     * </p>
+     */
+	static DerbyLuceneDir getDerbyLuceneDir( Connection conn, String schema, String table, String textcol )
+        throws SQLException
+    {
+        StorageFactory  storageFactory = getStorageFactory( conn );
+        String  relativePath = getRelativeIndexPath( schema, table, textcol );
+        DerbyLuceneDir  result = DerbyLuceneDir.getDirectory( storageFactory, relativePath );
+
+        return result;
+    }
+    
+    /**
+     * <p>
+     * Get the relative path of the index in the database.
+     * </p>
+     */
+    private static String getRelativeIndexPath( String schema, String table, String textcol )
+        throws SQLException
+    {
+        return
+            LUCENE_DIR + File.separator +
+            derbyIdentifier( schema ) + File.separator +
+            derbyIdentifier( table ) + File.separator +
+            derbyIdentifier( textcol ) + File.separator;
+    }
+
+    
+    /** Get the StorageFactory of the connected database */
+    static  StorageFactory  getStorageFactory( Connection conn )
+        throws SQLException
+    {
+        try {
+            Object monitor = Monitor.findService
+                ( Property.DATABASE_MODULE, ((EmbedConnection) conn).getDBName() ) ;
+            DataFactory dataFactory = (DataFactory) Monitor.findServiceModule( monitor, DataFactory.MODULE );
+
+            return dataFactory.getStorageFactory();
+        }
+        catch (StandardException se) { throw wrap( se ); }
+    }
+
 	
 }

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneCoarseAuthorizationTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneCoarseAuthorizationTest.java?rev=1589124&r1=1589123&r2=1589124&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneCoarseAuthorizationTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneCoarseAuthorizationTest.java Tue Apr 22 13:25:37 2014
@@ -318,20 +318,19 @@ public class LuceneCoarseAuthorizationTe
     //
     ///////////////////////////////////////////////////////////////////////////////////
 
-    private void    createSchema( Connection conn )  throws Exception
+    public  static void    createSchema( Connection conn )  throws Exception
     {
         createPoemsTable( conn );
     }
-    private void    dropSchema( Connection conn )   throws Exception
+    public  static void    dropSchema( Connection conn )   throws Exception
     {
-        goodStatement( conn, "drop table poems" );
+        conn.prepareStatement( "drop table poems" ).execute();
     }
-    private void    createPoemsTable( Connection conn )
+    public static void    createPoemsTable( Connection conn )
         throws Exception
     {
-        goodStatement
+        conn.prepareStatement
             (
-             conn,
              "create table poems\n" +
              "(\n" +
              "    poemID int,\n" +
@@ -341,7 +340,7 @@ public class LuceneCoarseAuthorizationTe
              "    poemText            clob,\n" +
              "    constraint poemsKey primary key( poemID, versionStamp )\n" +
              ")\n"
-             );
+             ).execute();
 
         PreparedStatement   ps = conn.prepareStatement( "insert into poems values ( ?, ?, ?, ?, ? )" );
 

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneInMemoryTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneInMemoryTest.java?rev=1589124&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneInMemoryTest.java (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneInMemoryTest.java Tue Apr 22 13:25:37 2014
@@ -0,0 +1,188 @@
+/*
+
+   Derby - Class org.apache.derbyTesting.functionTests.tests.lang.LuceneInMemoryTest
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to you 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.
+
+ */
+
+package org.apache.derbyTesting.functionTests.tests.lang;
+
+import java.sql.SQLException;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.Properties;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.apache.derbyTesting.junit.BaseJDBCTestCase;
+import org.apache.derbyTesting.junit.JDBC;
+import org.apache.derbyTesting.junit.TestConfiguration;
+import org.apache.derbyTesting.junit.SecurityManagerSetup;
+import org.apache.derbyTesting.functionTests.tests.memorydb.MemoryDbManager;
+
+/**
+ * <p>
+ * Test permissions on objects created by the optional Lucene support tool.
+ * </p>
+ */
+public class LuceneInMemoryTest extends GeneratedColumnsHelper
+{
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // CONSTANTS
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    private static  final   String      ENGLISH_ANALYZER =
+        "org.apache.derbyTesting.functionTests.tests.lang.LuceneCoarseAuthorizationTest.getEnglishAnalyzer";
+
+    private static  final   String      LOAD_TOOL = "call syscs_util.syscs_register_tool( 'luceneSupport', true )";
+    private static  final   String      UNLOAD_TOOL = "call syscs_util.syscs_register_tool( 'luceneSupport', false )";
+    private static  final   String      INDEX_POEMS =
+        "call LuceneSupport.createIndex( 'app', 'poems', 'poemText', '" + ENGLISH_ANALYZER + "' )";
+    private static  final   String      DROP_POEMS_INDEX = "call LuceneSupport.dropIndex( 'app', 'poems', 'poemText' )";
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // STATE
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Helper for dealing with memory databases. For now we use a single
+     * instance for all test classes / cases, as the tests are run single
+     * threaded.
+     */
+    private static final MemoryDbManager dbm = MemoryDbManager.getSharedInstance();
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // CONSTRUCTOR
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Create a new instance.
+     */
+
+    public LuceneInMemoryTest(String name)
+    {
+        super( name );
+    }
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // JUnit BEHAVIOR
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+
+    public static Test suite()
+    {
+		TestSuite suite = new TestSuite( "LuceneInMemoryTest" );
+        
+        Test    baseTest = TestConfiguration.embeddedSuite( LuceneInMemoryTest.class );
+		suite.addTest( SecurityManagerSetup.noSecurityManager( baseTest) );
+
+        return suite;
+    }
+
+    /**
+     * Closes all opened statements and connections that are known, and also
+     * deletes all known in-memory databases.
+     *
+     * @throws Exception if something goes wrong
+     */
+    public void tearDown()  throws Exception
+    {
+        dbm.cleanUp();
+        super.tearDown();
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // TESTS
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * <p>
+     * Test that you can create lucene indexes in an in-memory database.
+     * </p>
+     */
+    public  void    test_001_basic()
+        throws Exception
+    {
+        Connection  conn = dbm.createDatabase( "luceneMemDB" );
+
+        LuceneCoarseAuthorizationTest.createSchema( conn );
+
+        goodStatement( conn, LOAD_TOOL );
+        goodStatement( conn, INDEX_POEMS );
+
+        String  readPoemsIndex =
+            "select p.originalAuthor, i.score\n" +
+            "from poems p, table ( poems__poemText( 'star', null, 1000, 0 ) ) i\n" +
+            "where p.poemID = i.poemID and p.versionStamp = i.versionStamp\n" +
+            "order by i.score desc\n";
+        String[][]  defaultPoemResults =
+            new String[][]
+            {
+                { "Walt Whitman", "0.26756266" },
+                { "Lord Byron", "0.22933942" },
+                { "John Milton", "0.22933942" },
+            };
+
+        assertResults
+            (
+             conn,
+             readPoemsIndex,
+             defaultPoemResults,
+             false
+             );
+
+        String  listIndexes =
+            "select schemaName, tableName, columnName, analyzerMaker from table( LuceneSupport.listIndexes() ) l";
+        String[][]  defaultIndexList =
+            new String[][]
+            {
+                { "APP", "POEMS", "POEMTEXT", ENGLISH_ANALYZER },
+            };
+
+        assertResults
+            (
+             conn,
+             listIndexes,
+             defaultIndexList,
+             false
+             );
+
+        goodStatement( conn, DROP_POEMS_INDEX );
+        goodStatement( conn, UNLOAD_TOOL );
+
+        LuceneCoarseAuthorizationTest.dropSchema( conn );
+    }
+
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // MINIONS
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+
+}

Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneInMemoryTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneSuite.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneSuite.java?rev=1589124&r1=1589123&r2=1589124&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneSuite.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneSuite.java Tue Apr 22 13:25:37 2014
@@ -64,6 +64,7 @@ public class LuceneSuite extends BaseTes
             suite.addTest(LuceneSupportPermsTest.suite());
             suite.addTest(LuceneCollationTest.suite());
             suite.addTest(LuceneCoarseAuthorizationTest.suite());
+            suite.addTest(LuceneInMemoryTest.suite());
         }
 
         return suite;

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneSupportPermsTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneSupportPermsTest.java?rev=1589124&r1=1589123&r2=1589124&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneSupportPermsTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneSupportPermsTest.java Tue Apr 22 13:25:37 2014
@@ -97,6 +97,7 @@ public class LuceneSupportPermsTest exte
 	private static  final   String      DOUBLE_UNLOAD_ILLEGAL       = "42XBH";
 	private static  final   String      BAD_DIRECTORY                      = "42XBI";
 	private static  final   String      BAD_COLUMN_NAME                 = "42XBJ";
+    private static  final   String      NONEXISTENT_TABLE_FUNCTION  ="42ZB4";
 
     private static  final   String      POLICY_FILE = "org/apache/derbyTesting/functionTests/tests/lang/luceneSupport.policy";
 
@@ -509,9 +510,13 @@ public class LuceneSupportPermsTest exte
 
         assertTrue( deleteFile( poemTextIndexDirectory ) );
 
-        // can't update the index if the directory has disappeared
-        expectExecutionError( ruthConnection, BAD_DIRECTORY, UPDATE_POEMS_INDEX );
-        expectExecutionError( ruthConnection, BAD_DIRECTORY, DROP_POEMS_INDEX );
+        // but that doesn't stop you from deleting the index
+        goodStatement( ruthConnection, DROP_POEMS_INDEX );
+        expectCompilationError
+            (
+             ruthConnection, NONEXISTENT_TABLE_FUNCTION,
+             "select * from table( ruth.textTable__textCol( 'one two three four five six seven eight nine ten', null, 100, 0 ) ) t"
+             );
 
         goodStatement( dboConnection, UNLOAD_TOOL );
         dropSchema( ruthConnection );

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/CorruptRandomAccessFile.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/CorruptRandomAccessFile.java?rev=1589124&r1=1589123&r2=1589124&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/CorruptRandomAccessFile.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/CorruptRandomAccessFile.java Tue Apr 22 13:25:37 2014
@@ -57,6 +57,11 @@ public class CorruptRandomAccessFile imp
 		this.realFile = realFile;
     }
 
+    public  CorruptRandomAccessFile clone()
+    {
+        return new CorruptRandomAccessFile( realRaf.clone(), realFile );
+    }
+
 	
 	/**
      * Closes this file.