/*
* Copyright 2004-2015 the Seasar Foundation and the Others.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
package org.seasar.extension.dbcp.impl;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Savepoint;
import java.sql.Statement;
import java.util.Map;
import javax.sql.ConnectionEvent;
import javax.sql.ConnectionEventListener;
import javax.sql.XAConnection;
import javax.transaction.Transaction;
import javax.transaction.xa.XAResource;
import org.seasar.extension.dbcp.ConnectionPool;
import org.seasar.extension.dbcp.ConnectionWrapper;
import org.seasar.extension.jdbc.impl.PreparedStatementWrapper;
import org.seasar.framework.exception.SSQLException;
import org.seasar.framework.log.Logger;
/**
* {@link ConnectionWrapper}の実装クラスです。
*
* @author higa
*
*/
public class ConnectionWrapperImpl implements ConnectionWrapper,
ConnectionEventListener {
private static final Logger logger_ = Logger
.getLogger(ConnectionWrapperImpl.class);
private XAConnection xaConnection_;
private Connection physicalConnection_;
private XAResource xaResource_;
private ConnectionPool connectionPool_;
private boolean closed_ = false;
private Transaction tx_;
/**
* {@link ConnectionWrapperImpl}を作成します。
*
* @param xaConnection
* XAコネクション
* @param physicalConnection
* 物理コネクション
* @param connectionPool
* コネクションプール
* @param tx
* トランザクション
* @throws SQLException
* SQL例外が発生した場合
*/
public ConnectionWrapperImpl(final XAConnection xaConnection,
final Connection physicalConnection,
final ConnectionPool connectionPool, final Transaction tx)
throws SQLException {
xaConnection_ = xaConnection;
physicalConnection_ = physicalConnection;
xaResource_ = new XAResourceWrapperImpl(xaConnection.getXAResource(),
this);
connectionPool_ = connectionPool;
tx_ = tx;
xaConnection_.addConnectionEventListener(this);
}
public Connection getPhysicalConnection() {
return physicalConnection_;
}
public XAResource getXAResource() {
return xaResource_;
}
public XAConnection getXAConnection() {
return xaConnection_;
}
public void init(final Transaction tx) {
closed_ = false;
tx_ = tx;
}
public void cleanup() {
xaConnection_.removeConnectionEventListener(this);
closed_ = true;
xaConnection_ = null;
physicalConnection_ = null;
tx_ = null;
}
public void closeReally() {
if (xaConnection_ == null) {
return;
}
closed_ = true;
try {
if (!physicalConnection_.isClosed()) {
if (!physicalConnection_.getAutoCommit()) {
try {
physicalConnection_.rollback();
physicalConnection_.setAutoCommit(true);
} catch (final SQLException ex) {
logger_.log(ex);
}
}
physicalConnection_.close();
}
} catch (final SQLException ex) {
logger_.log(ex);
} finally {
physicalConnection_ = null;
}
try {
xaConnection_.close();
logger_.log("DSSR0001", null);
} catch (final SQLException ex) {
logger_.log(ex);
} finally {
xaConnection_ = null;
}
}
private void assertOpened() throws SQLException {
if (closed_) {
throw new SSQLException("ESSR0062", null);
}
}
private void assertLocalTx() throws SQLException {
if (tx_ != null) {
throw new SSQLException("ESSR0366", null);
}
}
public void release() throws SQLException {
if (!closed_) {
connectionPool_.release(this);
}
}
public void connectionClosed(final ConnectionEvent event) {
}
public void connectionErrorOccurred(final ConnectionEvent event) {
try {
release();
} catch (final SQLException ignore) {
}
}
public Statement createStatement() throws SQLException {
assertOpened();
try {
return physicalConnection_.createStatement();
} catch (final SQLException ex) {
release();
throw ex;
}
}
public PreparedStatement prepareStatement(final String sql)
throws SQLException {
assertOpened();
try {
return new PreparedStatementWrapper(physicalConnection_
.prepareStatement(sql), sql);
} catch (final SQLException ex) {
release();
throw wrapException(ex, sql);
}
}
public CallableStatement prepareCall(final String sql) throws SQLException {
assertOpened();
try {
return physicalConnection_.prepareCall(sql);
} catch (final SQLException ex) {
release();
throw wrapException(ex, sql);
}
}
public String nativeSQL(final String sql) throws SQLException {
assertOpened();
try {
return physicalConnection_.nativeSQL(sql);
} catch (final SQLException ex) {
release();
throw wrapException(ex, sql);
}
}
public boolean isClosed() throws SQLException {
return closed_;
}
public DatabaseMetaData getMetaData() throws SQLException {
assertOpened();
try {
return physicalConnection_.getMetaData();
} catch (final SQLException ex) {
release();
throw ex;
}
}
public void setReadOnly(final boolean readOnly) throws SQLException {
assertOpened();
try {
physicalConnection_.setReadOnly(readOnly);
} catch (final SQLException ex) {
release();
throw ex;
}
}
public boolean isReadOnly() throws SQLException {
assertOpened();
try {
return physicalConnection_.isReadOnly();
} catch (final SQLException ex) {
release();
throw ex;
}
}
public void setCatalog(final String catalog) throws SQLException {
assertOpened();
try {
physicalConnection_.setCatalog(catalog);
} catch (final SQLException ex) {
release();
throw ex;
}
}
public String getCatalog() throws SQLException {
assertOpened();
try {
return physicalConnection_.getCatalog();
} catch (final SQLException ex) {
release();
throw ex;
}
}
public void close() throws SQLException {
if (closed_) {
return;
}
if (logger_.isDebugEnabled()) {
logger_.log("DSSR0002", new Object[] { tx_ });
}
if (tx_ == null) {
connectionPool_.checkIn(this);
} else {
connectionPool_.checkInTx(tx_);
}
}
public void setTransactionIsolation(final int level) throws SQLException {
assertOpened();
try {
physicalConnection_.setTransactionIsolation(level);
} catch (final SQLException ex) {
release();
throw ex;
}
}
public int getTransactionIsolation() throws SQLException {
assertOpened();
try {
return physicalConnection_.getTransactionIsolation();
} catch (final SQLException ex) {
release();
throw ex;
}
}
public SQLWarning getWarnings() throws SQLException {
assertOpened();
try {
return physicalConnection_.getWarnings();
} catch (final SQLException ex) {
release();
throw ex;
}
}
public void clearWarnings() throws SQLException {
assertOpened();
try {
physicalConnection_.clearWarnings();
} catch (final SQLException ex) {
release();
throw ex;
}
}
public void commit() throws SQLException {
assertOpened();
assertLocalTx();
try {
physicalConnection_.commit();
} catch (final SQLException ex) {
release();
throw ex;
}
}
public void rollback() throws SQLException {
assertOpened();
assertLocalTx();
try {
physicalConnection_.rollback();
} catch (final SQLException ex) {
release();
throw ex;
}
}
public void setAutoCommit(final boolean autoCommit) throws SQLException {
assertOpened();
if (autoCommit) {
assertLocalTx();
}
try {
physicalConnection_.setAutoCommit(autoCommit);
} catch (final SQLException ex) {
release();
throw ex;
}
}
public boolean getAutoCommit() throws SQLException {
assertOpened();
try {
return physicalConnection_.getAutoCommit();
} catch (final SQLException ex) {
release();
throw ex;
}
}
public Statement createStatement(final int resultSetType,
final int resultSetConcurrency) throws SQLException {
assertOpened();
try {
return physicalConnection_.createStatement(resultSetType,
resultSetConcurrency);
} catch (final SQLException ex) {
release();
throw ex;
}
}
public Map getTypeMap() throws SQLException {
assertOpened();
try {
return physicalConnection_.getTypeMap();
} catch (final SQLException ex) {
release();
throw ex;
}
}
public void setTypeMap(final Map map) throws SQLException {
assertOpened();
try {
physicalConnection_.setTypeMap(map);
} catch (final SQLException ex) {
release();
throw ex;
}
}
public PreparedStatement prepareStatement(final String sql,
final int resultSetType, final int resultSetConcurrency)
throws SQLException {
assertOpened();
try {
return new PreparedStatementWrapper(
physicalConnection_.prepareStatement(sql, resultSetType,
resultSetConcurrency), sql);
} catch (final SQLException ex) {
release();
throw wrapException(ex, sql);
}
}
public CallableStatement prepareCall(final String sql,
final int resultSetType, final int resultSetConcurrency)
throws SQLException {
assertOpened();
try {
return physicalConnection_.prepareCall(sql, resultSetType,
resultSetConcurrency);
} catch (final SQLException ex) {
release();
throw wrapException(ex, sql);
}
}
public void setHoldability(final int holdability) throws SQLException {
assertOpened();
try {
physicalConnection_.setHoldability(holdability);
} catch (final SQLException ex) {
release();
throw ex;
}
}
public int getHoldability() throws SQLException {
assertOpened();
try {
return physicalConnection_.getHoldability();
} catch (final SQLException ex) {
release();
throw ex;
}
}
public Savepoint setSavepoint() throws SQLException {
assertOpened();
assertLocalTx();
try {
return physicalConnection_.setSavepoint();
} catch (final SQLException ex) {
release();
throw ex;
}
}
public Savepoint setSavepoint(final String name) throws SQLException {
assertOpened();
assertLocalTx();
try {
return physicalConnection_.setSavepoint(name);
} catch (final SQLException ex) {
release();
throw ex;
}
}
public void rollback(final Savepoint savepoint) throws SQLException {
assertOpened();
assertLocalTx();
try {
physicalConnection_.rollback(savepoint);
} catch (final SQLException ex) {
release();
throw ex;
}
}
public void releaseSavepoint(final Savepoint savepoint) throws SQLException {
assertOpened();
assertLocalTx();
try {
physicalConnection_.releaseSavepoint(savepoint);
} catch (final SQLException ex) {
release();
throw ex;
}
}
public Statement createStatement(final int resultSetType,
final int resultSetConcurrency, final int resultSetHoldability)
throws SQLException {
assertOpened();
try {
return physicalConnection_.createStatement(resultSetType,
resultSetConcurrency, resultSetHoldability);
} catch (final SQLException ex) {
release();
throw ex;
}
}
public PreparedStatement prepareStatement(final String sql,
final int resultSetType, final int resultSetConcurrency,
final int resultSetHoldability) throws SQLException {
assertOpened();
try {
return new PreparedStatementWrapper(physicalConnection_
.prepareStatement(sql, resultSetType, resultSetConcurrency,
resultSetHoldability), sql);
} catch (final SQLException ex) {
release();
throw wrapException(ex, sql);
}
}
public CallableStatement prepareCall(final String sql,
final int resultSetType, final int resultSetConcurrency,
final int resultSetHoldability) throws SQLException {
assertOpened();
try {
return physicalConnection_.prepareCall(sql, resultSetType,
resultSetConcurrency, resultSetHoldability);
} catch (final SQLException ex) {
release();
throw wrapException(ex, sql);
}
}
public PreparedStatement prepareStatement(final String sql,
final int autoGeneratedKeys) throws SQLException {
assertOpened();
try {
return new PreparedStatementWrapper(physicalConnection_
.prepareStatement(sql, autoGeneratedKeys), sql);
} catch (final SQLException ex) {
release();
throw wrapException(ex, sql);
}
}
public PreparedStatement prepareStatement(final String sql,
final int[] columnIndexes) throws SQLException {
assertOpened();
try {
return new PreparedStatementWrapper(physicalConnection_
.prepareStatement(sql, columnIndexes), sql);
} catch (final SQLException ex) {
release();
throw wrapException(ex, sql);
}
}
public PreparedStatement prepareStatement(final String sql,
final String[] columnNames) throws SQLException {
assertOpened();
try {
return new PreparedStatementWrapper(physicalConnection_
.prepareStatement(sql, columnNames), sql);
} catch (final SQLException ex) {
release();
throw wrapException(ex, sql);
}
}
private SQLException wrapException(final SQLException e, final String sql) {
return new SSQLException("ESSR0072",
new Object[] { sql, e.getMessage(),
new Integer(e.getErrorCode()), e.getSQLState() }, e
.getSQLState(), e.getErrorCode(), e, sql);
}
}