001: /*
002:
003: Derby - Class org.apache.derby.impl.io.BaseStorageFactory
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: package org.apache.derbyTesting.functionTests.util.corruptio;
022:
023: import org.apache.derby.io.WritableStorageFactory;
024: import org.apache.derby.io.StorageFile;
025:
026: import java.io.File;
027: import java.io.IOException;
028: import java.io.OutputStream;
029: import java.io.IOException;
030: import java.io.SyncFailedException;
031:
032: /**
033: * This class provides a proxy base implementation of the
034: * WritableStorageFactory interface to instrument I/O operations for testing
035: * purposes.
036: * Some methods in this class adds support for corrupting the I/O operation
037: * sent by the engine before invoking the real storage factory underneath.
038: * By deault all the calls will go to the real storage factory defined by the
039: * concrete class, unless corruption is enabled through CorruptibleIo instance.
040: *
041: * @see CorruptibleIo
042: * @see WritableStorageFactory
043: * @see StorageFactory
044: *
045: */
046:
047: abstract class CorruptBaseStorageFactory implements
048: WritableStorageFactory {
049:
050: protected WritableStorageFactory realStorageFactory;
051:
052: /**
053: * Most of the initialization is done in the init method.
054: */
055: CorruptBaseStorageFactory() {
056: }
057:
058: /**
059: * Classes implementing the StorageFactory interface must have a null
060: * constructor. This method is called when the database is booted up to
061: * initialize the class. It should perform all actions necessary to start
062: * the basic storage, such as creating a temporary file directory.
063: *
064: * The init method will be called once, before any other method is called,
065: * and will not be called again.
066: *
067: * @param home The name of the directory containing the database.
068: * It comes from the system.home system property.
069: * It may be null. A storage factory may decide to
070: * ignore this parameter. (For instance the classpath
071: * storage factory ignores it.)
072: *
073: * @param databaseName The name of the database (directory).
074: * All relative pathnames are relative to this
075: * directory.
076: * If null then the storage factory will only be used
077: * to deal with the directory containing the databases.
078: * @param create If true then the database is being created.
079: * @param tempDirName The name of the temporary file directory set in
080: * properties. If null then a default directory should
081: * be used. Each database should get a separate
082: * temporary file directory within this one to avoid
083: * collisions.
084: *
085: * @param uniqueName A unique name that can be used to create the
086: * temporary file directory for this database.
087: *
088: * @exception IOException on an error (unexpected).
089: */
090: public void init(String home, String databaseName,
091: String tempDirName, String uniqueName) throws IOException {
092: realStorageFactory = getRealStorageFactory();
093: realStorageFactory.init(home, databaseName, tempDirName,
094: uniqueName);
095: } // end of init
096:
097: public void shutdown() {
098: realStorageFactory.shutdown();
099: }
100:
101: /**
102: * Get the canonical name of the database.
103: *
104: * This is a name that uniquely identifies it. It is system dependent.
105: *
106: * The normal, disk based implementation uses method
107: * java.io.File.getCanonicalPath on the directory holding the
108: * database to construct the canonical name.
109: *
110: * @return the canonical name
111: *
112: * @exception IOException if an IO error occurred during the construction
113: * of the name.
114: */
115: public String getCanonicalName() throws IOException {
116: return realStorageFactory.getCanonicalName();
117: }
118:
119: /**
120: * Construct a StorageFile from a path name.
121: *
122: * @param path The path name of the file
123: *
124: * @return A corresponding StorageFile object
125: */
126: public StorageFile newStorageFile(String path) {
127: return new CorruptFile(realStorageFactory.newStorageFile(path));
128: }
129:
130: /**
131: * Construct a StorageFile from a directory and file name.
132: *
133: * @param directoryName The directory part of the path name.
134: * @param fileName The name of the file within the directory.
135: *
136: * @return A corresponding StorageFile object
137: */
138: public StorageFile newStorageFile(String directoryName,
139: String fileName) {
140: return new CorruptFile(realStorageFactory.newStorageFile(
141: directoryName, fileName));
142: }
143:
144: /**
145: * Construct a StorageFile from a directory and file name.
146: *
147: * @param directoryName The directory part of the path name.
148: * @param fileName The name of the file within the directory.
149: *
150: * @return A corresponding StorageFile object
151: */
152: public StorageFile newStorageFile(StorageFile directoryName,
153: String fileName) {
154: StorageFile realDirFile = ((CorruptFile) directoryName)
155: .getRealFileInstance();
156: return new CorruptFile(realStorageFactory.newStorageFile(
157: realDirFile, fileName));
158: }
159:
160: /**
161: * Get the pathname separator character used by the StorageFile
162: * implementation.
163: *
164: * @return the pathname separator character. (Normally '/' or '\').
165: */
166: public char getSeparator() {
167: return realStorageFactory.getSeparator();
168: }
169:
170: /**
171: * Get the abstract name of the directory that holds temporary files.
172: *
173: * @return a directory name
174: */
175: public StorageFile getTempDir() {
176: return new CorruptFile(realStorageFactory.getTempDir());
177: }
178:
179: /**
180: * This method is used to determine whether the storage is fast
181: * (RAM based) or slow (disk based).
182: *
183: * It may be used by the database engine to determine the default size of
184: * the page cache.
185: *
186: * @return <b>true</b> if the storage is fast, <b>false</b> if it is slow.
187: */
188: public boolean isFast() {
189: return realStorageFactory.isFast();
190: }
191:
192: public boolean isReadOnlyDatabase() {
193: return realStorageFactory.isReadOnlyDatabase();
194: }
195:
196: /**
197: * Determine whether the storage supports random access.
198: * If random access is not supported then it will only be accessed using
199: * InputStreams and OutputStreams (if the database is writable).
200: *
201: * @return <b>true</b> if the storage supports random access, <b>false</b> if it is writable.
202: */
203: public boolean supportsRandomAccess() {
204: return realStorageFactory.supportsRandomAccess();
205: }
206:
207: public int getStorageFactoryVersion() {
208: return realStorageFactory.getStorageFactoryVersion();
209: }
210:
211: /**
212: * Force the data of an output stream out to the underlying storage.
213: *
214: * That is, ensure that it has been made persistent. If the database is to
215: * be transient, that is, if the database does not survive a restart, then
216: * the sync method implementation need not do anything.
217: *
218: * @param stream The stream to be synchronized.
219: * @param metaData If true then this method must force both changes to the
220: * file's contents and metadata to be written to storage;
221: * if false, it need only force file content changes to be
222: * written. The implementation is allowed to ignore this
223: * parameter and always force out metadata changes.
224: *
225: * @exception IOException if an I/O error occurs.
226: * @exception SyncFailedException Thrown when the buffers cannot be flushed,
227: * or because the system cannot guarantee that all the buffers
228: * have been synchronized with physical media.
229: */
230: public void sync(OutputStream stream, boolean metaData)
231: throws IOException, SyncFailedException {
232: realStorageFactory.sync(stream, metaData);
233: }
234:
235: /**
236: * This method tests whether the "rws" and "rwd" modes are implemented.
237: *
238: * If the "rws" method is supported then the database engine will conclude
239: * that the write methods of "rws" mode StorageRandomAccessFiles are
240: * slow but the sync method is fast and optimize accordingly.
241: *
242: * @return <b>true</b> if an StIRandomAccess file opened with "rws" or "rwd" modes immediately writes data to the
243: * underlying storage, <b>false</b> if not.
244: */
245: public boolean supportsRws() {
246: return realStorageFactory.supportsRws();
247: }
248:
249: /**
250: * get the real storage factory
251: *
252: */
253: abstract WritableStorageFactory getRealStorageFactory();
254:
255: }
|