--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.impl.io.DirFile\r
+\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to you under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.impl.io;\r
+\r
+import org.apache.derby.io.StorageFile;\r
+import org.apache.derby.io.StorageRandomAccessFile;\r
+\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+import java.io.File;\r
+import java.io.InputStream;\r
+import java.io.OutputStream;\r
+import java.io.FileOutputStream;\r
+import java.io.FileInputStream;\r
+import java.io.IOException;\r
+import java.io.FileNotFoundException;\r
+import java.io.RandomAccessFile;\r
+import java.net.MalformedURLException;\r
+import java.net.URL;\r
+\r
+/**\r
+ * This class provides a disk based implementation of the StorageFile interface. It is used by the\r
+ * database engine to access persistent data and transaction logs under the directory (default) subsubprotocol.\r
+ */\r
+class DirFile extends File implements StorageFile\r
+{\r
+\r
+ /**\r
+ * Construct a DirFile from a path name.\r
+ *\r
+ * @param path The path name.\r
+ */\r
+ DirFile( String path)\r
+ {\r
+ super( path);\r
+ }\r
+\r
+ /**\r
+ * Construct a DirFile from a directory name and a file name.\r
+ *\r
+ * @param directoryName The directory part of the path name.\r
+ * @param fileName The name of the file within the directory.\r
+ */\r
+ DirFile( String directoryName, String fileName)\r
+ {\r
+ super( directoryName, fileName);\r
+ }\r
+\r
+ /**\r
+ * Construct a DirFile from a directory name and a file name.\r
+ *\r
+ * @param directoryName The directory part of the path name.\r
+ * @param fileName The name of the file within the directory.\r
+ */\r
+ DirFile( DirFile directoryName, String fileName)\r
+ {\r
+ super( (File) directoryName, fileName);\r
+ }\r
+\r
+ /**\r
+ * Get the name of the parent directory if this name includes a parent.\r
+ *\r
+ * @return An StorageFile denoting the parent directory of this StorageFile, if it has a parent, null if\r
+ * it does not have a parent.\r
+ */\r
+ public StorageFile getParentDir()\r
+ {\r
+ String parent = getParent();\r
+ if( parent == null)\r
+ return null;\r
+ return new DirFile( parent);\r
+ }\r
+ \r
+ /**\r
+ * Get the name of the directory of temporary files.\r
+ *\r
+ * @return The abstract name of the temp directory;\r
+ */\r
+ static StorageFile getTempDir() throws IOException\r
+ {\r
+ File temp = File.createTempFile("derby", "tmp");\r
+ StorageFile parent = new DirFile( temp.getParent());\r
+ temp.delete();\r
+\r
+ return parent;\r
+ } // End of getTempDir\r
+\r
+ /**\r
+ * Creates an output stream from a file name.\r
+ *\r
+ * @return an output stream suitable for writing to the file.\r
+ *\r
+ * @exception FileNotFoundException if the file exists but is a directory\r
+ * rather than a regular file, does not exist but cannot be created, or\r
+ * cannot be opened for any other reason.\r
+ */\r
+ public OutputStream getOutputStream( ) throws FileNotFoundException\r
+ {\r
+ return new FileOutputStream( (File) this);\r
+ }\r
+ \r
+ /**\r
+ * Creates an output stream from a file name.\r
+ *\r
+ * @param append If true then data will be appended to the end of the file, if it already exists.\r
+ * If false and a normal file already exists with this name the file will first be truncated\r
+ * to zero length.\r
+ *\r
+ * @return an output stream suitable for writing to the file.\r
+ *\r
+ * @exception FileNotFoundException if the file exists but is a directory\r
+ * rather than a regular file, does not exist but cannot be created, or\r
+ * cannot be opened for any other reason.\r
+ */\r
+ public OutputStream getOutputStream( final boolean append) throws FileNotFoundException\r
+ {\r
+ return new FileOutputStream( getPath(), append);\r
+ }\r
+\r
+ /**\r
+ * Creates an input stream from a file name.\r
+ *\r
+ * @return an input stream suitable for reading from the file.\r
+ *\r
+ * @exception FileNotFoundException if the file is not found.\r
+ */\r
+ public InputStream getInputStream( ) throws FileNotFoundException\r
+ {\r
+ return new FileInputStream( (File) this);\r
+ }\r
+\r
+ /**\r
+ * Get an exclusive lock. This is used to ensure that two or more JVMs do not open the same database\r
+ * at the same time.\r
+ *\r
+ *\r
+ * @return EXCLUSIVE_FILE_LOCK_NOT_AVAILABLE if the lock cannot be acquired because it is already held.<br>\r
+ * EXCLUSIVE_FILE_LOCK if the lock was successfully acquired.<br>\r
+ * NO_FILE_LOCK_SUPPORT if the system does not support exclusive locks.<br>\r
+ */\r
+ public synchronized int getExclusiveFileLock()\r
+ {\r
+ if (exists())\r
+ {\r
+ delete();\r
+ }\r
+ try\r
+ {\r
+ //Just create an empty file\r
+ RandomAccessFile lockFileOpen = new RandomAccessFile( (File) this, "rw");\r
+ lockFileOpen.getFD().sync( );\r
+ lockFileOpen.close();\r
+ }catch(IOException ioe)\r
+ {\r
+ // do nothing - it may be read only medium, who knows what the\r
+ // problem is\r
+ if (SanityManager.DEBUG)\r
+ {\r
+ SanityManager.THROWASSERT(\r
+ "Unable to create Exclusive Lock File " + getPath(), ioe);\r
+ }\r
+ }\r
+ \r
+ return NO_FILE_LOCK_SUPPORT;\r
+ } // end of getExclusiveFileLock\r
+\r
+ /**\r
+ * Release the resource associated with an earlier acquired exclusive lock\r
+ *\r
+ * @see #getExclusiveFileLock\r
+ */\r
+ public synchronized void releaseExclusiveFileLock()\r
+ {\r
+ if( exists())\r
+ {\r
+ delete(); \r
+ }\r
+ } // End of releaseExclusiveFileLock\r
+\r
+ /**\r
+ * Get a random access (read/write) file.\r
+ *\r
+ * @param mode "r", "rw", "rws", or "rwd". The "rws" and "rwd" modes specify\r
+ * that the data is to be written to persistent store, consistent with the\r
+ * java.io.RandomAccessFile class ("synchronized" with the persistent\r
+ * storage, in the file system meaning of the word "synchronized"). However\r
+ * the implementation is not required to implement the "rws" or "rwd"\r
+ * modes. The implementation may treat "rws" and "rwd" as "rw". It is up to\r
+ * the user of this interface to call the StorageRandomAccessFile.sync\r
+ * method. If the "rws" or "rwd" modes are supported and the\r
+ * RandomAccessFile was opened in "rws" or "rwd" mode then the\r
+ * implementation of StorageRandomAccessFile.sync need not do anything.\r
+ *\r
+ * @return an object that can be used for random access to the file.\r
+ *\r
+ * @exception IllegalArgumentException if the mode argument is not equal to one of "r", "rw".\r
+ * @exception FileNotFoundException if the file exists but is a directory rather than a regular\r
+ * file, or cannot be opened or created for any other reason .\r
+ */\r
+ public StorageRandomAccessFile getRandomAccessFile( String mode) throws FileNotFoundException\r
+ {\r
+ // Assume that modes "rws" and "rwd" are not supported.\r
+ if( "rws".equals( mode) || "rwd".equals( mode))\r
+ mode = "rw";\r
+ return new DirRandomAccessFile( (File) this, mode);\r
+ } // end of getRandomAccessFile\r
+\r
+ /**\r
+ * Rename the file denoted by this name. Note that StorageFile objects are immutable. This method\r
+ * renames the underlying file, it does not change this StorageFile object. The StorageFile object denotes the\r
+ * same name as before, however the exists() method will return false after the renameTo method\r
+ * executes successfully.\r
+ *\r
+ *<p>It is not specified whether this method will succeed if a file already exists under the new name.\r
+ *\r
+ * @param newName the new name.\r
+ *\r
+ * @return <b>true</b> if the rename succeeded, <b>false</b> if not.\r
+ */\r
+ public boolean renameTo( StorageFile newName)\r
+ {\r
+ return super.renameTo( (File) newName);\r
+ }\r
+\r
+ /**\r
+ * Deletes the named file and, if it is a directory, all the files and directories it contains.\r
+ *\r
+ * @return <b>true</b> if the named file or directory is successfully deleted, <b>false</b> if not\r
+ */\r
+ public boolean deleteAll()\r
+ {\r
+ if( !exists())\r
+ return false;\r
+ if( isDirectory())\r
+ {\r
+ String[] childList = super.list();\r
+ String parentName = getPath();\r
+ for( int i = 0; i < childList.length; i++)\r
+ {\r
+ if( childList[i].equals( ".") || childList[i].equals( ".."))\r
+ continue;\r
+ DirFile child = new DirFile( parentName, childList[i]);\r
+ if( ! child.deleteAll())\r
+ return false;\r
+ }\r
+ }\r
+ return delete();\r
+ } // end of deleteAll\r
+\r
+ /**\r
+ * @see org.apache.derby.io.StorageFile#getURL()\r
+ */\r
+ public URL getURL() throws MalformedURLException {\r
+ \r
+ return toURL();\r
+ }\r
+}\r