001: /*
002:
003: Derby - Class org.apache.derby.impl.io.DirFile
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to You under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derbyTesting.functionTests.util.corruptio;
023:
024: import org.apache.derby.io.StorageFile;
025: import org.apache.derby.io.StorageRandomAccessFile;
026: import java.io.File;
027: import java.io.InputStream;
028: import java.io.OutputStream;
029: import java.io.FileOutputStream;
030: import java.io.FileInputStream;
031: import java.io.IOException;
032: import java.io.FileNotFoundException;
033: import java.io.RandomAccessFile;
034: import java.net.MalformedURLException;
035: import java.net.URL;
036:
037: /**
038: * This class provides proxy implementation of the StorageFile interface. It is
039: * used by CorruptDiskStorageFactory to instrument the database engine
040: * i/o for testing.
041: *
042: * @see StorageFile
043: */
044: class CorruptFile implements StorageFile {
045:
046: private StorageFile realFile = null;
047:
048: CorruptFile(StorageFile realFile) {
049: this .realFile = realFile;
050: }
051:
052: /**
053: * Get the names of all files and sub-directories in the directory named
054: * by this path name.
055: *
056: * This method is only used in a writable database.
057: *
058: * @return An array of the names of the files and directories in this
059: * directory denoted by this abstract pathname. The returned array
060: * will have length 0 if this directory is empty. Returns null if
061: * this StorageFile is not a directory, or if an I/O error occurs.
062: * The return value is undefined if the database is read-only.
063: */
064: public String[] list() {
065: return realFile.list();
066: }
067:
068: /**
069: * Determine whether the named file is writable.
070: *
071: * @return <b>true</b> if the file exists and is writable, <b>false</b> if not.
072: */
073: public boolean canWrite() {
074: return realFile.canWrite();
075: }
076:
077: /**
078: * Tests whether the named file exists.
079: *
080: * @return <b>true</b> if the named file exists, <b>false</b> if not.
081: */
082: public boolean exists() {
083: return realFile.exists();
084: }
085:
086: /**
087: * Tests whether the named file is a directory, or not.
088: * This is only called in writable storage factories.
089: *
090: * @return <b>true</b> if named file exists and is a directory,
091: * <b>false</b> if not.
092: * The return value is undefined if the storage is read-only.
093: */
094: public boolean isDirectory() {
095: return realFile.isDirectory();
096: }
097:
098: /**
099: * Deletes the named file or empty directory.
100: * This method does not delete non-empty directories.
101: *
102: * @return <b>true</b> if the named file or directory is successfully
103: * deleted, <b>false</b> if not
104: */
105: public boolean delete() {
106: return realFile.delete();
107: }
108:
109: /**
110: * Deletes the named file and, if it is a directory, all the files and
111: * directories it contains.
112: *
113: * @return <b>true</b> if the named file or directory is successfully
114: * deleted, <b>false</b> if not
115: */
116: public boolean deleteAll() {
117: return realFile.deleteAll();
118: }
119:
120: /**
121: * Converts this StorageFile into a pathname string.
122: * The character returned by StorageFactory.getSeparator()
123: * is used to separate the directory and file names in the sequence.
124: *
125: *<p>
126: *<b>The returned path may include the database directory.
127: * Therefore it cannot be directly used to make an StorageFile
128: * equivalent to this one.</b>
129: *
130: * @return The pathname as a string.
131: *
132: * @see StorageFactory#getSeparator
133: */
134: public String getPath() {
135: return realFile.getPath();
136: }
137:
138: /**
139: * Converts this StorageFile into a canonical pathname string.
140: * The form of the canonical path is system dependent.
141: *
142: * @return The pathname as a string.
143: *
144: * @exception IOException if an I/O error occurred while finding the
145: * canonical name
146: */
147: public String getCanonicalPath() throws IOException {
148: return realFile.getCanonicalPath();
149: }
150:
151: /**
152: * @return The last segment in the path name, "" if the path name sequence
153: * is empty.
154: */
155: public String getName() {
156: return realFile.getName();
157: }
158:
159: /**
160: * If the named file does not already exist then create it as an empty
161: * normal file.
162: *
163: * The implementation must synchronize with other threads accessing the
164: * same file (in the same or a different process).
165: * If two threads both attempt to create a file with the same name
166: * at the same time then at most one should succeed.
167: *
168: * @return <b>true</b> if this thread's invocation of createNewFile
169: * successfully created the named file;
170: * <b>false</b> if not, i.e. <b>false</b> if the named file
171: * already exists or if another concurrent thread created it.
172: *
173: * @exception IOException - If the directory does not exist or some
174: * other I/O error occurred
175: */
176: public boolean createNewFile() throws IOException {
177: return realFile.createNewFile();
178: }
179:
180: /**
181: * Rename the file denoted by this name.
182: *
183: * Note that StorageFile objects are immutable. This method renames the
184: * underlying file, it does not change this StorageFile object. The
185: * StorageFile object denotes the same name as before, however the exists()
186: * method will return false after the renameTo method executes successfully.
187: *
188: * <p>
189: * It is not specified whether this method will succeed if a file
190: * already exists under the new name.
191: *
192: * @param newName the new name.
193: *
194: * @return <b>true</b> if the rename succeeded, <b>false</b> if not.
195: */
196: public boolean renameTo(StorageFile newName) {
197: return realFile.renameTo(newName);
198: }
199:
200: /**
201: * Creates the named directory.
202: *
203: * @return <b>true</b> if the directory was created; <b>false</b> if not.
204: */
205: public boolean mkdir() {
206: return realFile.mkdir();
207: }
208:
209: /**
210: * Creates the named directory, and all nonexistent parent directories.
211: *
212: * @return <b>true</b> if the directory was created, <b>false</b> if not
213: */
214: public boolean mkdirs() {
215: return realFile.mkdirs();
216: }
217:
218: /**
219: * Returns the length of the named file if it is not a directory.
220: *
221: * The return value is not specified if the file is a directory.
222: *
223: * @return The length, in bytes, of the named file if it exists and is not
224: * a directory, 0 if the file does not exist, or any value if the
225: * named file is a directory.
226: */
227: public long length() {
228: return realFile.length();
229: }
230:
231: /**
232: * Make the named file or directory read-only.
233: *
234: * This interface does not specify whether this also makes the file
235: * undeletable.
236: *
237: * @return <b>true</b> if the named file or directory was made read-only,
238: * or it already was read-only; <b>false</b> if not.
239: */
240: public boolean setReadOnly() {
241: return realFile.setReadOnly();
242: }
243:
244: /**
245: * Get the name of the parent directory if this name includes a parent.
246: *
247: * @return An StorageFile denoting the parent directory of this StorageFile,
248: * if it has a parent, null if it does not have a parent.
249: */
250: public StorageFile getParentDir() {
251: return realFile.getParentDir();
252: }
253:
254: /**
255: * Creates an output stream from a file name.
256: *
257: * @param name The file name.
258: *
259: * @return an output stream suitable for writing to the file.
260: *
261: * @exception FileNotFoundException if the file exists but is a directory
262: * rather than a regular file, does not exist but cannot be
263: * created, or cannot be opened for any other reason.
264: */
265: public OutputStream getOutputStream() throws FileNotFoundException {
266: return realFile.getOutputStream();
267: }
268:
269: /**
270: * Creates an output stream from a file name.
271: *
272: * @param append If true then data will be appended to the end of the file,
273: * if it already exists.
274: * If false and a normal file already exists with this name
275: * the file will first be truncated to zero length.
276: *
277: * @return an output stream suitable for writing to the file.
278: *
279: * @exception FileNotFoundException if the file exists but is a directory
280: * rather than a regular file, does not
281: * exist but cannot be created, or cannot
282: * be opened for any other reason.
283: */
284: public OutputStream getOutputStream(final boolean append)
285: throws FileNotFoundException {
286: return realFile.getOutputStream(append);
287: }
288:
289: /**
290: * Creates an input stream from a file name.
291: *
292: * @param name The file name.
293: *
294: * @return an input stream suitable for reading from the file.
295: *
296: * @exception FileNotFoundException if the file is not found.
297: */
298: public InputStream getInputStream() throws FileNotFoundException {
299: return realFile.getInputStream();
300: }
301:
302: /**
303: * Get an exclusive lock.
304: *
305: * This is used to ensure that two or more JVMs do not open the same
306: * database at the same time.
307: *
308: * @param lockFile The name of the lock. In a file system implementation it
309: * will be the name of a lock file.
310: *
311: * @return EXCLUSIVE_FILE_LOCK_NOT_AVAILABLE if the lock cannot be
312: * acquired because it is already held.
313: * <br> EXCLUSIVE_FILE_LOCK if the lock was successfully acquired.
314: * <br> NO_FILE_LOCK_SUPPORT if the system does not support
315: * exclusive locks.<br>
316: */
317: public synchronized int getExclusiveFileLock() {
318: return realFile.getExclusiveFileLock();
319:
320: } // end of getExclusiveFileLock
321:
322: /**
323: * Release the resource associated with an earlier acquired exclusive lock
324: *
325: * @param lockFile the name of the lock file
326: *
327: * @see #getExclusiveFileLock
328: */
329: public synchronized void releaseExclusiveFileLock() {
330: realFile.releaseExclusiveFileLock();
331:
332: } // End of releaseExclusiveFileLock
333:
334: /**
335: * Get a random access (read/write) file.
336: *
337: * @param name The name of the file.
338: * @param mode "r", "rw", "rws", or "rwd". The "rws" and "rwd" modes specify
339: * that the data is to be written to persistent store,
340: * consistent with the java.io.RandomAccessFile class
341: * ("synchronized" with the persistent storage, in the file
342: * system meaning of the word "synchronized"). However
343: * the implementation is not required to implement the "rws" or
344: * "rwd" modes. The implementation may treat "rws" and "rwd" as
345: * "rw". It is up to the user of this interface to call the
346: * StorageRandomAccessFile.sync method. If the "rws" or "rwd"
347: * modes are supported and the RandomAccessFile was opened in
348: * "rws" or "rwd" mode then the implementation of
349: * StorageRandomAccessFile.sync need not do anything.
350: *
351: * @return an object that can be used for random access to the file.
352: *
353: * @exception IllegalArgumentException if the mode argument is not equal to
354: * one of "r", "rw".
355: * @exception FileNotFoundException if the file exists but is a directory
356: * rather than a regular file, or cannot
357: * be opened or created for any other
358: * reason .
359: */
360: public StorageRandomAccessFile getRandomAccessFile(String mode)
361: throws FileNotFoundException {
362: return new CorruptRandomAccessFile(realFile
363: .getRandomAccessFile(mode), (File) realFile);
364: }
365:
366: /**
367: * retuns the real file handle that is used to delegate the calls
368: */
369: protected StorageFile getRealFileInstance() {
370: return realFile;
371: }
372:
373: /**
374: * @see org.apache.derby.io.StorageFile#getURL()
375: */
376: public URL getURL() throws MalformedURLException {
377: throw new MalformedURLException(toString());
378: }
379: }
|