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

--no commit message

--no commit message
上级 2a22d077
/*
* 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.jdbcx;
import java.sql.SQLException;
import org.h2.jdbc.JdbcConnection;
public interface JdbcConnectionListener {
// TODO pooled connection: make sure fatalErrorOccured is called in the right situations
void fatalErrorOccured(JdbcConnection conn, SQLException e) throws SQLException;
void closed(JdbcConnection conn);
}
/*
* 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.jdbcx;
import java.io.PrintWriter;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.Referenceable;
import javax.naming.StringRefAddr;
import javax.sql.ConnectionPoolDataSource;
import javax.sql.DataSource;
import javax.sql.PooledConnection;
import javax.sql.XAConnection;
import javax.sql.XADataSource;
import org.h2.jdbc.JdbcConnection;
import org.h2.message.TraceObject;
/**
* A data source for H2 database connections
*
* @author Tom
*/
public class JdbcDataSource extends TraceObject implements XADataSource, DataSource, ConnectionPoolDataSource, Serializable, Referenceable {
private static final long serialVersionUID = 1288136338451857771L;
private JdbcDataSourceFactory factory;
private int timeout;
private PrintWriter logWriter;
private String user;
private String password;
private String url;
public JdbcDataSource() {
this.factory = new JdbcDataSourceFactory();
int id = getNextId(TraceObject.DATASOURCE);
setTrace(factory.getTrace(), TraceObject.DATASOURCE, id);
}
public int getLoginTimeout() throws SQLException {
debugCodeCall("getLoginTimeout");
return timeout;
}
public void setLoginTimeout(int timeout) throws SQLException {
debugCodeCall("setLoginTimeout", timeout);
this.timeout = timeout;
}
public PrintWriter getLogWriter() throws SQLException {
debugCodeCall("getLogWriter");
return logWriter;
}
public void setLogWriter(PrintWriter out) throws SQLException {
debugCodeCall("setLogWriter(out)");
logWriter = out;
}
public Connection getConnection() throws SQLException {
debugCodeCall("getConnection");
return getJdbcConnection(user, password);
}
public Connection getConnection(String user, String password) throws SQLException {
debugCode("getConnection("+quote(user)+", "+quote(password)+");");
return getJdbcConnection(user, password);
}
public JdbcConnection getJdbcConnection(String user, String password) throws SQLException {
debugCode("getJdbcConnection("+quote(user)+", "+quote(password)+");");
Properties info = new Properties();
info.setProperty("user", user);
info.setProperty("password", password);
return new JdbcConnection(url, info);
}
public String getURL() {
debugCodeCall("getURL");
return url;
}
public void setURL(String url) {
debugCodeCall("setURL", url);
this.url = url;
}
public String getPassword() {
debugCodeCall("getPassword");
return password;
}
public void setPassword(String password) {
debugCodeCall("setPassword", password);
this.password = password;
}
public String getUser() {
debugCodeCall("getUser");
return user;
}
public void setUser(String user) {
debugCodeCall("setUser", user);
this.user = user;
}
public Reference getReference() throws NamingException {
debugCodeCall("getReference");
String factoryClassName = JdbcDataSourceFactory.class.getName();
Reference ref = new Reference(getClass().getName(), factoryClassName, null);
ref.add(new StringRefAddr("url", getURL()));
ref.add(new StringRefAddr("user", getUser()));
ref.add(new StringRefAddr("password", password));
return ref;
}
public XAConnection getXAConnection() throws SQLException {
debugCodeCall("getXAConnection");
int id = getNextId(XA_DATASOURCE);
return new JdbcXAConnection(factory, id, url, user, password);
}
public XAConnection getXAConnection(String user, String password) throws SQLException {
debugCode("getXAConnection("+quote(user)+", "+quote(password)+");");
int id = getNextId(XA_DATASOURCE);
return new JdbcXAConnection(factory, id, url, user, password);
}
public PooledConnection getPooledConnection() throws SQLException {
debugCodeCall("getPooledConnection");
return getXAConnection();
}
public PooledConnection getPooledConnection(String user, String password) throws SQLException {
debugCode("getPooledConnection("+quote(user)+", "+quote(password)+");");
return getXAConnection(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.jdbcx;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.Reference;
import javax.naming.spi.ObjectFactory;
import org.h2.engine.Constants;
import org.h2.message.Trace;
import org.h2.message.TraceSystem;
public class JdbcDataSourceFactory implements ObjectFactory {
private static TraceSystem traceSystem;
private Trace trace;
static {
traceSystem = new TraceSystem("h2datasource" + Constants.SUFFIX_TRACE_FILE);
traceSystem.setLevelFile(TraceSystem.DEBUG);
}
public JdbcDataSourceFactory() {
trace = traceSystem.getTrace("JDBCX");
}
public synchronized Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) throws Exception {
trace.debug("getObjectInstance obj=" + obj + " name=" + name + " nameCtx=" + nameCtx + " environment=" + environment);
Reference ref = (Reference) obj;
if (ref.getClassName().equals(JdbcDataSource.class.getName())) {
JdbcDataSource dataSource = new JdbcDataSource();
dataSource.setURL((String) ref.get("url").getContent());
dataSource.setUser((String) ref.get("user").getContent());
dataSource.setPassword((String) ref.get("password").getContent());
return dataSource;
}
return null;
}
TraceSystem getTraceSystem() {
return traceSystem;
}
Trace getTrace() {
return trace;
}
}
/*
* 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.jdbcx;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Properties;
import javax.sql.ConnectionEvent;
import javax.sql.ConnectionEventListener;
import javax.sql.XAConnection;
import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
import org.h2.jdbc.JdbcConnection;
import org.h2.message.TraceObject;
import org.h2.util.ByteUtils;
public class JdbcXAConnection extends TraceObject implements XAConnection, JdbcConnectionListener, XAResource {
private JdbcDataSourceFactory factory;
private String url, user, password;
private JdbcConnection conn;
private ArrayList listeners = new ArrayList();
private Xid currentTransaction;
JdbcXAConnection(JdbcDataSourceFactory factory, int id, String url, String user, String password) {
this.factory = factory;
setTrace(factory.getTrace(), TraceObject.XA_DATASOURCE, id);
this.url = url;
this.user = user;
this.password = password;
}
public XAResource getXAResource() throws SQLException {
debugCodeCall("getXAResource");
return this;
}
public void close() throws SQLException {
debugCodeCall("close");
if(conn != null) {
conn.closeConnection();
conn = null;
}
}
public Connection getConnection() throws SQLException {
debugCodeCall("getConnection");
close();
Properties info = new Properties();
info.setProperty("user", user);
info.setProperty("password", password);
conn = new JdbcConnection(url, info);
return conn;
}
public void addConnectionEventListener(ConnectionEventListener listener) {
debugCode("addConnectionEventListener(listener)");
listeners.add(listener);
conn.setJdbcConnectionListener(this);
}
public void removeConnectionEventListener(ConnectionEventListener listener) {
debugCode("removeConnectionEventListener(listener)");
listeners.remove(listener);
}
public void fatalErrorOccured(JdbcConnection conn, SQLException e) throws SQLException {
debugCode("fatalErrorOccured(conn, e)");
for(int i=0; i<listeners.size(); i++) {
ConnectionEventListener listener = (ConnectionEventListener)listeners.get(i);
ConnectionEvent event = new ConnectionEvent(this, e);
listener.connectionErrorOccurred(event);
}
close();
}
public void closed(JdbcConnection conn) {
debugCode("closed(conn)");
for(int i=0; i<listeners.size(); i++) {
ConnectionEventListener listener = (ConnectionEventListener)listeners.get(i);
ConnectionEvent event = new ConnectionEvent(this);
listener.connectionClosed(event);
}
}
public int getTransactionTimeout() throws XAException {
debugCodeCall("getTransactionTimeout");
return 0;
}
public boolean setTransactionTimeout(int seconds) throws XAException {
debugCodeCall("setTransactionTimeout", seconds);
return false;
}
public boolean isSameRM(XAResource xares) throws XAException {
debugCode("isSameRM(xares)");
return xares == this;
}
public Xid[] recover(int flag) throws XAException {
debugCodeCall("recover", quoteFlags(flag));
checkOpen();
try {
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery("SELECT * FROM INFORMATION_SCHEMA.IN_DOUBT ORDER BY ID");
ArrayList list = new ArrayList();
while(rs.next()) {
String tid = rs.getString("TRANSACTION");
int id = getNextId(XID);
Xid xid = new JdbcXid(factory, id, tid);
list.add(xid);
}
Xid[] result = new Xid[list.size()];
list.toArray(result);
return result;
} catch(SQLException e) {
getTrace().debug("throw XAException.XAER_OUTSIDE", e);
throw new XAException(XAException.XAER_OUTSIDE);
}
}
private void checkOpen() throws XAException {
if(conn == null) {
getTrace().debug("conn==null");
throw new XAException(XAException.XAER_OUTSIDE);
}
}
public int prepare(Xid xid) throws XAException {
debugCode("prepare("+quoteXid(xid)+")");
checkOpen();
if(currentTransaction != xid) {
getTrace().debug("throw XAException.XAER_INVAL");
throw new XAException(XAException.XAER_INVAL);
}
try {
conn.createStatement().execute("PREPARE COMMIT");
} catch(SQLException e) {
throw convertException(e);
}
getTrace().debug("return TMSUCCESS");
return TMSUCCESS;
}
public void forget(Xid xid) throws XAException {
debugCode("forget("+quoteXid(xid)+")");
// TODO
}
public void rollback(Xid xid) throws XAException {
debugCode("rollback("+quoteXid(xid)+")");
try {
conn.rollback();
} catch(SQLException e) {
throw convertException(e);
}
getTrace().debug("rolled back");
}
public void end(Xid xid, int flags) throws XAException {
debugCode("end("+quoteXid(xid)+", "+quoteFlags(flags)+")");
if(flags == TMSUSPEND) {
return;
}
if(currentTransaction != xid) {
getTrace().debug("throw XAException.XAER_OUTSIDE");
throw new XAException(XAException.XAER_OUTSIDE);
}
getTrace().debug("currentTransaction=null");
currentTransaction = null;
}
private String quoteFlags(int flags) {
StringBuffer buff = new StringBuffer();
if((flags & XAResource.TMENDRSCAN) != 0) {
buff.append("|XAResource.TMENDRSCAN");
}
if((flags & XAResource.TMFAIL) != 0) {
buff.append("|XAResource.TMFAIL");
}
if((flags & XAResource.TMJOIN) != 0) {
buff.append("|XAResource.TMJOIN");
}
if((flags & XAResource.TMONEPHASE) != 0) {
buff.append("|XAResource.TMONEPHASE");
}
if((flags & XAResource.TMRESUME) != 0) {
buff.append("|XAResource.TMRESUME");
}
if((flags & XAResource.TMSTARTRSCAN) != 0) {
buff.append("|XAResource.TMSTARTRSCAN");
}
if((flags & XAResource.TMSUCCESS) != 0) {
buff.append("|XAResource.TMSUCCESS");
}
if((flags & XAResource.TMSUSPEND) != 0) {
buff.append("|XAResource.TMSUSPEND");
}
if(buff.length() == 0) {
buff.append("|XAResource.TMNOFLAGS");
}
return buff.toString().substring(1);
}
private String quoteXid(Xid xid) {
StringBuffer buff = new StringBuffer();
buff.append("\"f:");
buff.append(xid.getFormatId());
buff.append(",bq:");
buff.append(ByteUtils.convertBytesToString(xid.getBranchQualifier()));
buff.append(",gxid:");
buff.append(ByteUtils.convertBytesToString(xid.getGlobalTransactionId()));
buff.append(",c:");
buff.append(xid.getClass().getName());
buff.append("\"");
return buff.toString();
}
public void start(Xid xid, int flags) throws XAException {
debugCode("start("+quoteXid(xid)+", "+quoteFlags(flags)+")");
if(flags == TMRESUME) {
return;
}
if(currentTransaction != null) {
getTrace().debug("throw XAException.XAER_NOTA");
throw new XAException(XAException.XAER_NOTA);
}
try {
conn.setAutoCommit(false);
} catch(SQLException e) {
throw convertException(e);
}
getTrace().debug("currentTransaction=xid");
currentTransaction = xid;
}
private XAException convertException(SQLException e) {
getTrace().debug("throw XAException("+e.getMessage()+")");
return new XAException(e.getMessage());
}
public void commit(Xid xid, boolean onePhase) throws XAException {
debugCode("commit("+quoteXid(xid)+", "+onePhase+")");
try {
conn.commit();
} catch(SQLException e) {
throw convertException(e);
}
getTrace().debug("committed");
}
}
/*
* 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.jdbcx;
import java.sql.SQLException;
import java.util.StringTokenizer;
import javax.transaction.xa.Xid;
import org.h2.message.Message;
import org.h2.message.TraceObject;
import org.h2.util.ByteUtils;
public class JdbcXid extends TraceObject implements Xid {
private static final String PREFIX = "XID";
private int formatId;
private byte[] branchQualifier;
private byte[] globalTransactionId;
JdbcXid(JdbcDataSourceFactory factory, int id, String tid) throws SQLException {
setTrace(factory.getTrace(), TraceObject.XID, id);
try {
StringTokenizer tokenizer = new StringTokenizer(tid, "_");
String prefix = tokenizer.nextToken();
if(!PREFIX.equals(prefix)) {
throw Message.getSQLException(Message.WRONG_XID_FORMAT_1, tid);
}
formatId = Integer.parseInt(tokenizer.nextToken());
branchQualifier = ByteUtils.convertStringToBytes(tokenizer.nextToken());
globalTransactionId = ByteUtils.convertStringToBytes(tokenizer.nextToken());
} catch(Exception e) {
throw Message.getSQLException(Message.WRONG_XID_FORMAT_1, tid);
}
}
// private JdbcXid(JdbcDataSourceFactory factory, int id, Xid xid) {
// setTrace(factory.getTrace(), TraceObject.XID, id);
// this.formatId = xid.getFormatId();
// this.branchQualifier = clone(xid.getBranchQualifier());
// this.globalTransactionId = clone(xid.getGlobalTransactionId());
// }
public String getAsString() {
StringBuffer buff = new StringBuffer(PREFIX);
buff.append('_');
buff.append(formatId);
buff.append('_');
buff.append(ByteUtils.convertBytesToString(branchQualifier));
buff.append('_');
buff.append(ByteUtils.convertBytesToString(globalTransactionId));
return buff.toString();
}
// private byte[] clone(byte[] data) {
// byte[] d2 = new byte[data.length];
// System.arraycopy(data, 0, d2, 0, data.length);
// return d2;
// }
public int getFormatId() {
debugCodeCall("getFormatId");
return formatId;
}
public byte[] getBranchQualifier() {
debugCodeCall("getBranchQualifier");
return branchQualifier;
}
public byte[] getGlobalTransactionId() {
debugCodeCall("getGlobalTransactionId");
return globalTransactionId;
}
}
/*
* 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.message;
public class InternalException extends RuntimeException {
private static final long serialVersionUID = -5369631382082604330L;
private Exception cause;
public InternalException(Exception e) {
cause = e;
}
public Exception getOriginalCause() {
return cause;
}
}
差异被折叠。
/*
* 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.message;
/**
* @author Thomas
*/
public class Trace {
// currently called trace because log mean something else
// TODO trace: java code generation does not always work
private TraceSystem traceSystem;
private String module;
private String lineSeparator;
public static final String LOCK = "lock";
public static final String SETTING = "setting";
public static final String COMMAND = "command";
public static final String INDEX = "index";
public static final String SEQUENCE = "sequence";
public static final String CONSTRAINT = "constraint";
public static final String USER = "user";
public static final String TRIGGER = "trigger";
public static final String FUNCTION = "function";
public static final String JDBC = "jdbc";
public static final String FILE_LOCK = "fileLock";
public static final String TABLE = "table";
public static final String LOG = "log";
public static final String SCHEMA = "schema";
public static final String DATABASE = "database";
public static final String SESSION = "session";
public Trace(TraceSystem traceSystem, String module) {
this.traceSystem = traceSystem;
this.module = module;
this.lineSeparator = System.getProperty("line.separator");
}
public boolean info() {
return traceSystem.isEnabled(TraceSystem.INFO);
}
public boolean debug() {
return traceSystem.isEnabled(TraceSystem.DEBUG);
}
public void error(String s) {
traceSystem.write(TraceSystem.ERROR, module, s, null);
}
public void error(String s, Throwable t) {
traceSystem.write(TraceSystem.ERROR, module, s, t);
}
public void info(String s) {
traceSystem.write(TraceSystem.INFO, module, s, null);
}
public void debugCode(String java) {
traceSystem.write(TraceSystem.DEBUG, module, lineSeparator + "/**/" + java, null);
}
public void infoCode(String java) {
traceSystem.write(TraceSystem.INFO, module, lineSeparator + "/**/" + java, null);
}
public void infoSQL(String sql) {
sql = replaceNewline(sql);
if(sql.startsWith("/*")) {
sql = sql.substring(sql.indexOf("*/") + 2).trim();
}
traceSystem.write(TraceSystem.INFO, module, lineSeparator + "/*SQL*/" + sql, null);
}
private String replaceNewline(String s) {
if(s.indexOf('\r') < 0 && s.indexOf('\n') < 0) {
return s;
}
StringBuffer buff = new StringBuffer(s.length());
for(int i=0; i<s.length(); i++) {
char ch = s.charAt(i);
if(ch == '\r' || ch == '\n') {
ch = ' ';
}
buff.append(ch);
}
return buff.toString();
}
public void debug(String s) {
traceSystem.write(TraceSystem.DEBUG, module, s, null);
}
public void debug(String s, Throwable t) {
traceSystem.write(TraceSystem.DEBUG, module, s, t);
}
}
/*
* 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.message;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.sql.SQLException;
import org.h2.engine.Constants;
import org.h2.util.StringUtils;
/**
*
* @author tgdmuth6
*
*/
public class TraceObject {
public static final int CALLABLE_STATEMENT = 0, CONNECTION = 1, DATABASE_META_DATA = 2,
PREPARED_STATEMENT = 3, RESULT_SET = 4, RESULT_SET_META_DATA = 5,
SAVEPOINT = 6, SQL_EXCEPTION = 7, STATEMENT = 8, BLOB = 9, CLOB = 10,
PARAMETER_META_DATA = 11;
public static final int DATASOURCE = 12, XA_DATASOURCE = 13, XID = 14;
private static int LAST = XID + 1;
private Trace trace;
private static final int[] ID = new int[LAST];
private static final String[] PREFIX = {
"call", "conn", "dbMeta", "prep", "rs", "rsMeta", "sp", "ex", "stat", "blob", "clob", "pMeta",
"ds", "xads", "xid"
};
private int type, id;
protected void setTrace(Trace trace, int type, int id) {
this.trace = trace;
this.type = type;
this.id = id;
}
protected int getTraceId() {
return id;
}
/**
* INTERNAL
*/
public String toString() {
return PREFIX[type] + id ;
}
protected int getNextId(int type) {
return ID[type]++;
}
protected boolean debug() {
return trace.debug();
}
protected Trace getTrace() {
return trace;
}
protected void debugCodeAssign(String className, int type, int id) {
if(!trace.debug()) {
return;
}
trace.debugCode(className + " " + toString() + " = ");
}
protected void infoCodeAssign(String className, int type, int id) {
if(!trace.info()) {
return;
}
trace.infoCode(className + " " + toString() + " = ");
}
protected void debugCodeCall(String text) {
if(!trace.debug()) {
return;
}
trace.debugCode(toString() + "." + text + "();");
}
protected void debugCodeCall(String text, long param) {
if(!trace.debug()) {
return;
}
trace.debugCode(toString() + "." + text + "("+param+");");
}
protected void debugCodeCall(String text, String param) {
if(!trace.debug()) {
return;
}
trace.debugCode(toString() + "." + text + "("+quote(param)+");");
}
protected void debugCode(String text) {
if(!trace.debug()) {
return;
}
trace.debugCode(toString() + "." + text);
}
protected String quote(String s) {
return StringUtils.quoteJavaString(s);
}
protected String quoteTime(java.sql.Time x) {
if(x == null) {
return "null";
}
return "Time.valueOf(\"" + x.toString() + "\")";
}
protected String quoteTimestamp(java.sql.Timestamp x) {
if(x == null) {
return "null";
}
return "Timestamp.valueOf(\"" + x.toString() + "\")";
}
protected String quoteDate(java.sql.Date x) {
if(x == null) {
return "null";
}
return "Date.valueOf(\"" + x.toString() + "\")";
}
protected String quoteBigDecimal(BigDecimal x) {
if(x == null) {
return "null";
}
return "new BigDecimal(\"" + x.toString() + "\")";
}
protected String quoteBytes(byte[] x) {
if(x == null) {
return "null";
}
return "new byte[" + x.length + "]";
}
protected String quoteArray(String[] s) {
return StringUtils.quoteJavaStringArray(s);
}
protected String quoteIntArray(int[] s) {
return StringUtils.quoteJavaIntArray(s);
}
protected SQLException logAndConvert(Throwable e) {
if(Constants.LOG_ALL_ERRORS) {
synchronized(this.getClass()) {
// e.printStackTrace();
try {
FileWriter writer = new FileWriter("c:\\temp\\h2error.txt", true);
PrintWriter p = new PrintWriter(writer);
e.printStackTrace(p);
p.close();
writer.close();
} catch(IOException e2) {
e2.printStackTrace();
}
}
}
if(trace == null) {
TraceSystem.traceThrowable(e);
} else {
if(e instanceof SQLException) {
trace.error("SQLException", e);
return (SQLException)e;
} else {
trace.error("Uncaught Exception", e);
}
}
return Message.convert(e);
}
}
/*
* 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.message;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import org.h2.engine.Constants;
import org.h2.util.FileUtils;
/**
* It is possible to write after close was called, but that means for each write the
* log file will be opened and closed again (which is slower).
*
* @author Thomas
*/
public class TraceSystem {
public static final int OFF = 0, ERROR = 1, INFO = 2, DEBUG = 3;
// TODO log total and free memory from time to time
// max file size is currently 64 MB,
// and then there could be a .old file of the same size
private static final int DEFAULT_MAX_FILE_SIZE = 64 * 1024 * 1024;
public static final int DEFAULT_TRACE_LEVEL_SYSTEM_OUT = OFF;
public static final int DEFAULT_TRACE_LEVEL_FILE = ERROR;
private static final int CHECK_FILE_TIME = 4000;
private int levelSystemOut = DEFAULT_TRACE_LEVEL_SYSTEM_OUT;
private int levelFile = DEFAULT_TRACE_LEVEL_FILE;
private int maxFileSize = DEFAULT_MAX_FILE_SIZE;
private String fileName;
private long lastCheck;
private HashMap traces;
private SimpleDateFormat dateFormat;
private FileWriter fileWriter;
private PrintWriter printWriter;
private static final int CHECK_SIZE_EACH_WRITES = 128;
private int checkSize;
private boolean closed;
public static void traceThrowable(Throwable e) {
PrintWriter writer = DriverManager.getLogWriter();
if(writer != null) {
e.printStackTrace(writer);
}
}
public TraceSystem(String fileName) {
this.fileName = fileName;
traces = new HashMap();
dateFormat = new SimpleDateFormat("MM-dd HH:mm:ss ");
if(fileName != null) {
try {
openWriter();
} catch(Exception e) {
logWritingError(e);
}
}
}
public Trace getTrace(String module) {
Trace t = (Trace) traces.get(module);
if (t == null) {
t = new Trace(this, module);
traces.put(module, t);
}
return t;
}
public boolean isEnabled(int level) {
int max = Math.max(levelSystemOut, levelFile);
return level <= max;
}
public void setFileName(String name) {
this.fileName = name;
}
public void setMaxFileSize(int max) {
this.maxFileSize = max;
}
public int getMaxFileSize() {
return maxFileSize;
}
public void setLevelSystemOut(int l) {
levelSystemOut = l;
}
public int getLevelFile() {
return levelFile;
}
public int getLevelSystemOut() {
return levelSystemOut;
}
public void setLevelFile(int l) {
levelFile = l;
}
private String format(String module, String s) {
return dateFormat.format(new Date()) + module + ": " + s;
}
void write(int l, String module, String s, Throwable t) {
if (l <= levelSystemOut) {
System.out.println(format(module, s));
if (t != null && levelSystemOut == DEBUG) {
t.printStackTrace();
}
}
if (fileName != null) {
if (l > levelFile) {
long time = System.currentTimeMillis();
if (time > lastCheck + CHECK_FILE_TIME) {
String checkFile = fileName + Constants.SUFFIX_TRACE_START_FILE;
lastCheck = time;
if (FileUtils.exists(checkFile)) {
levelFile = DEBUG;
try {
FileUtils.delete(checkFile);
} catch (Exception e) {
// the file may be read only
}
}
}
}
if (l <= levelFile) {
writeFile(format(module, s), t);
}
}
}
private synchronized void writeFile(String s, Throwable t) {
try {
if(checkSize++ >= CHECK_SIZE_EACH_WRITES) {
checkSize = 0;
closeWriter();
if (maxFileSize > 0 && FileUtils.length(fileName) > maxFileSize) {
String old = fileName + ".old";
if (FileUtils.exists(old)) {
FileUtils.delete(old);
}
FileUtils.rename(fileName, old);
}
}
if(!openWriter()) {
return;
}
printWriter.println(s);
if (t != null) {
t.printStackTrace(printWriter);
}
printWriter.flush();
if(closed) {
closeWriter();
}
} catch (Exception e) {
logWritingError(e);
}
}
private void logWritingError(Exception e) {
// TODO translate trace messages
SQLException se = Message.getSQLException(Message.LOG_FILE_ERROR_1, new String[] { fileName }, e);
// print this error only once
fileName = null;
System.out.println(se);
se.printStackTrace();
}
private boolean openWriter() throws IOException {
if(printWriter == null) {
try {
FileUtils.createDirs(fileName);
if(FileUtils.exists(fileName) && FileUtils.isReadOnly(fileName)) {
// read only database: don't log error if the trace file can't be opened
return false;
}
fileWriter = FileUtils.openFileWriter(fileName, true);
printWriter = new PrintWriter(fileWriter, true);
} catch(SQLException e) {
return false;
}
}
return true;
}
private synchronized void closeWriter() {
if(printWriter != null) {
printWriter.flush();
printWriter.close();
printWriter = null;
}
if(fileWriter != null) {
try {
fileWriter.close();
} catch(IOException e) {
// ignore exception
}
fileWriter = null;
}
}
public void close() {
closeWriter();
closed = true;
}
public void finalize() {
if(!Constants.RUN_FINALIZERS) {
return;
}
close();
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论