📄 connectioninfo.java
字号:
/*
* Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.engine;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Properties;
import org.h2.api.DatabaseEventListener;
import org.h2.command.dml.SetTypes;
import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties;
import org.h2.message.Message;
import org.h2.security.SHA256;
import org.h2.util.FileUtils;
import org.h2.util.MathUtils;
import org.h2.util.ObjectArray;
import org.h2.util.StringUtils;
/**
* Encapsulates the connection settings, including user name and password.
*/
public class ConnectionInfo {
private static final HashSet KNOWN_SETTINGS = new HashSet();
private final Properties prop = new Properties();
private String originalURL;
private String url;
private String user;
private byte[] filePasswordHash;
private byte[] userPasswordHash;
private String name;
private boolean remote;
private boolean ssl;
private boolean persistent;
private boolean unnamed;
static {
ObjectArray list = SetTypes.getSettings();
for (int i = 0; i < list.size(); i++) {
KNOWN_SETTINGS.add(list.get(i));
}
// TODO document these settings
String[] connectionTime = new String[] { "ACCESS_MODE_LOG", "ACCESS_MODE_DATA", "AUTOCOMMIT", "CIPHER",
"CREATE", "CACHE_TYPE", "DB_CLOSE_ON_EXIT", "FILE_LOCK", "IGNORE_UNKNOWN_SETTINGS", "IFEXISTS",
"PASSWORD", "RECOVER", "STORAGE", "USER", "DATABASE_EVENT_LISTENER_OBJECT" };
for (int i = 0; i < connectionTime.length; i++) {
String key = connectionTime[i];
if (SysProperties.CHECK && KNOWN_SETTINGS.contains(key)) {
throw Message.getInternalError(key);
}
KNOWN_SETTINGS.add(key);
}
}
public ConnectionInfo(String name) {
this.name = name;
parseName();
}
public ConnectionInfo(String u, Properties info) throws SQLException {
this.originalURL = u;
if (!u.startsWith(Constants.START_URL)) {
throw Message.getInvalidValueException(u, "url");
}
this.url = u;
readProperties(info);
readSettingsFromURL();
setUserName(removeProperty("USER", ""));
readPasswords();
name = url.substring(Constants.START_URL.length());
parseName();
}
private void parseName() {
if (".".equals(name)) {
name = "mem:";
}
if (name.startsWith("tcp:")) {
remote = true;
name = name.substring("tcp:".length());
} else if (name.startsWith("ssl:")) {
remote = true;
ssl = true;
name = name.substring("ssl:".length());
} else if (name.startsWith("mem:")) {
persistent = false;
if ("mem:".equals(name)) {
unnamed = true;
}
} else if (name.startsWith("file:")) {
name = name.substring("file:".length());
persistent = true;
} else {
persistent = true;
}
}
public String getDatabaseName() {
if (remote) {
if (ssl) {
return "ssl:" + name;
} else {
return "tcp:" + name;
}
} else if (persistent) {
return "file:" + name;
}
return name;
}
public void setBaseDir(String dir) {
if (persistent) {
if (!name.startsWith("~")) {
name = dir + SysProperties.FILE_SEPARATOR + name;
}
}
}
public boolean isRemote() {
return remote;
}
public boolean isPersistent() {
return persistent;
}
public boolean isUnnamed() {
return unnamed;
}
private void readProperties(Properties info) throws SQLException {
Object[] list = new Object[info.size()];
info.keySet().toArray(list);
for (int i = 0; i < list.length; i++) {
String key = StringUtils.toUpperEnglish(list[i].toString());
if (prop.containsKey(key)) {
throw Message.getSQLException(ErrorCode.DUPLICATE_PROPERTY_1, key);
}
if (KNOWN_SETTINGS.contains(key)) {
prop.put(key, info.get(list[i]));
}
}
}
private void readSettingsFromURL() throws SQLException {
int idx = url.indexOf(';');
if (idx >= 0) {
String settings = url.substring(idx + 1);
url = url.substring(0, idx);
String[] list = StringUtils.arraySplit(settings, ';', false);
for (int i = 0; i < list.length; i++) {
String setting = list[i];
int equal = setting.indexOf('=');
if (equal < 0) {
throw getFormatException();
}
String value = setting.substring(equal + 1);
String key = setting.substring(0, equal);
key = StringUtils.toUpperEnglish(key);
if (!KNOWN_SETTINGS.contains(key)) {
throw Message.getSQLException(ErrorCode.UNSUPPORTED_SETTING_1, key);
}
String old = prop.getProperty(key);
if (old != null && !old.equals(value)) {
throw Message.getSQLException(ErrorCode.DUPLICATE_PROPERTY_1, key);
}
prop.setProperty(key, value);
}
}
}
DatabaseEventListener removeDatabaseEventListenerObject() throws SQLException {
Object p = prop.remove("DATABASE_EVENT_LISTENER_OBJECT");
if (p == null) {
return null;
}
if (p instanceof DatabaseEventListener) {
return (DatabaseEventListener) p;
}
throw Message.getSQLException(ErrorCode.DATA_CONVERSION_ERROR_1, p.getClass().getName());
}
private char[] removePassword() {
Object p = prop.remove("PASSWORD");
if (p == null) {
return new char[0];
} else if (p instanceof char[]) {
return (char[]) p;
} else {
return p.toString().toCharArray();
}
}
public void readPasswords() throws SQLException {
char[] password = removePassword();
SHA256 sha = new SHA256();
if (getProperty("CIPHER", null) != null) {
// split password into (filePassword+' '+userPassword)
int space = -1;
for (int i = 0; i < password.length; i++) {
if (password[i] == ' ') {
space = i;
break;
}
}
if (space < 0) {
throw Message.getSQLException(ErrorCode.WRONG_PASSWORD_FORMAT);
}
char[] np = new char[password.length - space - 1];
char[] filePassword = new char[space];
System.arraycopy(password, space + 1, np, 0, np.length);
System.arraycopy(password, 0, filePassword, 0, space);
Arrays.fill(password, (char) 0);
password = np;
filePasswordHash = sha.getKeyPasswordHash("file", filePassword);
}
userPasswordHash = sha.getKeyPasswordHash(user, password);
}
public boolean removeProperty(String key, boolean defaultValue) {
String x = removeProperty(key, null);
return x == null ? defaultValue : Boolean.valueOf(x).booleanValue();
}
public String removeProperty(String key, String defaultValue) {
if (SysProperties.CHECK && !KNOWN_SETTINGS.contains(key)) {
throw Message.getInternalError(key);
}
Object x = prop.remove(key);
return x == null ? defaultValue : x.toString();
}
public String getName() throws SQLException {
if (persistent) {
String n = FileUtils.normalize(name + Constants.SUFFIX_DATA_FILE);
n = n.substring(0, n.length() - Constants.SUFFIX_DATA_FILE.length());
return FileUtils.normalize(n);
}
return name;
}
public byte[] getFilePasswordHash() {
return filePasswordHash;
}
public String getUserName() {
return user;
}
public byte[] getUserPasswordHash() {
return userPasswordHash;
}
public String[] getKeys() {
String[] keys = new String[prop.size()];
prop.keySet().toArray(keys);
return keys;
}
public String getProperty(String key) {
Object value = prop.get(key);
if (value == null || !(value instanceof String)) {
return null;
}
return value.toString();
}
public String getProperty(String key, String defaultValue) {
if (SysProperties.CHECK && !KNOWN_SETTINGS.contains(key)) {
throw Message.getInternalError(key);
}
String s = getProperty(key);
return s == null ? defaultValue : s;
}
public String getProperty(int setting, String defaultValue) {
String key = SetTypes.getTypeName(setting);
String s = getProperty(key);
return s == null ? defaultValue : s;
}
public int getIntProperty(int setting, int defaultValue) {
String key = SetTypes.getTypeName(setting);
String s = getProperty(key, null);
try {
return s == null ? defaultValue : MathUtils.decodeInt(s);
} catch (NumberFormatException e) {
return defaultValue;
}
}
public boolean isSSL() {
return ssl;
}
public void setUserName(String name) {
// TODO document: the user name is case-insensitive (stored uppercase)
// and english conversion is used
this.user = StringUtils.toUpperEnglish(name);
}
public void setUserPasswordHash(byte[] bs) {
this.userPasswordHash = bs;
}
public void setFilePasswordHash(byte[] bs) {
this.filePasswordHash = bs;
}
public void setProperty(String key, String value) {
// value is null if the value is an object
if (value != null) {
prop.setProperty(key, value);
}
}
public String getURL() {
return url;
}
public String getOriginalURL() {
return originalURL;
}
public void setOriginalURL(String url) {
originalURL = url;
}
boolean getTextStorage() throws SQLException {
String storage = removeProperty("STORAGE", "BINARY");
if ("BINARY".equalsIgnoreCase(storage)) {
return false;
} else if ("TEXT".equalsIgnoreCase(storage)) {
return true;
} else {
throw Message.getInvalidValueException(storage, "storage");
}
}
public SQLException getFormatException() {
String format = Constants.URL_FORMAT;
return Message.getSQLException(ErrorCode.URL_FORMAT_ERROR_2, new String[] { format, url });
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -