提交 858f95f3 authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 5a86eaff
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.server;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;
import org.h2.util.MathUtils;
import org.h2.util.NetUtils;
/**
* @author Thomas
*/
public class OdbcServer implements Service {
public static final int DEFAULT_PORT = 9083; // also in the docs
private int port = OdbcServer.DEFAULT_PORT;
private boolean stop;
private boolean log;
private ServerSocket serverSocket;
private HashSet running = new HashSet();
private String baseDir;
private String url;
private boolean allowOthers;
private boolean ifExists;
boolean getLog() {
return log;
}
void log(String s) {
if (log) {
System.out.println(s);
}
}
synchronized void remove(OdbcServerThread t) {
running.remove(t);
}
void logError(Exception e) {
if (log) {
e.printStackTrace();
}
}
public void init(String[] args) throws Exception {
port = DEFAULT_PORT;
for (int i = 0; i < args.length; i++) {
String a = args[i];
if (a.equals("-log")) {
log = Boolean.valueOf(args[++i]).booleanValue();
} else if (a.equals("-odbcPort")) {
port = MathUtils.decodeInt(args[++i]);
} else if (a.equals("-baseDir")) {
baseDir = args[++i];
} else if (a.equals("-odbcAllowOthers")) {
allowOthers = Boolean.valueOf(args[++i]).booleanValue();
} else if (a.equals("-ifExists")) {
ifExists = Boolean.valueOf(args[++i]).booleanValue();
}
}
org.h2.Driver.load();
url = "tcp://localhost:" + port;
}
public String getURL() {
return url;
}
boolean allow(Socket socket) {
if(allowOthers) {
return true;
}
return socket.getInetAddress().isLoopbackAddress();
}
public void start() throws SQLException {
serverSocket = NetUtils.createServerSocket(port, false);
}
public void listen() {
String threadName = Thread.currentThread().getName();
try {
while (!stop) {
Socket s = serverSocket.accept();
if(!allow(s)) {
log("Connection not allowed");
s.close();
} else {
OdbcServerThread c = new OdbcServerThread(s, this);
running.add(c);
Thread thread = new Thread(c);
thread.setName(threadName+" thread");
c.setThread(thread);
thread.start();
}
}
} catch (Exception e) {
if(!stop) {
e.printStackTrace();
}
}
}
public void stop() {
// TODO server: share code between web and tcp servers
if(!stop) {
stop = true;
if(serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
// TODO log exception
e.printStackTrace();
}
serverSocket = null;
}
}
// TODO server: using a boolean 'now' argument? a timeout?
ArrayList list = new ArrayList(running);
for(int i=0; i<list.size(); i++) {
OdbcServerThread c = (OdbcServerThread) list.get(i);
c.close();
try {
c.getThread().join(100);
} catch(Exception e) {
// TODO log exception
e.printStackTrace();
}
}
}
public boolean isRunning() {
if(serverSocket == null) {
return false;
}
try {
Socket s = NetUtils.createSocket(InetAddress.getLocalHost(), serverSocket.getLocalPort(), false);
s.close();
return true;
} catch(Exception e) {
return false;
}
}
public String getBaseDir() {
return baseDir;
}
public boolean getAllowOthers() {
return allowOthers;
}
public String getType() {
return "ODBC";
}
public boolean getIfExists() {
return ifExists;
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.server;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
/**
* @author Thomas
*/
public class OdbcTransfer {
static final int BUFFER_SIZE = 1024;
private DataInputStream in;
private DataOutputStream out;
OdbcTransfer(DataInputStream in, DataOutputStream out) {
this.in = in;
this.out = out;
}
OdbcTransfer writeBoolean(boolean x) throws IOException {
writeInt(x ? 1 : 0);
return this;
}
OdbcTransfer writeOk() throws IOException {
writeBoolean(true);
return this;
}
boolean readBoolean() throws IOException {
return readInt() == 1;
}
OdbcTransfer writeByte(byte x) throws IOException {
out.write(x);
return this;
}
int readByte() throws IOException {
return in.read();
}
OdbcTransfer writeShort(short x) throws IOException {
return writeInt(x);
}
short readShort() throws IOException {
return (short) readInt();
}
OdbcTransfer writeInt(int i) throws IOException {
out.writeInt(i);
return this;
}
int readInt() throws IOException {
return in.readInt();
}
OdbcTransfer writeLong(long i) throws IOException {
out.writeLong(i);
return this;
}
long readLong() throws IOException {
return in.readLong();
}
OdbcTransfer writeFloat(float i) throws IOException {
out.writeFloat(i);
return this;
}
float readFloat() throws IOException {
return in.readFloat();
}
OdbcTransfer writeDouble(double i) throws IOException {
out.writeDouble(i);
return this;
}
double readDouble() throws IOException {
return in.readDouble();
}
OdbcTransfer writeString(String s) throws IOException {
if (s == null) {
out.writeInt(-1);
} else {
out.writeInt(s.length());
for(int i=0; i<s.length(); i++) {
out.write(s.charAt(i));
}
}
return this;
}
String readString() throws IOException {
int len = in.readInt();
if (len == -1) {
return null;
}
char[] chars = new char[len];
for(int i=0; i<len; i++) {
chars[i] = (char)in.readByte();
}
return new String(chars);
}
OdbcTransfer writeDate(java.sql.Date x) throws IOException {
if (x == null) {
writeString(null);
} else {
writeString(x.toString());
}
return this;
}
OdbcTransfer writeTime(java.sql.Time x) throws IOException {
if (x == null) {
writeString(null);
} else {
writeString(x.toString());
}
return this;
}
OdbcTransfer writeTimestamp(java.sql.Timestamp x) throws IOException {
if (x == null) {
writeString(null);
} else {
writeString(x.toString());
}
return this;
}
java.sql.Date readDate() throws IOException {
String s = readString();
if (s == null) {
return null;
}
return java.sql.Date.valueOf(s);
}
java.sql.Time readTime() throws IOException {
String s = readString();
if (s == null) {
return null;
}
return java.sql.Time.valueOf(s);
}
java.sql.Timestamp readTimestamp() throws IOException {
String s = readString();
if (s == null) {
return null;
}
return java.sql.Timestamp.valueOf(s);
}
OdbcTransfer writeByteArray(byte[] data) throws IOException {
if (data == null) {
writeInt(-1);
} else {
writeInt(data.length);
}
out.write(data);
return this;
}
byte[] readByteArray() throws IOException {
int len = readInt();
if (len == -1) {
return null;
}
byte[] b = new byte[len];
in.readFully(b);
return b;
}
OdbcTransfer writeIntArray(int[] s) throws IOException {
if (s == null) {
writeInt(-1);
} else {
writeInt(s.length);
for (int i = 0; i < s.length; i++) {
writeInt(s[i]);
}
}
return this;
}
int[] readIntArray() throws IOException {
int len = readInt();
if (len == -1) {
return null;
}
int[] s = new int[len];
for (int i = 0; i < len; i++) {
s[i] = readInt();
}
return s;
}
OdbcTransfer writeStringArray(String[] s) throws IOException {
if (s == null) {
writeInt(-1);
} else {
writeInt(s.length);
for (int i = 0; i < s.length; i++) {
writeString(s[i]);
}
}
return this;
}
String[] readStringArray() throws IOException {
int len = readInt();
if (len == -1) {
return null;
}
String[] s = new String[len];
for (int i = 0; i < len; i++) {
s[i] = readString();
}
return s;
}
// buffer - cannot be null
OdbcTransfer writeBuffer(byte[] buffer) throws IOException {
out.write(buffer);
return this;
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.server;
import java.sql.SQLException;
public interface Service {
void init(String[] args) throws Exception;
String getURL();
void start() throws SQLException;
void listen();
void stop();
boolean isRunning();
boolean getAllowOthers();
String getType();
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.server;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import org.h2.engine.Constants;
import org.h2.message.TraceSystem;
import org.h2.util.MathUtils;
import org.h2.util.NetUtils;
public class TcpServer implements Service {
// TODO new feature: implement automatic client / server mode if 'socket' file locking is used
// TODO make the kernel multi-threaded
// TODO better exception message if the port is already in use, maybe automatically use the next free port?
public static final int DEFAULT_PORT = 9092;
public static final int SHUTDOWN_NORMAL = 0;
public static final int SHUTDOWN_FORCE = 1;
public static boolean LOG_INTERNAL_ERRORS;
private int port;
private boolean log;
private boolean ssl;
private boolean stop;
private ServerSocket serverSocket;
private HashSet running = new HashSet();
private String baseDir;
private String url;
private boolean allowOthers;
private boolean ifExists;
private Connection managementDb;
private String managementPassword = "";
private static HashMap servers = new HashMap();
public static String getManagementDbName(int port) {
return "mem:" + Constants.MANAGEMENT_DB_PREFIX + port;
}
private void initManagementDb() throws SQLException {
Connection conn = DriverManager.getConnection("jdbc:h2:" + getManagementDbName(port), "sa", managementPassword);
managementDb = conn;
Statement stat = conn.createStatement();
stat.execute("CREATE ALIAS IF NOT EXISTS STOP_SERVER FOR \"" + TcpServer.class.getName() +".stopServer\"");
servers.put(""+port, this);
}
private void stopManagementDb() {
if(managementDb != null) {
try {
managementDb.close();
} catch (SQLException e) {
TraceSystem.traceThrowable(e);
}
managementDb = null;
}
}
public static void stopServer(int port, String password, int shutdownMode) {
TcpServer server = (TcpServer) servers.get("" + port);
if(server == null) {
return;
}
if(!server.managementPassword.equals(password)) {
return;
}
if(shutdownMode == TcpServer.SHUTDOWN_NORMAL) {
server.stop = true;
try {
Socket s = new Socket("localhost", port);
s.close();
} catch (Exception e) {
// try to connect - so that accept returns
}
} else if(shutdownMode == TcpServer.SHUTDOWN_FORCE) {
server.stop();
}
}
public void init(String[] args) throws Exception {
port = DEFAULT_PORT;
for (int i = 0; i < args.length; i++) {
String a = args[i];
if (a.equals("-log")) {
log = Boolean.valueOf(args[++i]).booleanValue();
} else if (a.equals("-tcpSSL")) {
ssl = Boolean.valueOf(args[++i]).booleanValue();
} else if (a.equals("-tcpPort")) {
port = MathUtils.decodeInt(args[++i]);
} else if (a.equals("-tcpPassword")) {
managementPassword= args[++i];
} else if (a.equals("-baseDir")) {
baseDir = args[++i];
} else if (a.equals("-tcpAllowOthers")) {
allowOthers = Boolean.valueOf(args[++i]).booleanValue();
} else if (a.equals("-ifExists")) {
ifExists = Boolean.valueOf(args[++i]).booleanValue();
}
}
org.h2.Driver.load();
url = (ssl ? "ssl" : "tcp") + "://localhost:" + port;
}
public String getURL() {
return url;
}
boolean allow(Socket socket) {
if(allowOthers) {
return true;
}
return socket.getInetAddress().isLoopbackAddress();
}
public void start() throws SQLException {
initManagementDb();
serverSocket = NetUtils.createServerSocket(port, ssl);
}
public void listen() {
String threadName = Thread.currentThread().getName();
try {
while (!stop) {
Socket s = serverSocket.accept();
TcpServerThread c = new TcpServerThread(s, this);
running.add(c);
Thread thread = new Thread(c);
thread.setName(threadName+" thread");
c.setThread(thread);
thread.start();
}
} catch (Exception e) {
if(!stop) {
TraceSystem.traceThrowable(e);
}
}
stopManagementDb();
}
public boolean isRunning() {
if(serverSocket == null) {
return false;
}
try {
Socket s = NetUtils.createLoopbackSocket(port, ssl);
s.close();
return true;
} catch(Exception e) {
return false;
}
}
public synchronized void stop() {
// TODO server: share code between web and tcp servers
if(!stop) {
stop = true;
if(serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
TraceSystem.traceThrowable(e);
}
serverSocket = null;
}
}
// TODO server: using a boolean 'now' argument? a timeout?
ArrayList list = new ArrayList(running);
for(int i=0; i<list.size(); i++) {
TcpServerThread c = (TcpServerThread) list.get(i);
c.close();
try {
c.getThread().join(100);
} catch(Exception e) {
TraceSystem.traceThrowable(e);
}
}
servers.remove(""+port);
}
synchronized void remove(TcpServerThread t) {
running.remove(t);
}
boolean getLog() {
return log;
}
String getBaseDir() {
return baseDir;
}
void log(String s) {
// TODO log: need concept for server log
if (log) {
System.out.println(s);
}
}
void logError(Exception e) {
if (log) {
e.printStackTrace();
}
}
public boolean getAllowOthers() {
return allowOthers;
}
public String getType() {
return "TCP";
}
public void logInternalError(String string) {
if(TcpServer.LOG_INTERNAL_ERRORS) {
System.out.println(string);
new Error(string).printStackTrace();
}
}
public boolean getIfExists() {
return ifExists;
}
}
差异被折叠。
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.server.ftp;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public interface FileObject {
boolean exists();
boolean isDirectory();
boolean isFile();
boolean delete();
boolean mkdirs();
long lastModified();
boolean renameTo(FileObject fileNew);
void read(long skip, OutputStream out) throws IOException;
FileObject[] listFiles();
long length();
boolean canRead();
boolean canWrite();
String getName();
void write(InputStream in) throws IOException;
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.server.ftp;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class FileObjectDatabase implements FileObject {
static FileObjectDatabase get(FileSystemDatabase db, String name) {
return new FileObjectDatabase(db, name);
}
private FileSystemDatabase db;
private String fullName;
private FileObjectDatabase(FileSystemDatabase db, String fullName) {
this.db = db;
this.fullName = fullName;
}
public boolean canRead() {
return true;
}
public boolean canWrite() {
return true;
}
public boolean delete() {
db.delete(fullName);
return true;
}
public boolean exists() {
return db.exists(fullName);
}
public void read(long skip, OutputStream out) throws IOException {
db.read(fullName, skip, out);
}
public String getName() {
return db.getName(fullName);
}
public void write(InputStream in) throws IOException {
db.write(fullName, in);
}
public boolean isDirectory() {
return db.isDirectory(fullName);
}
public boolean isFile() {
return !db.isDirectory(fullName);
}
public long lastModified() {
return db.lastModified(fullName);
}
public long length() {
return db.length(fullName);
}
public FileObject[] listFiles() {
return db.listFiles(fullName);
}
public boolean mkdirs() {
db.mkdirs(fullName);
return true;
}
public boolean renameTo(FileObject fileNew) {
return db.renameTo(fullName, ((FileObjectDatabase)fileNew).fullName);
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.server.ftp;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.h2.util.IOUtils;
public class FileObjectNative implements FileObject {
private File file;
static FileObjectNative get(String name) {
return new FileObjectNative(new File(name));
}
private FileObjectNative(File f) {
this.file = f;
}
public boolean exists() {
return file.exists();
}
public boolean isDirectory() {
return file.isDirectory();
}
public boolean canRead() {
return file.canRead();
}
public boolean canWrite() {
return file.canWrite();
}
public boolean delete() {
return file.delete();
}
public String getName() {
return file.getName();
}
public boolean isFile() {
return file.isFile();
}
public long lastModified() {
return file.lastModified();
}
public long length() {
return file.length();
}
public FileObject[] listFiles() {
File[] list = file.listFiles();
FileObject[] result = new FileObject[list.length];
for(int i=0; i<list.length; i++) {
result[i] = get(list[i].getAbsolutePath());
}
return result;
}
public boolean mkdirs() {
return file.mkdirs();
}
public boolean renameTo(FileObject newFile) {
return file.renameTo(get(newFile.getName()).file);
}
public void write(InputStream in) throws IOException {
FileOutputStream out = new FileOutputStream(file);
IOUtils.copyAndClose(in, out);
}
public void read(long skip, OutputStream out) throws IOException {
InputStream in = new FileInputStream(file);
IOUtils.skipFully(in, skip);
IOUtils.copyAndClose(in, out);
}
}
差异被折叠。
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.server.ftp;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class FtpData extends Thread {
private FtpServer server;
private InetAddress address;
private ServerSocket serverSocket;
private volatile Socket socket;
public FtpData(FtpServer server, InetAddress address, ServerSocket serverSocket) throws IOException {
this.server = server;
this.address = address;
this.serverSocket = serverSocket;
}
public void run() {
try {
synchronized(this) {
Socket s = serverSocket.accept();
if(s.getInetAddress().equals(address)) {
server.log("Data connected:" + s.getInetAddress() + " expected:" + address);
socket = s;
notifyAll();
} else {
server.log("Data REJECTED:" + s.getInetAddress() + " expected:" + address);
close();
}
}
} catch(IOException e) {
e.printStackTrace();
}
}
private void waitUntilConnected() {
while(serverSocket != null && socket == null) {
try {
wait();
} catch(InterruptedException e) {
// ignore
}
}
server.log("connected");
}
public void close() {
serverSocket = null;
socket = null;
}
public synchronized void receive(FileObject file) throws IOException {
waitUntilConnected();
try {
InputStream in = socket.getInputStream();
file.write(in);
} finally {
socket.close();
}
server.log("closed");
}
public synchronized void send(FileObject file, long skip) throws IOException {
waitUntilConnected();
try {
OutputStream out = socket.getOutputStream();
file.read(skip, out);
} finally {
socket.close();
}
server.log("closed");
}
public synchronized void send(byte[] data) throws IOException {
waitUntilConnected();
try {
OutputStream out = socket.getOutputStream();
out.write(data);
} finally {
socket.close();
}
server.log("closed");
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.server.ftp;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import org.h2.engine.Constants;
import org.h2.server.Service;
import org.h2.util.MathUtils;
import org.h2.util.NetUtils;
/**
* Small FTP Server. Intended for ad-hoc networks in a secure environment.
* See also http://cr.yp.to/ftp.html http://www.ftpguide.com/
*/
public class FtpServer implements Service {
public static final String DEFAULT_ROOT = "ftp";
public static final String DEFAULT_READ = "guest";
public static final String DEFAULT_WRITE = "sa";
public static final String DEFAULT_WRITE_PASSWORD = "sa";
private ServerSocket serverSocket;
private int port = Constants.DEFAULT_FTP_PORT;
private int openConnectionCount;
private int maxConnectionCount = 100;
private SimpleDateFormat dateFormatNew = new SimpleDateFormat("MMM dd HH:mm", Locale.ENGLISH);
private SimpleDateFormat dateFormatOld = new SimpleDateFormat("MMM dd yyyy", Locale.ENGLISH);
private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
private String root = DEFAULT_ROOT;
private String writeUserName = DEFAULT_WRITE, writePassword = DEFAULT_WRITE_PASSWORD;
private String readUserName = DEFAULT_READ;
private FileSystemDatabase db;
private boolean log;
public void listen() {
try {
while (serverSocket != null) {
Socket s = serverSocket.accept();
boolean stop;
synchronized(this) {
openConnectionCount++;
stop = openConnectionCount > maxConnectionCount;
}
FtpControl c = new FtpControl(s, this, stop);
c.start();
}
} catch (Exception e) {
logError(e);
}
}
void closeConnection() {
synchronized(this) {
openConnectionCount--;
}
}
public ServerSocket createDataSocket() throws IOException {
ServerSocket dataSocket = new ServerSocket(0);
return dataSocket;
}
void appendFile(StringBuffer buff, FileObject f) {
buff.append(f.isDirectory() ? 'd' : '-');
buff.append(f.canRead() ? 'r' : '-');
buff.append(f.canWrite() ? 'w' : '-');
buff.append("------- 1 owner group ");
String size = String.valueOf(f.length());
for(int i = size.length(); i < 15; i++) {
buff.append(' ');
}
buff.append(size);
buff.append(' ');
Date now = new Date(), mod = new Date(f.lastModified());
if(mod.after(now) || Math.abs((now.getTime() - mod.getTime())/1000/60/60/24) > 180) {
buff.append(dateFormatOld.format(mod));
} else {
buff.append(dateFormatNew.format(mod));
}
buff.append(' ');
buff.append(f.getName());
buff.append("\r\n");
}
String formatLastModified(FileObject file) {
return dateFormat.format(new Date(file.lastModified()));
}
FileObject getFile(String path) {
if(path.indexOf("..") > 0) {
path = "/";
}
while(path.startsWith("/") && root.endsWith("/")) {
path = path.substring(1);
}
while(path.endsWith("/")) {
path = path.substring(0, path.length()-1);
}
log("file: " + root + path);
if(db != null) {
return FileObjectDatabase.get(db, root + path);
} else {
return FileObjectNative.get(root + path);
}
}
String getDirectoryListing(FileObject directory, boolean listDirectories) {
FileObject[] list = directory.listFiles();
StringBuffer buff = new StringBuffer();
for(int i=0; list != null && i<list.length; i++) {
FileObject f = list[i];
if(f.isFile() || (f.isDirectory() && listDirectories)) {
appendFile(buff, f);
}
}
return buff.toString();
}
public boolean checkUserPassword(String userName, String param) {
return userName.equals(this.writeUserName) && writePassword.equals(this.writePassword);
}
public boolean checkUserPasswordReadOnly(String userName, String param) {
return userName.equals(this.readUserName);
}
public void init(String[] args) throws Exception {
for(int i=0; args != null && i<args.length; i++) {
if("-ftpPort".equals(args[i])) {
port = MathUtils.decodeInt(args[++i]);
} else if("-ftpDir".equals(args[i])) {
root = args[++i];
} else if("-ftpRead".equals(args[i])) {
readUserName = args[++i];
} else if("-ftpWrite".equals(args[i])) {
writeUserName = args[++i];
} else if("-ftpWritePassword".equals(args[i])) {
writePassword = args[++i];
} else if("-log".equals(args[i])) {
log = Boolean.valueOf(args[++i]).booleanValue();
}
}
if(root.startsWith("jdbc:")) {
org.h2.Driver.load();
Connection conn = DriverManager.getConnection(root);
db = new FileSystemDatabase(conn, log);
root = "/";
}
}
public String getURL() {
return "ftp://localhost:"+port;
}
public void start() throws SQLException {
getFile("").mkdirs();
serverSocket = NetUtils.createServerSocket(port, false);
}
public void stop() {
try {
serverSocket.close();
} catch(IOException e) {
logError(e);
}
serverSocket = null;
}
public boolean isRunning() {
if(serverSocket == null) {
return false;
}
try {
Socket s = NetUtils.createLoopbackSocket(port, false);
s.close();
return true;
} catch(Exception e) {
return false;
}
}
public boolean getAllowOthers() {
return true;
}
public String getType() {
return "FTP";
}
void log(String s) {
if(log) {
System.out.println(s);
}
}
void logError(Throwable e) {
if (log) {
e.printStackTrace();
}
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.server.web;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Properties;
import org.h2.engine.Constants;
import org.h2.message.TraceSystem;
import org.h2.util.FileUtils;
import org.h2.util.MathUtils;
import org.h2.util.StringUtils;
public class AppServer {
private static final String[] GENERIC = new String[] {
"Generic Firebird Server|org.firebirdsql.jdbc.FBDriver|jdbc:firebirdsql:localhost:c:/temp/firebird/test|sysdba",
"Generic OneDollarDB|in.co.daffodil.db.jdbc.DaffodilDBDriver|jdbc:daffodilDB_embedded:school;path=C:/temp;create=true|sa",
"Generic DB2|COM.ibm.db2.jdbc.net.DB2Driver|jdbc:db2://<host>/<db>|" ,
"Generic Oracle|oracle.jdbc.driver.OracleDriver|jdbc:oracle:thin:@<host>:1521:<instance>|scott" ,
"Generic PostgreSQL|org.postgresql.Driver|jdbc:postgresql:<db>|" ,
"Generic MS SQL Server|com.microsoft.jdbc.sqlserver.SQLServerDriver|jdbc:Microsoft:sqlserver://localhost:1433;DatabaseName=sqlexpress|sa",
"Generic MS SQL Server 2005|com.microsoft.sqlserver.jdbc.SQLServerDriver|jdbc:sqlserver://localhost;DatabaseName=test|sa",
"Generic MySQL|com.mysql.jdbc.Driver|jdbc:mysql://<host>:<port>/<db>|" ,
"Generic Derby (Embedded)|org.apache.derby.jdbc.EmbeddedDriver|jdbc:derby:test;create=true|sa",
"Generic Derby (Server)|org.apache.derby.jdbc.ClientDriver|jdbc:derby://localhost:1527/test;create=true|sa",
"Generic HSQLDB|org.hsqldb.jdbcDriver|jdbc:hsqldb:test;hsqldb.default_table_type=cached|sa" ,
"Generic H2|org.h2.Driver|jdbc:h2:test|sa",
};
private URLClassLoader urlClassLoader;
private String driverList;
private static int ticker;
private int port;
private boolean allowOthers;
private boolean ssl;
private HashMap connectionInfos = new HashMap();
AppServer(String[] args) {
Properties prop = loadProperties();
driverList = prop.getProperty("drivers");
port = FileUtils.getIntProperty(prop, "webPort", Constants.DEFAULT_HTTP_PORT);
ssl = FileUtils.getBooleanProperty(prop, "webSSL", Constants.DEFAULT_HTTP_SSL);
allowOthers = FileUtils.getBooleanProperty(prop, "webAllowOthers", Constants.DEFAULT_HTTP_ALLOW_OTHERS);
for(int i=0; args != null && i<args.length; i++) {
if("-webPort".equals(args[i])) {
port = MathUtils.decodeInt(args[++i]);
} else if("-webSSL".equals(args[i])) {
ssl = Boolean.valueOf(args[++i]).booleanValue();
} else if("-webAllowOthers".equals(args[i])) {
allowOthers = Boolean.valueOf(args[++i]).booleanValue();
}
}
// TODO gcj: don't load drivers in case of GCJ
if(false) {
if(driverList != null) {
try {
String[] drivers = StringUtils.arraySplit(driverList, ',', false);
URL[] urls = new URL[drivers.length];
for(int i=0; i<drivers.length; i++) {
urls[i] = new URL(drivers[i]);
}
urlClassLoader = URLClassLoader.newInstance(urls);
} catch (MalformedURLException e) {
TraceSystem.traceThrowable(e);
}
}
}
}
void setAllowOthers(boolean b) {
allowOthers = b;
}
void setSSL(boolean b) {
ssl = b;
}
void setPort(int port) {
this.port = port;
}
boolean getAllowOthers() {
return allowOthers;
}
boolean getSSL() {
return ssl;
}
int getPort() {
return port;
}
ConnectionInfo getSetting(String name) {
return (ConnectionInfo)connectionInfos.get(name);
}
void updateSetting(ConnectionInfo info) {
connectionInfos.put(info.name, info);
info.lastAccess = ticker++;
}
void removeSetting(String name) {
connectionInfos.remove(name);
}
private File getPropertiesFile() {
// store the properties in the user directory
return FileUtils.getFileInUserHome(Constants.SERVER_PROPERTIES_FILE);
}
Properties loadProperties() {
File file = getPropertiesFile();
try {
return FileUtils.loadProperties(file);
} catch(IOException e) {
// TODO log exception
return new Properties();
}
}
String[] getSettingNames() {
ArrayList list = getSettings();
String[] names = new String[list.size()];
for(int i=0; i<list.size(); i++) {
names[i] = ((ConnectionInfo)list.get(i)).name;
}
return names;
}
synchronized ArrayList getSettings() {
ArrayList settings = new ArrayList();
if(connectionInfos.size() == 0) {
Properties prop = loadProperties();
if(prop.size() == 0) {
for(int i=0; i<AppServer.GENERIC.length; i++) {
ConnectionInfo info = new ConnectionInfo(AppServer.GENERIC[i]);
settings.add(info);
updateSetting(info);
}
} else {
for(int i=0; ; i++) {
String data = prop.getProperty(String.valueOf(i));
if(data == null) {
break;
}
ConnectionInfo info = new ConnectionInfo(data);
settings.add(info);
updateSetting(info);
}
}
} else {
settings.addAll(connectionInfos.values());
}
sortConnectionInfo(settings);
return settings;
}
void sortConnectionInfo(ArrayList list) {
for (int i = 1, j; i < list.size(); i++) {
ConnectionInfo t = (ConnectionInfo) list.get(i);
for (j = i - 1; j >= 0 && (((ConnectionInfo)list.get(j)).lastAccess < t.lastAccess); j--) {
list.set(j + 1, list.get(j));
}
list.set(j + 1, t);
}
}
synchronized void saveSettings() {
try {
Properties prop = new Properties();
if(driverList != null) {
prop.setProperty("drivers", driverList);
}
prop.setProperty("webPort", String.valueOf(port));
prop.setProperty("webAllowOthers", String.valueOf(allowOthers));
prop.setProperty("webSSL", String.valueOf(ssl));
ArrayList settings = getSettings();
int len = settings.size();
for(int i=0; i<len; i++) {
ConnectionInfo info = (ConnectionInfo) settings.get(i);
if(info != null) {
prop.setProperty(String.valueOf(len - i - 1), info.getString());
}
}
FileOutputStream out = new FileOutputStream(getPropertiesFile());
prop.store(out, Constants.SERVER_PROPERTIES_TITLE);
out.close();
} catch(IOException e) {
TraceSystem.traceThrowable(e);
}
}
// TODO GCJ: if this method is synchronized, then the .exe file fails (probably does not unlock the object)
// and cannot go in here after a class was not found
Connection getConnection(String driver, String url, String user, String password) throws Exception {
driver = driver.trim();
url = url.trim();
user = user.trim();
password = password.trim();
org.h2.Driver.load();
try {
Class.forName(driver);
} catch(ClassNotFoundException e) {
if(urlClassLoader == null) {
throw e;
}
try {
Driver dr = (Driver) urlClassLoader.loadClass(driver).newInstance();
Properties p = new Properties();
p.setProperty("user", user);
p.setProperty("password", password);
return dr.connect(url, p);
} catch(ClassNotFoundException e2) {
throw e2;
}
}
return DriverManager.getConnection(url, user, password);
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.server.web;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import org.h2.bnf.Bnf;
import org.h2.message.TraceSystem;
public class AppSession extends WebServerSession {
private static final int MAX_HISTORY = 1000;
private ArrayList commandHistory = new ArrayList();
private Connection conn;
private DatabaseMetaData meta;
private DbContents contents = new DbContents();
private DbContextRule columnRule;
private DbContextRule newAliasRule;
private DbContextRule tableRule;
private DbContextRule aliasRule;
private DbContextRule columnAliasRule;
private Bnf bnf;
Statement executingStatement;
ResultSet result;
AppSession(WebServer server) {
super(server);
}
public Bnf getBnf() {
return bnf;
}
void loadBnf() {
try {
Bnf newBnf = Bnf.getInstance(null);
columnRule = new DbContextRule(contents, DbContextRule.COLUMN);
newAliasRule = new DbContextRule(contents, DbContextRule.NEW_TABLE_ALIAS);
aliasRule = new DbContextRule(contents, DbContextRule.TABLE_ALIAS);
tableRule = new DbContextRule(contents, DbContextRule.TABLE);
columnAliasRule = new DbContextRule(contents, DbContextRule.COLUMN_ALIAS);
// bnf.updateTopic("newTableName", new String[]{"TEST"});
// String[] schemas;
// if(contents.isMySQL) {
// schemas = new String[0];
// } else {
// schemas = new String[contents.schemas.length];
// for(int i=0; i<contents.schemas.length; i++) {
// schemas[i] = contents.schemas[i].quotedName + ".";
// }
// }
// bnf.updateTopic("schemaName", schemas);
newBnf.updateTopic("columnName", columnRule);
newBnf.updateTopic("newTableAlias", newAliasRule);
newBnf.updateTopic("tableAlias", aliasRule);
newBnf.updateTopic("columnAlias", columnAliasRule);
newBnf.updateTopic("tableName", tableRule);
// bnf.updateTopic("name", new String[]{""});
newBnf.linkStatements();
bnf = newBnf;
} catch(Exception e) {
// ok we don't have the bnf
e.printStackTrace();
}
}
String getCommand(int id) {
return (String) commandHistory.get(id);
}
void addCommand(String sql) {
if(sql == null) {
return;
}
sql = sql.trim();
if(sql.length() == 0) {
return;
}
if(commandHistory.size() > MAX_HISTORY) {
commandHistory.remove(0);
}
int idx = commandHistory.indexOf(sql);
if(idx >= 0) {
commandHistory.remove(idx);
}
commandHistory.add(sql);
}
ArrayList getCommands() {
return commandHistory;
}
public HashMap getInfo() {
HashMap m = super.getInfo();
try {
m.put("url", conn == null ? "not connected" : conn.getMetaData().getURL());
m.put("user", conn == null ? "-" : conn.getMetaData().getUserName());
m.put("lastQuery", commandHistory.size()==0 ? "" : commandHistory.get(0));
m.put("executing", executingStatement==null ? "no" : "yes");
} catch (SQLException e) {
TraceSystem.traceThrowable(e);
}
return m;
}
void setConnection(Connection conn) throws SQLException {
this.conn = conn;
if(conn == null) {
meta = null;
} else {
meta = conn.getMetaData();
}
contents = new DbContents();
}
DatabaseMetaData getMetaData() {
return meta;
}
Connection getConnection() {
return conn;
}
public DbContents getContents() {
return contents;
}
}
差异被折叠。
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.server.web;
import org.h2.util.StringUtils;
public class ConnectionInfo {
String name, driver, url, user;
int lastAccess;
ConnectionInfo() {
}
ConnectionInfo(String data) {
String[] array = StringUtils.arraySplit(data, '|', false);
name = get(array, 0);
driver = get(array, 1);
url = get(array, 2);
user = get(array, 3);
}
private String get(String[] array, int i) {
return array != null && array.length>i ? array[i] : "";
}
String getString() {
return StringUtils.arrayCombine(new String[]{name, driver, url, user}, '|');
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.server.web;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
public class DbColumn {
String name;
String dataType;
DbColumn(ResultSet rs) throws SQLException {
name = rs.getString("COLUMN_NAME");
String type = rs.getString("TYPE_NAME");
int size = rs.getInt("COLUMN_SIZE");
if(size > 0) {
type += "("+size;
int prec = rs.getInt("DECIMAL_DIGITS");
if(prec > 0) {
type += ", " + prec;
}
type += ")";
}
if(rs.getInt("NULLABLE") == DatabaseMetaData.columnNoNulls) {
type +=" NOT NULL";
}
dataType = type;
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.server.web;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import org.h2.command.Parser;
import org.h2.util.StringUtils;
public class DbContents {
DbSchema[] schemas;
DbSchema defaultSchema;
boolean isOracle, isH2, isPostgreSQL, isHSQLDB, isMySQL, isDerby, isFirebird, isSQLite;
void readContents(DatabaseMetaData meta) throws SQLException {
String prod = StringUtils.toLowerEnglish(meta.getDatabaseProductName());
isSQLite = prod.indexOf("sqlite") >= 0;
String url = meta.getURL();
if(url != null) {
isH2 = url.startsWith("jdbc:h2:");
isOracle = url.startsWith("jdbc:oracle:");
isPostgreSQL = url.startsWith("jdbc:postgresql:");
isHSQLDB = url.startsWith("jdbc:hsqldb:");
isMySQL = url.startsWith("jdbc:mysql:");
isDerby = url.startsWith("jdbc:derby:");
isFirebird = url.startsWith("jdbc:firebirdsql:");
}
String defaultSchemaName = getDefaultSchemaName(meta);
String[] schemaNames = getSchemaNames(meta);
schemas = new DbSchema[schemaNames.length];
for(int i=0; i<schemaNames.length; i++) {
String schemaName = schemaNames[i];
boolean isDefault = defaultSchemaName==null || defaultSchemaName.equals(schemaName);
DbSchema schema = new DbSchema(this, schemaName, isDefault);
if(schema.isDefault) {
defaultSchema = schema;
}
schemas[i] = schema;
String[] tableTypes = new String[]{"TABLE", "SYSTEM TABLE", "VIEW", "SYSTEM VIEW", "TABLE LINK", "SYNONYM"};
schema.readTables(meta, tableTypes);
}
if(defaultSchema == null) {
for(int i=0; i<schemas.length; i++) {
String best = null;
if("dbo".equals(schemas[i].name)) {
// MS SQL Server
defaultSchema = schemas[i];
break;
}
if(defaultSchema == null || best == null || schemas[i].name.length() < best.length()) {
best = schemas[i].name;
defaultSchema = schemas[i];
}
}
}
}
private String[] getSchemaNames(DatabaseMetaData meta) throws SQLException {
if(isMySQL) {
return new String[]{""};
} else if(isFirebird) {
return new String[]{null};
}
ResultSet rs = meta.getSchemas();
ArrayList schemas = new ArrayList();
while(rs.next()) {
String schema = rs.getString("TABLE_SCHEM");
if(schema == null) {
continue;
}
schemas.add(schema);
}
rs.close();
String[] list = new String[schemas.size()];
schemas.toArray(list);
return list;
}
private String getDefaultSchemaName(DatabaseMetaData meta) throws SQLException {
String defaultSchemaName = "";
try {
if(isOracle) {
return meta.getUserName();
} else if(isPostgreSQL) {
return "public";
} else if(isMySQL) {
return "";
} else if(isDerby) {
return StringUtils.toUpperEnglish(meta.getUserName());
} else if(isFirebird) {
return null;
}
ResultSet rs = meta.getSchemas();
int index = rs.findColumn("IS_DEFAULT");
while(rs.next()) {
if(rs.getBoolean(index)) {
defaultSchemaName = rs.getString("TABLE_SCHEM");
}
}
} catch(SQLException e) {
// IS_DEFAULT not found
}
return defaultSchemaName;
}
String quoteIdentifier(String identifier) {
if(identifier == null) {
return null;
}
if(isH2) {
return Parser.quoteIdentifier(identifier);
} else {
return StringUtils.toUpperEnglish(identifier);
// } else {
// return Generator.quoteIdentifierAlways(identifier);
}
}
}
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
${autoCompleteList}
\ No newline at end of file
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论