提交 d2787fcf authored 作者: Thomas Mueller's avatar Thomas Mueller

A file system implementation can now be registered. The database file system…

A file system implementation can now be registered. The database file system moved to the test section.
上级 ca083f04
......@@ -18,7 +18,8 @@ Change Log
<h1>Change Log</h1>
<h2>Next Version (unreleased)</h2>
<ul><li>-
<ul><li>A file system implementation can now be registered using FileSystem.register.
The database file system is no longer included in the jar file, it moved to the test section.
</li></ul>
<h2>Version 1.1.111 (2009-04-10)</h2>
......
......@@ -17,7 +17,12 @@ public class FileObjectInputStream extends InputStream {
private FileObject file;
private byte[] buffer = new byte[1];
FileObjectInputStream(FileObject file) {
/**
* Create a new file object input stream from the file object.
*
* @param file the file object
*/
public FileObjectInputStream(FileObject file) {
this.file = file;
}
......
......@@ -17,7 +17,13 @@ public class FileObjectOutputStream extends OutputStream {
private FileObject file;
private byte[] buffer = new byte[1];
FileObjectOutputStream(FileObject file, boolean append) throws IOException {
/**
* Create a new file object output stream from the file object.
*
* @param file the file object
* @param append true for append mode, false for truncate and overwrite
*/
public FileObjectOutputStream(FileObject file, boolean append) throws IOException {
this.file = file;
if (append) {
file.seek(file.length());
......
......@@ -10,6 +10,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.SQLException;
import java.util.ArrayList;
/**
* The file system is a storage abstraction.
......@@ -26,11 +27,6 @@ public abstract class FileSystem {
*/
public static final String PREFIX_MEMORY_LZF = "memLZF:";
/**
* The prefix used for a database based file system.
*/
public static final String PREFIX_DB = "jdbc:";
/**
* The prefix used for a read-only zip-file based file system.
*/
......@@ -52,6 +48,8 @@ public abstract class FileSystem {
*/
public static final String PREFIX_NIO_MAPPED = "nioMapped:";
public static final ArrayList SERVICES = new ArrayList();
/**
* Get the file system object.
*
......@@ -61,8 +59,6 @@ public abstract class FileSystem {
public static FileSystem getInstance(String fileName) {
if (isInMemory(fileName)) {
return FileSystemMemory.getInstance();
} else if (fileName.startsWith(PREFIX_DB)) {
return FileSystemDatabase.getInstance(fileName);
} else if (fileName.startsWith(PREFIX_ZIP)) {
return FileSystemZip.getInstance();
} else if (fileName.startsWith(PREFIX_SPLIT)) {
......@@ -72,9 +68,43 @@ public abstract class FileSystem {
} else if (fileName.startsWith(PREFIX_NIO_MAPPED)) {
return FileSystemDiskNioMapped.getInstance();
}
for (int i = 0; i < SERVICES.size(); i++) {
FileSystem fs = (FileSystem) SERVICES.get(i);
if (fs.accepts(fileName)) {
return fs;
}
}
return FileSystemDisk.getInstance();
}
/**
* Register a file system.
*
* @param service the file system
*/
public static synchronized void register(FileSystem service) {
SERVICES.add(service);
}
/**
* Unregister a file system.
*
* @param service the file system
*/
public static synchronized void unregister(FileSystem service) {
SERVICES.remove(service);
}
/**
* Check if the file system is responsible for this file name.
*
* @param fileName the file name
* @return true if it is
*/
protected boolean accepts(String fileName) {
return false;
}
private static boolean isInMemory(String fileName) {
return fileName != null && (fileName.startsWith(PREFIX_MEMORY) || fileName.startsWith(PREFIX_MEMORY_LZF));
}
......@@ -287,13 +317,4 @@ public abstract class FileSystem {
*/
public abstract InputStream openFileInputStream(String fileName) throws IOException;
/**
* Close the file system. This call normally does not have an effect, except
* if the file system is kept in a database, in which case the connection is
* closed.
*/
public void close() {
// do nothing
}
}
......@@ -4,11 +4,12 @@
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.store.fs;
package org.h2.test.unit;
import java.io.EOFException;
import java.io.IOException;
import org.h2.store.fs.FileObject;
import org.h2.util.ByteUtils;
/**
......
......@@ -4,7 +4,7 @@
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.store.fs;
package org.h2.test.unit;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
......@@ -22,6 +22,10 @@ import java.util.Properties;
import org.h2.Driver;
import org.h2.message.Message;
import org.h2.store.fs.FileObject;
import org.h2.store.fs.FileObjectInputStream;
import org.h2.store.fs.FileObjectOutputStream;
import org.h2.store.fs.FileSystem;
import org.h2.util.IOUtils;
import org.h2.util.JdbcUtils;
import org.h2.util.StringUtils;
......@@ -31,7 +35,6 @@ import org.h2.util.StringUtils;
*/
public class FileSystemDatabase extends FileSystem {
private static final HashMap INSTANCES = new HashMap();
private Connection conn;
private String url;
private HashMap preparedMap = new HashMap();
......@@ -69,38 +72,30 @@ public class FileSystemDatabase extends FileSystem {
}
}
public static synchronized FileSystem getInstance(String url) {
int idx = url.indexOf('/');
if (idx > 0) {
url = url.substring(0, idx);
}
FileSystemDatabase fs = (FileSystemDatabase) INSTANCES.get(url);
if (fs != null) {
return fs;
}
protected boolean accepts(String fileName) {
return fileName.startsWith(url);
}
public static synchronized FileSystemDatabase register(String url) throws SQLException {
Connection conn;
try {
if (url.startsWith("jdbc:h2:")) {
// avoid using DriverManager if possible
conn = Driver.load().connect(url, new Properties());
} else {
conn = JdbcUtils.getConnection(null, url, new Properties());
}
boolean log = url.toUpperCase().indexOf("TRACE_") >= 0;
fs = new FileSystemDatabase(url, conn, log);
INSTANCES.put(url, fs);
return fs;
} catch (SQLException e) {
throw Message.convertToInternal(e);
if (url.startsWith("jdbc:h2:")) {
// avoid using DriverManager if possible
conn = Driver.load().connect(url, new Properties());
} else {
conn = JdbcUtils.getConnection(null, url, new Properties());
}
boolean log = url.toUpperCase().indexOf("TRACE_") >= 0;
FileSystemDatabase fs = new FileSystemDatabase(url, conn, log);
FileSystem.register(fs);
return fs;
}
/**
* Close the underlying database.
* Close the underlying database and unregister the file system.
*/
public void close() {
public void unregister() {
JdbcUtils.closeSilently(conn);
INSTANCES.remove(url);
FileSystem.unregister(this);
}
private void commit() {
......
......@@ -44,10 +44,12 @@ public class TestFileSystem extends TestBase {
testFileSystem(FileSystem.PREFIX_SPLIT + baseDir + "/fs");
testFileSystem(baseDir + "/fs");
testFileSystem(FileSystem.PREFIX_MEMORY);
FileSystemDatabase fs = FileSystemDatabase.register("jdbc:h2:mem:fs");
// testFileSystem("jdbc:h2:mem:fs;TRACE_LEVEL_FILE=3");
testFileSystem("jdbc:h2:mem:fs");
testFileSystem(FileSystem.PREFIX_MEMORY_LZF);
testUserHome();
fs.unregister();
}
private void testDatabaseInMemFileSys() throws SQLException {
......@@ -179,12 +181,11 @@ public class TestFileSystem extends TestBase {
if (!fsBase.startsWith(FileSystem.PREFIX_MEMORY) && !fsBase.startsWith(FileSystem.PREFIX_MEMORY_LZF)) {
fs.createDirs(fsBase + "/testDir/test");
assertTrue(fs.isDirectory(fsBase + "/testDir"));
if (!fsBase.startsWith(FileSystem.PREFIX_DB)) {
if (!fsBase.startsWith("jdbc:")) {
fs.deleteRecursive(fsBase + "/testDir");
assertTrue(!fs.exists(fsBase + "/testDir"));
}
}
fs.close();
}
private void testRandomAccess(String fsBase) throws Exception {
......@@ -267,7 +268,6 @@ public class TestFileSystem extends TestBase {
}
f.close();
ra.close();
fs.close();
}
private void testTempFile(String fsBase) throws Exception {
......@@ -288,7 +288,6 @@ public class TestFileSystem extends TestBase {
assertEquals(in.read(), -1);
in.close();
out.close();
fs.close();
}
......
......@@ -585,4 +585,4 @@ versus extracts squirrel misdirected rle looking arc addressed european
soerensen favicon glass restarts flexive fish resulted vpda mvc kotek jan
consistently springfuse grep signatures wrote symbolic parents caches readers
animate scaladoc models disadvantages vladykin sergi trims requesting
handing bonita placed euros embeds reliability singular
\ No newline at end of file
handing bonita placed euros embeds reliability singular unregister
\ No newline at end of file
......@@ -377,7 +377,6 @@ public class FtpServer extends Tool implements Service {
traceError(e);
}
serverSocket = null;
fs.close();
}
public boolean isRunning(boolean traceError) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论