提交 12d611a2 authored 作者: Thomas Mueller's avatar Thomas Mueller

Less classes are loaded when using the database in embedded mode.

上级 26c096dd
......@@ -11,6 +11,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import org.h2.util.ClassUtils;
import org.h2.util.New;
/**
......@@ -18,36 +19,7 @@ import org.h2.util.New;
*/
public abstract class FileSystem {
/**
* The prefix used for an in-memory file system.
*/
public static final String PREFIX_MEMORY = "memFS:";
/**
* The prefix used for a compressed in-memory file system.
*/
public static final String PREFIX_MEMORY_LZF = "memLZF:";
/**
* The prefix used for a read-only zip-file based file system.
*/
public static final String PREFIX_ZIP = "zip:";
/**
* The prefix used to split large files (required for a FAT32 because it
* only support files up to 2 GB).
*/
public static final String PREFIX_SPLIT = "split:";
/**
* The prefix used for the NIO FileChannel file system.
*/
public static final String PREFIX_NIO = "nio:";
/**
* The prefix used for the NIO (memory mapped) file system.
*/
public static final String PREFIX_NIO_MAPPED = "nioMapped:";
private static boolean defaultServicesRegistered;
private static final ArrayList<FileSystem> SERVICES = New.arrayList();
......@@ -58,31 +30,45 @@ public abstract class FileSystem {
* @return the file system
*/
public static FileSystem getInstance(String fileName) {
if (isInMemory(fileName)) {
return FileSystemMemory.getInstance();
} else if (fileName.startsWith(PREFIX_ZIP)) {
return FileSystemZip.getInstance();
} else if (fileName.startsWith(PREFIX_SPLIT)) {
return FileSystemSplit.getInstance();
} else if (fileName.startsWith(PREFIX_NIO)) {
return FileSystemDiskNio.getInstance();
} else if (fileName.startsWith(PREFIX_NIO_MAPPED)) {
return FileSystemDiskNioMapped.getInstance();
}
for (FileSystem fs : SERVICES) {
if (fs.accepts(fileName)) {
return fs;
if (fileName.indexOf(':') >= 0) {
if (FileSystemMemory.getInstance().accepts(fileName)) {
return FileSystemMemory.getInstance();
}
registerDefaultServices();
for (FileSystem fs : SERVICES) {
if (fs.accepts(fileName)) {
return fs;
}
}
}
return FileSystemDisk.getInstance();
}
private static synchronized void registerDefaultServices() {
if (!defaultServicesRegistered) {
defaultServicesRegistered = true;
for (String c : new String[] {
"org.h2.store.fs.FileSystemZip",
"org.h2.store.fs.FileSystemSplit",
"org.h2.store.fs.FileSystemDiskNio",
"org.h2.store.fs.FileSystemDiskNioMapped"
}) {
try {
ClassUtils.loadSystemClass(c);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
/**
* Register a file system.
*
* @param service the file system
*/
public static synchronized void register(FileSystem service) {
registerDefaultServices();
SERVICES.add(service);
}
......@@ -101,13 +87,7 @@ public abstract class FileSystem {
* @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));
}
protected abstract boolean accepts(String fileName);
/**
* Get the length of a file.
......
......@@ -441,4 +441,8 @@ public class FileSystemDisk extends FileSystem {
return f;
}
protected boolean accepts(String fileName) {
return true;
}
}
......@@ -16,10 +16,10 @@ import java.sql.SQLException;
*/
public class FileSystemDiskNio extends FileSystemDisk {
private static final FileSystemDiskNio INSTANCE = new FileSystemDiskNio();
private static final String PREFIX = "nio:";
public static FileSystemDisk getInstance() {
return INSTANCE;
static {
FileSystem.register(new FileSystemDiskNio());
}
public String createTempFile(String name, String suffix, boolean deleteOnExit, boolean inTempDir)
......@@ -82,7 +82,7 @@ public class FileSystemDiskNio extends FileSystemDisk {
* @return the prefix
*/
protected String getPrefix() {
return FileSystem.PREFIX_NIO;
return PREFIX;
}
/**
......@@ -97,4 +97,8 @@ public class FileSystemDiskNio extends FileSystemDisk {
return new FileObjectDiskChannel(fileName, mode);
}
protected boolean accepts(String fileName) {
return fileName.startsWith(getPrefix());
}
}
......@@ -14,14 +14,14 @@ import java.io.IOException;
*/
public class FileSystemDiskNioMapped extends FileSystemDiskNio {
private static final FileSystemDiskNioMapped INSTANCE = new FileSystemDiskNioMapped();
private static final String PREFIX = "nioMapped:";
public static FileSystemDisk getInstance() {
return INSTANCE;
static {
FileSystem.register(new FileSystemDiskNioMapped());
}
protected String getPrefix() {
return FileSystem.PREFIX_NIO_MAPPED;
return PREFIX;
}
protected FileObject open(String fileName, String mode) throws IOException {
......
......@@ -23,6 +23,16 @@ import org.h2.util.RandomUtils;
*/
public class FileSystemMemory extends FileSystem {
/**
* The prefix used for an in-memory file system.
*/
public static final String PREFIX = "memFS:";
/**
* The prefix used for a compressed in-memory file system.
*/
public static final String PREFIX_LZF = "memLZF:";
private static final FileSystemMemory INSTANCE = new FileSystemMemory();
private static final TreeMap<String, FileObjectMemory> MEMORY_FILES = new TreeMap<String, FileObjectMemory>();
......@@ -220,7 +230,7 @@ public class FileSystemMemory extends FileSystem {
synchronized (MEMORY_FILES) {
FileObjectMemory m = MEMORY_FILES.get(fileName);
if (m == null) {
boolean compress = fileName.startsWith(FileSystem.PREFIX_MEMORY_LZF);
boolean compress = fileName.startsWith(PREFIX_LZF);
m = new FileObjectMemory(fileName, compress);
MEMORY_FILES.put(fileName, m);
}
......@@ -228,4 +238,8 @@ public class FileSystemMemory extends FileSystem {
}
}
protected boolean accepts(String fileName) {
return fileName.startsWith(PREFIX) || fileName.startsWith(PREFIX_LZF);
}
}
......@@ -19,15 +19,17 @@ import org.h2.util.New;
/**
* A file system that may split files into multiple smaller files.
* (required for a FAT32 because it only support files up to 2 GB).
*/
public class FileSystemSplit extends FileSystem {
private static final String PREFIX = "split:";
private static final String PART_SUFFIX = ".part";
private static final FileSystemSplit INSTANCE = new FileSystemSplit();
private long defaultMaxSize = 1L << SysProperties.SPLIT_FILE_SIZE_SHIFT;
public static FileSystemSplit getInstance() {
return INSTANCE;
static {
FileSystem.register(new FileSystemSplit());
}
public boolean canWrite(String fileName) {
......@@ -63,7 +65,7 @@ public class FileSystemSplit extends FileSystem {
public String createTempFile(String prefix, String suffix, boolean deleteOnExit, boolean inTempDir)
throws IOException {
prefix = translateFileName(prefix);
return FileSystem.PREFIX_SPLIT + getFileSystem(prefix).createTempFile(prefix, suffix, deleteOnExit, inTempDir);
return PREFIX + getFileSystem(prefix).createTempFile(prefix, suffix, deleteOnExit, inTempDir);
}
public void delete(String fileName) throws SQLException {
......@@ -96,7 +98,7 @@ public class FileSystemSplit extends FileSystem {
public String getAbsolutePath(String fileName) {
fileName = translateFileName(fileName);
return FileSystem.PREFIX_SPLIT + getFileSystem(fileName).getAbsolutePath(fileName);
return PREFIX + getFileSystem(fileName).getAbsolutePath(fileName);
}
public String getFileName(String name) {
......@@ -121,7 +123,7 @@ public class FileSystemSplit extends FileSystem {
public String getParent(String fileName) {
fileName = translateFileName(fileName);
return FileSystem.PREFIX_SPLIT + getFileSystem(fileName).getParent(fileName);
return PREFIX + getFileSystem(fileName).getParent(fileName);
}
public boolean isAbsolute(String fileName) {
......@@ -162,7 +164,7 @@ public class FileSystemSplit extends FileSystem {
if (f.endsWith(PART_SUFFIX)) {
continue;
}
array[i] = f = FileSystem.PREFIX_SPLIT + f;
array[i] = f = PREFIX + f;
list.add(f);
}
if (list.size() != array.length) {
......@@ -174,7 +176,7 @@ public class FileSystemSplit extends FileSystem {
public String normalize(String fileName) throws SQLException {
fileName = translateFileName(fileName);
return FileSystem.PREFIX_SPLIT + getFileSystem(fileName).normalize(fileName);
return PREFIX + getFileSystem(fileName).normalize(fileName);
}
public InputStream openFileInputStream(String fileName) throws IOException {
......@@ -271,10 +273,10 @@ public class FileSystemSplit extends FileSystem {
}
private String translateFileName(String fileName) {
if (!fileName.startsWith(FileSystem.PREFIX_SPLIT)) {
Message.throwInternalError(fileName + " doesn't start with " + FileSystem.PREFIX_SPLIT);
if (!fileName.startsWith(PREFIX)) {
Message.throwInternalError(fileName + " doesn't start with " + PREFIX);
}
fileName = fileName.substring(FileSystem.PREFIX_SPLIT.length());
fileName = fileName.substring(PREFIX.length());
if (fileName.length() > 0 && Character.isDigit(fileName.charAt(0))) {
int idx = fileName.indexOf(':');
String size = fileName.substring(0, idx);
......@@ -306,4 +308,8 @@ public class FileSystemSplit extends FileSystem {
return FileSystem.getInstance(fileName);
}
protected boolean accepts(String fileName) {
return fileName.startsWith(PREFIX);
}
}
......@@ -24,14 +24,10 @@ import org.h2.util.New;
*/
public class FileSystemZip extends FileSystem {
private static final FileSystemZip INSTANCE = new FileSystemZip();
private static final String PREFIX = "zip:";
private FileSystemZip() {
// don't allow construction
}
public static FileSystemZip getInstance() {
return INSTANCE;
static {
FileSystem.register(new FileSystemZip());
}
public boolean canWrite(String fileName) {
......@@ -221,8 +217,8 @@ public class FileSystemZip extends FileSystem {
}
private String translateFileName(String fileName) {
if (fileName.startsWith(FileSystem.PREFIX_ZIP)) {
fileName = fileName.substring(FileSystem.PREFIX_ZIP.length());
if (fileName.startsWith(PREFIX)) {
fileName = fileName.substring(PREFIX.length());
}
int idx = fileName.indexOf('!');
if (idx >= 0) {
......@@ -249,4 +245,9 @@ public class FileSystemZip extends FileSystem {
fileName = translateFileName(fileName);
return new ZipFile(fileName);
}
protected boolean accepts(String fileName) {
return fileName.startsWith(PREFIX);
}
}
......@@ -31,11 +31,9 @@ import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import org.h2.util.Resources;
import org.h2.util.Tool;
import java.io.IOException;
//## AWT end ##
import java.sql.SQLException;
import org.h2.constant.SysProperties;
import org.h2.server.ShutdownHandler;
import org.h2.util.StartBrowser;
......@@ -55,7 +53,6 @@ ShutdownHandler {
//## AWT begin ##
Frame frame;
private Font font;
private Image icon16, icon22, icon24;
private Button startBrowser;
//## AWT end ##
private Server web, tcp, pg;
......@@ -150,6 +147,27 @@ ShutdownHandler {
startException = e;
}
}
//## AWT begin ##
if (toolStart && webRunning && !GraphicsEnvironment.isHeadless()) {
loadFont();
try {
if (!createTrayIcon()) {
showWindow(true);
}
} catch (Exception e) {
e.printStackTrace();
}
}
//## AWT end ##
// start browser in any case (even if the server is already running)
// because some people don't look at the output,
// but are wondering why nothing happens
if (browserStart) {
StartBrowser.openURL(web.getURL());
}
if (tcpStart) {
try {
tcp = Server.createTcpServer(args);
......@@ -172,32 +190,6 @@ ShutdownHandler {
}
}
}
//## AWT begin ##
if (toolStart && webRunning && !GraphicsEnvironment.isHeadless()) {
if (isWindows) {
font = new Font("Dialog", Font.PLAIN, 11);
} else {
font = new Font("Dialog", Font.PLAIN, 12);
}
try {
icon16 = loadImage("/org/h2/res/h2.png");
icon22 = loadImage("/org/h2/res/h2-22.png");
icon24 = loadImage("/org/h2/res/h2-24.png");
if (!createTrayIcon()) {
showWindow(true);
}
} catch (Exception e) {
e.printStackTrace();
}
}
//## AWT end ##
// start browser anyway (even if the server is already running)
// because some people don't look at the output,
// but are wondering why nothing happens
if (browserStart) {
StartBrowser.openURL(web.getURL());
}
if (startException != null) {
throw startException;
}
......@@ -212,12 +204,17 @@ ShutdownHandler {
}
}
private Image loadImage(String name) throws IOException {
byte[] imageData = Resources.get(name);
if (imageData == null) {
private Image loadImage(String name) {
try {
byte[] imageData = Resources.get(name);
if (imageData == null) {
return null;
}
return Toolkit.getDefaultToolkit().createImage(imageData);
} catch (IOException e) {
e.printStackTrace();
return null;
}
return Toolkit.getDefaultToolkit().createImage(imageData);
}
/**
......@@ -253,17 +250,23 @@ ShutdownHandler {
}
//## AWT begin ##
private void loadFont() {
if (isWindows) {
font = new Font("Dialog", Font.PLAIN, 11);
} else {
font = new Font("Dialog", Font.PLAIN, 12);
}
}
private boolean createTrayIcon() {
try {
// SystemTray.isSupported();
Boolean supported = (Boolean) Class.forName("java.awt.SystemTray").
getMethod("isSupported").
invoke(null);
if (!supported.booleanValue()) {
if (!supported) {
return false;
}
PopupMenu menuConsole = new PopupMenu();
MenuItem itemConsole = new MenuItem("H2 Console");
itemConsole.setActionCommand("console");
......@@ -290,14 +293,15 @@ ShutdownHandler {
Dimension d = (Dimension) Class.forName("java.awt.SystemTray").
getMethod("getTrayIconSize").
invoke(tray);
Image icon;
String iconFile;
if (d.width >= 24 && d.height >= 24) {
icon = icon24;
iconFile = "/org/h2/res/h2-24.png";
} else if (d.width >= 22 && d.height >= 22) {
icon = icon22;
iconFile = "/org/h2/res/h2-22.png";
} else {
icon = icon16;
iconFile = "/org/h2/res/h2.png";
}
Image icon = loadImage(iconFile);
// TrayIcon icon = new TrayIcon(image, "H2 Database Engine", menuConsole);
Object trayIcon = Class.forName("java.awt.TrayIcon").
getConstructor(Image.class, String.class, PopupMenu.class).
......@@ -330,8 +334,9 @@ ShutdownHandler {
}
}
});
if (icon16 != null) {
frame.setIconImage(icon16);
Image image = loadImage("/org/h2/res/h2.png");
if (image != null) {
frame.setIconImage(image);
}
frame.setResizable(false);
frame.setBackground(SystemColor.control);
......
......@@ -85,10 +85,11 @@ public class ClassUtils {
} catch (Exception e2) {
throw Message.getSQLException(ErrorCode.CLASS_NOT_FOUND_1, e, className);
}
} catch (UnsupportedClassVersionError e) {
throw Message.getSQLException(ErrorCode.GENERAL_ERROR_1, e, className);
} catch (NoClassDefFoundError e) {
throw Message.getSQLException(ErrorCode.CLASS_NOT_FOUND_1, e, className);
} catch (Error e) {
// UnsupportedClassVersionError
throw Message.getSQLException(ErrorCode.GENERAL_ERROR_1, e, className);
}
}
......
......@@ -114,7 +114,7 @@ public class FileUtils {
* @param name the directory and file name
* @return just the file name
*/
public static String getFileName(String name) throws SQLException {
public static String getFileName(String name) {
return FileSystem.getInstance(name).getFileName(name);
}
......
......@@ -89,7 +89,7 @@ public class MathUtils {
public static long scaleUp50Percent(long start, long min, long blockSize, long maxIncrease) {
long len;
if (min > maxIncrease * 2) {
len = MathUtils.roundUpLong(min, maxIncrease);
len = roundUpLong(min, maxIncrease);
} else {
len = start;
while (len < min) {
......
......@@ -351,7 +351,7 @@ public class ObjectArray<T> implements Iterable<T> {
}
public void remove() {
throw new UnsupportedOperationException();
throw new RuntimeException();
}
}
......
......@@ -53,10 +53,13 @@ public class Profiler implements Runnable {
*/
public void stopCollecting() {
stop = true;
try {
thread.join();
} catch (InterruptedException e) {
// ignore
if (thread != null) {
try {
thread.join();
} catch (InterruptedException e) {
// ignore
}
thread = null;
}
}
......@@ -186,4 +189,12 @@ public class Profiler implements Runnable {
this.interval = interval;
}
public int getDepth() {
return depth;
}
public void setDepth(int depth) {
this.depth = depth;
}
}
......@@ -10,7 +10,6 @@ import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Random;
......@@ -59,7 +58,8 @@ public class RandomUtils {
cachedSecureRandom.setSeed(seed);
seeded = true;
}
} catch (NoSuchAlgorithmException e) {
} catch (Exception e) {
// NoSuchAlgorithmException
warn("SecureRandom", e);
}
}
......@@ -89,7 +89,8 @@ public class RandomUtils {
generateAlternativeSeed();
}
} catch (NoSuchAlgorithmException e) {
} catch (Exception e) {
// NoSuchAlgorithmException
warn("SecureRandom", e);
cachedSecureRandom = new SecureRandom();
}
......@@ -177,6 +178,15 @@ public class RandomUtils {
}
}
/**
* Get a number of pseudo random bytes.
*
* @param bytes the target array
*/
public static void nextBytes(byte[] bytes) {
RANDOM.nextBytes(bytes);
}
/**
* Get a number of cryptographically secure pseudo random bytes.
*
......
......@@ -44,7 +44,6 @@ public class StartBrowser {
}
return;
}
try {
Class< ? > desktopClass = Class.forName("java.awt.Desktop");
// Desktop.isDesktopSupported()
......@@ -52,7 +51,7 @@ public class StartBrowser {
getMethod("isDesktopSupported").
invoke(null, new Object[0]);
URI uri = new URI(url);
if (supported.booleanValue()) {
if (supported) {
// Desktop.getDesktop();
Object desktop = desktopClass.getMethod("getDesktop").
invoke(null, new Object[0]);
......@@ -64,7 +63,6 @@ public class StartBrowser {
} catch (Exception e) {
// ignore
}
if (osName.indexOf("windows") >= 0) {
rt.exec(new String[] { "rundll32", "url.dll,FileProtocolHandler", url });
} else if (osName.indexOf("mac") >= 0) {
......
......@@ -6,16 +6,13 @@
*/
package org.h2.util;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties;
import org.h2.engine.Constants;
......@@ -279,7 +276,8 @@ public class StringUtils {
public static byte[] utf8Encode(String s) {
try {
return s.getBytes(Constants.UTF8);
} catch (UnsupportedEncodingException e) {
} catch (Exception e) {
// UnsupportedEncodingException
throw Message.convertToInternal(e);
}
}
......@@ -293,7 +291,8 @@ public class StringUtils {
public static String utf8Decode(byte[] utf8) {
try {
return new String(utf8, Constants.UTF8);
} catch (UnsupportedEncodingException e) {
} catch (Exception e) {
// UnsupportedEncodingException
throw Message.convertToInternal(e);
}
}
......@@ -310,7 +309,8 @@ public class StringUtils {
private static String utf8Decode(byte[] bytes, int offset, int length) {
try {
return new String(bytes, offset, length, Constants.UTF8);
} catch (UnsupportedEncodingException e) {
} catch (Exception e) {
// UnsupportedEncodingException
throw Message.convertToInternal(e);
}
}
......@@ -389,7 +389,8 @@ public class StringUtils {
//## Java 1.4 begin ##
try {
return URLEncoder.encode(s, "UTF-8");
} catch (UnsupportedEncodingException e) {
} catch (Exception e) {
// UnsupportedEncodingException
throw Message.convertToInternal(e);
}
//## Java 1.4 end ##
......@@ -529,7 +530,8 @@ public class StringUtils {
synchronized (dateFormat) {
return dateFormat.parse(date);
}
} catch (ParseException e) {
} catch (Exception e) {
// ParseException
throw Message.getSQLException(ErrorCode.PARSE_ERROR_1, e, date);
}
}
......
......@@ -14,7 +14,7 @@ import java.util.ArrayList;
import org.h2.bnf.Bnf;
import org.h2.bnf.RuleHead;
import org.h2.constant.SysProperties;
import org.h2.store.fs.FileSystem;
import org.h2.store.fs.FileSystemMemory;
import org.h2.test.TestAll;
import org.h2.test.TestBase;
import org.h2.tools.DeleteDbFiles;
......@@ -90,7 +90,7 @@ public class TestRandomSQL extends TestBase {
private void deleteDb() throws SQLException {
String name = getDatabaseName();
if (name.startsWith(FileSystem.PREFIX_MEMORY)) {
if (name.startsWith(FileSystemMemory.PREFIX)) {
DeleteDbFiles.execute("memFS:/", name, true);
} else {
DeleteDbFiles.execute(baseDir, name, true);
......
......@@ -20,6 +20,7 @@ import java.util.Random;
import org.h2.store.fs.FileObject;
import org.h2.store.fs.FileSystem;
import org.h2.store.fs.FileSystemMemory;
import org.h2.test.TestBase;
/**
......@@ -40,14 +41,14 @@ public class TestFileSystem extends TestBase {
testDatabaseInMemFileSys();
testDatabaseInJar();
// set default part size to 1 << 10
FileSystem.getInstance(FileSystem.PREFIX_SPLIT + "10:" + baseDir + "/fs");
testFileSystem(FileSystem.PREFIX_SPLIT + baseDir + "/fs");
FileSystem.getInstance("split:10:" + baseDir + "/fs");
testFileSystem("split:" + baseDir + "/fs");
testFileSystem(baseDir + "/fs");
testFileSystem(FileSystem.PREFIX_MEMORY);
testFileSystem(FileSystemMemory.PREFIX);
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);
testFileSystem(FileSystemMemory.PREFIX_LZF);
testUserHome();
fs.unregister();
}
......@@ -175,7 +176,7 @@ public class TestFileSystem extends TestBase {
assertTrue(fs.tryDelete(fsBase + "/test2"));
fs.delete(fsBase + "/test");
if (!fsBase.startsWith(FileSystem.PREFIX_MEMORY) && !fsBase.startsWith(FileSystem.PREFIX_MEMORY_LZF)) {
if (!fsBase.startsWith(FileSystemMemory.PREFIX) && !fsBase.startsWith(FileSystemMemory.PREFIX_LZF)) {
fs.createDirs(fsBase + "/testDir/test");
assertTrue(fs.isDirectory(fsBase + "/testDir"));
if (!fsBase.startsWith("jdbc:")) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论