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:
022: package org.apache.derby.impl.io;
023:
024: import org.apache.derby.iapi.store.raw.data.DataFactory;
025:
026: import org.apache.derby.io.StorageFactory;
027: import org.apache.derby.io.StorageFile;
028:
029: import java.io.File;
030: import java.io.IOException;
031:
032: /**
033: * This class provides a base for implementations of the StorageFactory interface. It is used by the
034: * database engine to access persistent data and transaction logs under the directory (default) subsubprotocol.
035: */
036:
037: abstract class BaseStorageFactory implements StorageFactory {
038:
039: String home;
040: protected StorageFile tempDir;
041: protected String tempDirPath;
042: protected String dataDirectory;
043: protected String separatedDataDirectory; // dataDirectory + separator
044: protected String uniqueName;
045: protected String canonicalName;
046: private static final String TEMP_DIR_PREFIX = "derbytmp_";
047:
048: /**
049: * Most of the initialization is done in the init method.
050: */
051: BaseStorageFactory() {
052: }
053:
054: /**
055: * Classes implementing the StorageFactory interface must have a null
056: * constructor. This method is called when the database is booted up to
057: * initialize the class. It should perform all actions necessary to start the
058: * basic storage, such as creating a temporary file directory.
059: *
060: * The init method will be called once, before any other method is called, and will not
061: * be called again.
062: *
063: * @param home The name of the directory containing the database. It comes from the system.home system property.
064: * It may be null. A storage factory may decide to ignore this parameter. (For instance the classpath
065: * storage factory ignores it.
066: * @param databaseName The name of the database (directory). All relative pathnames are relative to this directory.
067: * If null then the storage factory will only be used to deal with the directory containing
068: * the databases.
069: * @param tempDirName The name of the temporary file directory set in properties. If null then a default
070: * directory should be used. Each database should get a separate temporary file
071: * directory within this one to avoid collisions.
072: * @param uniqueName A unique name that can be used to create the temporary file directory for this database.
073: *
074: * @exception IOException on an error (unexpected).
075: */
076: public void init(String home, String databaseName,
077: String tempDirName, String uniqueName) throws IOException {
078: if (databaseName != null) {
079: dataDirectory = databaseName;
080: separatedDataDirectory = databaseName + getSeparator();
081: }
082: this .home = home;
083: this .uniqueName = uniqueName;
084: tempDirPath = tempDirName;
085: doInit();
086: } // end of init
087:
088: abstract void doInit() throws IOException;
089:
090: public void shutdown() {
091: }
092:
093: /**
094: * Get the canonical name of the database. This is a name that uniquely identifies it. It is system dependent.
095: *
096: * The normal, disk based implementation uses method java.io.File.getCanonicalPath on the directory holding the
097: * database to construct the canonical name.
098: *
099: * @return the canonical name
100: *
101: * @exception IOException if an IO error occurred during the construction of the name.
102: */
103: public String getCanonicalName() throws IOException {
104: return canonicalName;
105: }
106:
107: /**
108: * Construct a StorageFile from a path name.
109: *
110: * @param path The path name of the file
111: *
112: * @return A corresponding StorageFile object
113: */
114: public StorageFile newStorageFile(String path) {
115: if (path != null && tempDirPath != null
116: && path.startsWith(tempDirPath))
117: return new DirFile(path);
118: return newPersistentFile(path);
119: }
120:
121: /**
122: * Construct a StorageFile from a directory and file name.
123: *
124: * @param directoryName The directory part of the path name.
125: * @param fileName The name of the file within the directory.
126: *
127: * @return A corresponding StorageFile object
128: */
129: public StorageFile newStorageFile(String directoryName,
130: String fileName) {
131: if (directoryName == null)
132: return newStorageFile(fileName);
133: else if (tempDirPath != null
134: && directoryName.startsWith(tempDirPath))
135: return new DirFile(directoryName, fileName);
136: else
137: return newPersistentFile(directoryName, fileName);
138: }
139:
140: /**
141: * Construct a StorageFile from a directory and file name.
142: *
143: * @param directoryName The directory part of the path name.
144: * @param fileName The name of the file within the directory.
145: *
146: * @return A corresponding StorageFile object
147: */
148: public StorageFile newStorageFile(StorageFile directoryName,
149: String fileName) {
150: if (directoryName == null)
151: return newStorageFile(fileName);
152: if (fileName == null)
153: return directoryName;
154: else if (tempDirPath != null
155: && directoryName.getPath().startsWith(tempDirPath))
156: return new DirFile((DirFile) directoryName, fileName);
157: return newPersistentFile(directoryName, fileName);
158: }
159:
160: /**
161: * Construct a persistent StorageFile from a path name.
162: *
163: * @param path The path name of the file. Guaranteed not to be in the temporary file directory. If null
164: * then the database directory should be returned.
165: *
166: * @return A corresponding StorageFile object
167: */
168: abstract StorageFile newPersistentFile(String path);
169:
170: /**
171: * Construct a persistent StorageFile from a directory and path name.
172: *
173: * @param directoryName The path name of the directory. Guaranteed not to be in the temporary file directory.
174: * Guaranteed not to be null
175: * @param fileName The name of the file within the directory. Guaranteed not to be null.
176: *
177: * @return A corresponding StorageFile object
178: */
179: abstract StorageFile newPersistentFile(String directoryName,
180: String fileName);
181:
182: /**
183: * Construct a persistent StorageFile from a directory and path name.
184: *
185: * @param directoryName The path name of the directory. Guaranteed not to be to be null. Guaranteed to be
186: * created by a call to one of the newPersistentFile methods.
187: * @param fileName The name of the file within the directory. Guaranteed not to be null.
188: *
189: * @return A corresponding StorageFile object
190: */
191: abstract StorageFile newPersistentFile(StorageFile directoryName,
192: String fileName);
193:
194: /**
195: * Get the pathname separator character used by the StorageFile implementation.
196: *
197: * @return the pathname separator character. (Normally '/' or '\').
198: */
199: public char getSeparator() {
200: // Temp files are always java.io.File's and use its separator.
201: return File.separatorChar;
202: }
203:
204: /**
205: * Get the abstract name of the directory that holds temporary files.
206: *
207: * @return a directory name
208: */
209: public StorageFile getTempDir() {
210: return tempDir;
211: }
212:
213: /**
214: * This method is used to determine whether the storage is fast (RAM based) or slow (disk based).
215: * It may be used by the database engine to determine the default size of the page cache.
216: *
217: * @return <b>true</b> if the storage is fast, <b>false</b> if it is slow.
218: */
219: public boolean isFast() {
220: return false;
221: }
222:
223: public boolean isReadOnlyDatabase() {
224: return true;
225: }
226:
227: /**
228: * Determine whether the storage supports random access. If random access is not supported then
229: * it will only be accessed using InputStreams and OutputStreams (if the database is writable).
230: *
231: * @return <b>true</b> if the storage supports random access, <b>false</b> if it is writable.
232: */
233: public boolean supportsRandomAccess() {
234: return false;
235: }
236:
237: void createTempDir() throws java.io.IOException {
238: if (uniqueName == null)
239: return;
240:
241: if (tempDirPath != null)
242: tempDir = new DirFile(tempDirPath, TEMP_DIR_PREFIX
243: .concat(uniqueName));
244: else if (isReadOnlyDatabase())
245: tempDir = new DirFile(readOnlyTempRoot(), TEMP_DIR_PREFIX
246: .concat(uniqueName));
247: else
248: tempDir = new DirFile(canonicalName,
249: DataFactory.TEMP_SEGMENT_NAME);
250:
251: // blow away any temporary directory
252: tempDir.deleteAll();
253:
254: tempDir.mkdirs();
255: tempDirPath = tempDir.getPath();
256: } // end of createTempDir
257:
258: private String readOnlyTempRoot() throws java.io.IOException {
259: // return the system temp dir by creating a temp file
260: // and finding its parent.
261: File temp = File.createTempFile("derby", "tmp");
262: String parent = temp.getParent();
263: temp.delete();
264:
265: return parent;
266: }
267:
268: public int getStorageFactoryVersion() {
269: return StorageFactory.VERSION_NUMBER;
270: }
271: }
|