/* */ package org.jboss.resource.adapter.jdbc;
/* */
/* */ import EDU.oswego.cs.dl.util.concurrent.SynchronizedBoolean;
/* */ import java.io.PrintWriter;
/* */ import java.sql.CallableStatement;
/* */ import java.sql.Connection;
/* */ import java.sql.PreparedStatement;
/* */ import java.sql.SQLException;
/* */ import java.sql.Savepoint;
/* */ import java.sql.Statement;
/* */ import java.util.ArrayList;
/* */ import java.util.Collection;
/* */ import java.util.HashSet;
/* */ import java.util.Iterator;
/* */ import java.util.Properties;
/* */ import java.util.Set;
/* */ import javax.resource.ResourceException;
/* */ import javax.resource.spi.ConnectionEvent;
/* */ import javax.resource.spi.ConnectionEventListener;
/* */ import javax.resource.spi.ConnectionRequestInfo;
/* */ import javax.resource.spi.ManagedConnection;
/* */ import javax.resource.spi.ManagedConnectionMetaData;
/* */ import javax.resource.spi.ResourceAdapterInternalException;
/* */ import javax.security.auth.Subject;
/* */ import org.jboss.logging.Logger;
/* */ import org.jboss.resource.JBossResourceException;
/* */
/* */ public abstract class BaseWrapperManagedConnection
/* */ implements ManagedConnection
/* */ {
/* */ private static final WrappedConnectionFactory wrappedConnectionFactory;
/* */ protected final BaseWrapperManagedConnectionFactory mcf;
/* */ protected final Connection con;
/* */ protected final Properties props;
/* */ private final int transactionIsolation;
/* */ private final boolean readOnly;
/* 75 */ private final Collection cels = new ArrayList();
/* */
/* 77 */ private final Set handles = new HashSet();
/* */
/* 79 */ private PreparedStatementCache psCache = null;
/* */
/* 81 */ protected final Object stateLock = new Object();
/* */
/* 83 */ protected boolean inManagedTransaction = false;
/* */
/* 85 */ protected SynchronizedBoolean inLocalTransaction = new SynchronizedBoolean(false);
/* */
/* 87 */ protected boolean jdbcAutoCommit = true;
/* */
/* 89 */ protected boolean underlyingAutoCommit = true;
/* */ protected boolean jdbcReadOnly;
/* */ protected boolean underlyingReadOnly;
/* */ protected int jdbcTransactionIsolation;
/* 97 */ protected boolean destroyed = false;
/* */
/* */ public BaseWrapperManagedConnection(BaseWrapperManagedConnectionFactory mcf, Connection con, Properties props, int transactionIsolation, int psCacheSize)
/* */ throws SQLException
/* */ {
/* 130 */ this.mcf = mcf;
/* 131 */ this.con = con;
/* 132 */ this.props = props;
/* */
/* 134 */ if (psCacheSize > 0) {
/* 135 */ this.psCache = new PreparedStatementCache(psCacheSize);
/* */ }
/* 137 */ if (transactionIsolation == -1) {
/* 138 */ this.transactionIsolation = con.getTransactionIsolation();
/* */ }
/* */ else
/* */ {
/* 142 */ this.transactionIsolation = transactionIsolation;
/* 143 */ con.setTransactionIsolation(transactionIsolation);
/* */ }
/* */
/* 146 */ this.readOnly = con.isReadOnly();
/* */
/* 148 */ if (mcf.getNewConnectionSQL() != null)
/* */ {
/* 150 */ Statement s = con.createStatement();
/* */ try
/* */ {
/* 153 */ s.execute(mcf.getNewConnectionSQL());
/* */ }
/* */ finally
/* */ {
/* 157 */ s.close();
/* */ }
/* */ }
/* */
/* 161 */ this.underlyingReadOnly = this.readOnly;
/* 162 */ this.jdbcReadOnly = this.readOnly;
/* 163 */ this.jdbcTransactionIsolation = this.transactionIsolation;
/* */ }
/* */
/* */ public void addConnectionEventListener(ConnectionEventListener cel)
/* */ {
/* 168 */ synchronized (this.cels)
/* */ {
/* 170 */ this.cels.add(cel);
/* */ }
/* */ }
/* */
/* */ public void removeConnectionEventListener(ConnectionEventListener cel)
/* */ {
/* 176 */ synchronized (this.cels)
/* */ {
/* 178 */ this.cels.remove(cel);
/* */ }
/* */ }
/* */
/* */ public void associateConnection(Object handle) throws ResourceException
/* */ {
/* 184 */ if (!(handle instanceof WrappedConnection))
/* 185 */ throw new JBossResourceException("Wrong kind of connection handle to associate" + handle);
/* 186 */ ((WrappedConnection)handle).setManagedConnection(this);
/* 187 */ synchronized (this.handles)
/* */ {
/* 189 */ this.handles.add(handle);
/* */ }
/* */ }
/* */
/* */ public PrintWriter getLogWriter()
/* */ throws ResourceException
/* */ {
/* 196 */ return null;
/* */ }
/* */
/* */ public ManagedConnectionMetaData getMetaData()
/* */ throws ResourceException
/* */ {
/* 202 */ return null;
/* */ }
/* */
/* */ public void setLogWriter(PrintWriter param1)
/* */ throws ResourceException
/* */ {
/* */ }
/* */
/* */ public void cleanup() throws ResourceException
/* */ {
/* 212 */ synchronized (this.handles)
/* */ {
/* 214 */ for (Iterator i = this.handles.iterator(); i.hasNext(); )
/* */ {
/* 216 */ WrappedConnection lc = (WrappedConnection)i.next();
/* 217 */ lc.setManagedConnection(null);
/* */ }
/* 219 */ this.handles.clear();
/* */ }
/* */
/* 222 */ synchronized (this.stateLock)
/* */ {
/* 224 */ this.jdbcAutoCommit = true;
/* 225 */ this.jdbcReadOnly = this.readOnly;
/* 226 */ if (this.jdbcTransactionIsolation != this.transactionIsolation)
/* */ {
/* */ try
/* */ {
/* 230 */ this.con.setTransactionIsolation(this.jdbcTransactionIsolation);
/* 231 */ this.jdbcTransactionIsolation = this.transactionIsolation;
/* */ }
/* */ catch (SQLException e)
/* */ {
/* 235 */ this.mcf.log.warn("Error resetting transaction isolation ", e);
/* */ }
/* */ }
/* */ }
/* */ }
/* */
/* */ public Object getConnection(Subject subject, ConnectionRequestInfo cri) throws ResourceException
/* */ {
/* 243 */ checkIdentity(subject, cri);
/* 244 */ WrappedConnection lc = wrappedConnectionFactory.createWrappedConnection(this);
/* 245 */ synchronized (this.handles)
/* */ {
/* 247 */ this.handles.add(lc);
/* */ }
/* 249 */ return lc;
/* */ }
/* */
/* */ public void destroy() throws ResourceException
/* */ {
/* 254 */ synchronized (this.stateLock)
/* */ {
/* 256 */ this.destroyed = true;
/* */ }
/* */
/* 259 */ cleanup();
/* */ try
/* */ {
/* 262 */ this.con.close();
/* */ }
/* */ catch (SQLException ignored)
/* */ {
/* 266 */ getLog().trace("Ignored error during close: ", ignored);
/* */ }
/* */ }
/* */
/* */ public boolean checkValid()
/* */ {
/* 272 */ SQLException e = this.mcf.isValidConnection(this.con);
/* */
/* 274 */ if (e == null)
/* */ {
/* 276 */ return true;
/* */ }
/* */
/* 279 */ getLog().warn("Destroying connection that is not valid, due to the following exception: " + this.con, e);
/* 280 */ broadcastConnectionError(e);
/* 281 */ return false;
/* */ }
/* */
/* */ public Properties getProperties()
/* */ {
/* 287 */ return this.props;
/* */ }
/* */
/* */ void closeHandle(WrappedConnection handle)
/* */ {
/* 293 */ synchronized (this.stateLock)
/* */ {
/* 295 */ if (this.destroyed) {
/* 296 */ return;
/* */ }
/* */ }
/* 299 */ synchronized (this.handles)
/* */ {
/* 301 */ this.handles.remove(handle);
/* */ }
/* 303 */ ConnectionEvent ce = new ConnectionEvent(this, 1);
/* 304 */ ce.setConnectionHandle(handle);
/* 305 */ Object copy = null;
/* 306 */ synchronized (this.cels)
/* */ {
/* 308 */ copy = new ArrayList(this.cels);
/* */ }
/* 310 */ for (Iterator i = ((Collection)copy).iterator(); i.hasNext(); )
/* */ {
/* 312 */ ConnectionEventListener cel = (ConnectionEventListener)i.next();
/* 313 */ cel.connectionClosed(ce);
/* */ }
/* */ }
/* */
/* */ Throwable connectionError(Throwable t)
/* */ {
/* 319 */ if ((t instanceof SQLException))
/* */ {
/* 321 */ if (this.mcf.isStaleConnection((SQLException)t))
/* */ {
/* 323 */ t = new StaleConnectionException((SQLException)t);
/* */ }
/* 327 */ else if (this.mcf.isExceptionFatal((SQLException)t))
/* */ {
/* 329 */ broadcastConnectionError(t);
/* */ }
/* */
/* */ }
/* */ else
/* */ {
/* 336 */ broadcastConnectionError(t);
/* */ }
/* */
/* 339 */ return t;
/* */ }
/* */
/* */ protected void broadcastConnectionError(Throwable e)
/* */ {
/* 345 */ synchronized (this.stateLock)
/* */ {
/* 347 */ if (this.destroyed)
/* */ {
/* 349 */ Logger log = getLog();
/* 350 */ if (log.isTraceEnabled())
/* 351 */ log.trace("Not broadcasting error, already destroyed " + this, e);
/* 352 */ return;
/* */ }
/* */ }
/* */
/* 356 */ Exception ex = null;
/* 357 */ if ((e instanceof Exception))
/* 358 */ ex = (Exception)e;
/* */ else
/* 360 */ ex = new ResourceAdapterInternalException("Unexpected error", e);
/* 361 */ ConnectionEvent ce = new ConnectionEvent(this, 5, ex);
/* 362 */ Object copy = null;
/* 363 */ synchronized (this.cels)
/* */ {
/* 365 */ copy = new ArrayList(this.cels);
/* */ }
/* 367 */ for (Iterator i = ((Collection)copy).iterator(); i.hasNext(); )
/* */ {
/* 369 */ ConnectionEventListener cel = (ConnectionEventListener)i.next();
/* */ try
/* */ {
/* 372 */ cel.connectionErrorOccurred(ce);
/* */ }
/* */ catch (Throwable t)
/* */ {
/* 376 */ getLog().warn("Error notifying of connection error for listener: " + cel, t);
/* */ }
/* */ }
/* */ }
/* */
/* */ Connection getConnection() throws SQLException
/* */ {
/* 383 */ if (this.con == null)
/* 384 */ throw new SQLException("Connection has been destroyed!!!");
/* 385 */ return this.con;
/* */ }
/* */
/* */ PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException
/* */ {
/* 390 */ if (this.psCache != null)
/* */ {
/* 392 */ PreparedStatementCache.Key key = new PreparedStatementCache.Key(sql, 1, resultSetType, resultSetConcurrency);
/* */
/* 394 */ CachedPreparedStatement cachedps = (CachedPreparedStatement)this.psCache.get(key);
/* 395 */ if (cachedps != null)
/* */ {
/* 397 */ if (canUse(cachedps))
/* 398 */ cachedps.inUse();
/* */ else
/* 400 */ return doPrepareStatement(sql, resultSetType, resultSetConcurrency);
/* */ }
/* */ else
/* */ {
/* 404 */ PreparedStatement ps = doPrepareStatement(sql, resultSetType, resultSetConcurrency);
/* 405 */ cachedps = wrappedConnectionFactory.createCachedPreparedStatement(ps);
/* 406 */ this.psCache.insert(key, cachedps);
/* */ }
/* 408 */ return cachedps;
/* */ }
/* */
/* 411 */ return doPrepareStatement(sql, resultSetType, resultSetConcurrency);
/* */ }
/* */
/* */ PreparedStatement doPrepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException
/* */ {
/* 416 */ return this.con.prepareStatement(sql, resultSetType, resultSetConcurrency);
/* */ }
/* */
/* */ CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException
/* */ {
/* 421 */ if (this.psCache != null)
/* */ {
/* 423 */ PreparedStatementCache.Key key = new PreparedStatementCache.Key(sql, 2, resultSetType, resultSetConcurrency);
/* */
/* 425 */ CachedCallableStatement cachedps = (CachedCallableStatement)this.psCache.get(key);
/* 426 */ if (cachedps != null)
/* */ {
/* 428 */ if (canUse(cachedps))
/* 429 */ cachedps.inUse();
/* */ else
/* 431 */ return doPrepareCall(sql, resultSetType, resultSetConcurrency);
/* */ }
/* */ else
/* */ {
/* 435 */ CallableStatement cs = doPrepareCall(sql, resultSetType, resultSetConcurrency);
/* 436 */ cachedps = wrappedConnectionFactory.createCachedCallableStatement(cs);
/* 437 */ this.psCache.insert(key, cachedps);
/* */ }
/* 439 */ return cachedps;
/* */ }
/* */
/* 442 */ return doPrepareCall(sql, resultSetType, resultSetConcurrency);
/* */ }
/* */
/* */ CallableStatement doPrepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException
/* */ {
/* 447 */ return this.con.prepareCall(sql, resultSetType, resultSetConcurrency);
/* */ }
/* */
/* */ boolean canUse(CachedPreparedStatement cachedps)
/* */ {
/* 453 */ if (!cachedps.isInUse()) {
/* 454 */ return true;
/* */ }
/* */
/* 458 */ if (this.underlyingAutoCommit == true) {
/* 459 */ return false;
/* */ }
/* */
/* 462 */ return this.mcf.sharePS;
/* */ }
/* */
/* */ protected Logger getLog()
/* */ {
/* 467 */ return this.mcf.log;
/* */ }
/* */
/* */ private void checkIdentity(Subject subject, ConnectionRequestInfo cri) throws ResourceException
/* */ {
/* 472 */ Properties newProps = this.mcf.getConnectionProperties(subject, cri);
/* 473 */ if (!this.props.equals(newProps))
/* */ {
/* 475 */ throw new JBossResourceException("Wrong credentials passed to getConnection!");
/* */ }
/* */ }
/* */
/* */ void checkTransaction()
/* */ throws SQLException
/* */ {
/* 488 */ synchronized (this.stateLock)
/* */ {
/* 490 */ if (this.inManagedTransaction) {
/* 491 */ return;
/* */ }
/* */
/* 494 */ if (this.jdbcAutoCommit != this.underlyingAutoCommit)
/* */ {
/* 496 */ this.con.setAutoCommit(this.jdbcAutoCommit);
/* 497 */ this.underlyingAutoCommit = this.jdbcAutoCommit;
/* */ }
/* */ }
/* */
/* 501 */ if ((!this.jdbcAutoCommit) && (!this.inLocalTransaction.set(true)))
/* */ {
/* */ ArrayList copy;
/* 504 */ synchronized (this.cels)
/* */ {
/* 506 */ copy = new ArrayList(this.cels);
/* */ }
/* 508 */ ConnectionEvent ce = new ConnectionEvent(this, 2);
/* 509 */ for (int i = 0; i < copy.size(); i++)
/* */ {
/* 511 */ ConnectionEventListener cel = (ConnectionEventListener)copy.get(i);
/* */ try
/* */ {
/* 514 */ cel.localTransactionStarted(ce);
/* */ }
/* */ catch (Throwable t)
/* */ {
/* 518 */ getLog().trace("Error notifying of connection committed for listener: " + cel, t);
/* */ }
/* */ }
/* */ }
/* */
/* 523 */ checkState();
/* */ }
/* */
/* */ protected void checkState() throws SQLException
/* */ {
/* 528 */ synchronized (this.stateLock)
/* */ {
/* 531 */ if (this.jdbcReadOnly != this.underlyingReadOnly)
/* */ {
/* 533 */ this.con.setReadOnly(this.jdbcReadOnly);
/* 534 */ this.underlyingReadOnly = this.jdbcReadOnly;
/* */ }
/* */ }
/* */ }
/* */
/* */ boolean isJdbcAutoCommit()
/* */ {
/* 541 */ return this.inManagedTransaction ? false : this.jdbcAutoCommit;
/* */ }
/* */
/* */ void setJdbcAutoCommit(boolean jdbcAutoCommit) throws SQLException
/* */ {
/* 546 */ synchronized (this.stateLock)
/* */ {
/* 548 */ if (this.inManagedTransaction)
/* 549 */ throw new SQLException("You cannot set autocommit during a managed transaction!");
/* 550 */ this.jdbcAutoCommit = jdbcAutoCommit;
/* */ }
/* */
/* 553 */ if ((jdbcAutoCommit) && (this.inLocalTransaction.set(false)))
/* */ {
/* */ ArrayList copy;
/* 556 */ synchronized (this.cels)
/* */ {
/* 558 */ copy = new ArrayList(this.cels);
/* */ }
/* 560 */ ConnectionEvent ce = new ConnectionEvent(this, 3);
/* 561 */ for (int i = 0; i < copy.size(); i++)
/* */ {
/* 563 */ ConnectionEventListener cel = (ConnectionEventListener)copy.get(i);
/* */ try
/* */ {
/* 566 */ cel.localTransactionCommitted(ce);
/* */ }
/* */ catch (Throwable t)
/* */ {
/* 570 */ getLog().trace("Error notifying of connection committed for listener: " + cel, t);
/* */ }
/* */ }
/* */ }
/* */ }
/* */
/* */ boolean isJdbcReadOnly()
/* */ {
/* 578 */ return this.jdbcReadOnly;
/* */ }
/* */
/* */ void setJdbcReadOnly(boolean readOnly) throws SQLException
/* */ {
/* 583 */ synchronized (this.stateLock)
/* */ {
/* 585 */ if (this.inManagedTransaction)
/* 586 */ throw new SQLException("You cannot set read only during a managed transaction!");
/* 587 */ this.jdbcReadOnly = readOnly;
/* */ }
/* */ }
/* */
/* */ int getJdbcTransactionIsolation()
/* */ {
/* 593 */ return this.jdbcTransactionIsolation;
/* */ }
/* */
/* */ void setJdbcTransactionIsolation(int isolationLevel) throws SQLException
/* */ {
/* 598 */ synchronized (this.stateLock)
/* */ {
/* 600 */ this.jdbcTransactionIsolation = isolationLevel;
/* 601 */ this.con.setTransactionIsolation(this.jdbcTransactionIsolation);
/* */ }
/* */ }
/* */
/* */ void jdbcCommit() throws SQLException
/* */ {
/* 607 */ synchronized (this.stateLock)
/* */ {
/* 609 */ if (this.inManagedTransaction)
/* 610 */ throw new SQLException("You cannot commit during a managed transaction!");
/* 611 */ if (this.jdbcAutoCommit)
/* 612 */ throw new SQLException("You cannot commit with autocommit set!");
/* */ }
/* 614 */ this.con.commit();
/* */
/* 616 */ if (this.inLocalTransaction.set(false))
/* */ {
/* */ ArrayList copy;
/* 619 */ synchronized (this.cels)
/* */ {
/* 621 */ copy = new ArrayList(this.cels);
/* */ }
/* 623 */ ConnectionEvent ce = new ConnectionEvent(this, 3);
/* 624 */ for (int i = 0; i < copy.size(); i++)
/* */ {
/* 626 */ ConnectionEventListener cel = (ConnectionEventListener)copy.get(i);
/* */ try
/* */ {
/* 629 */ cel.localTransactionCommitted(ce);
/* */ }
/* */ catch (Throwable t)
/* */ {
/* 633 */ getLog().trace("Error notifying of connection committed for listener: " + cel, t);
/* */ }
/* */ }
/* */ }
/* */ }
/* */
/* */ void jdbcRollback() throws SQLException
/* */ {
/* 641 */ synchronized (this.stateLock)
/* */ {
/* 643 */ if (this.inManagedTransaction)
/* 644 */ throw new SQLException("You cannot rollback during a managed transaction!");
/* 645 */ if (this.jdbcAutoCommit)
/* 646 */ throw new SQLException("You cannot rollback with autocommit set!");
/* */ }
/* 648 */ this.con.rollback();
/* */
/* 650 */ if (this.inLocalTransaction.set(false))
/* */ {
/* */ ArrayList copy;
/* 653 */ synchronized (this.cels)
/* */ {
/* 655 */ copy = new ArrayList(this.cels);
/* */ }
/* 657 */ ConnectionEvent ce = new ConnectionEvent(this, 4);
/* 658 */ for (int i = 0; i < copy.size(); i++)
/* */ {
/* 660 */ ConnectionEventListener cel = (ConnectionEventListener)copy.get(i);
/* */ try
/* */ {
/* 663 */ cel.localTransactionRolledback(ce);
/* */ }
/* */ catch (Throwable t)
/* */ {
/* 667 */ getLog().trace("Error notifying of connection rollback for listener: " + cel, t);
/* */ }
/* */ }
/* */ }
/* */ }
/* */
/* */ void jdbcRollback(Savepoint savepoint) throws SQLException
/* */ {
/* 675 */ synchronized (this.stateLock)
/* */ {
/* 677 */ if (this.inManagedTransaction)
/* 678 */ throw new SQLException("You cannot rollback during a managed transaction!");
/* 679 */ if (this.jdbcAutoCommit)
/* 680 */ throw new SQLException("You cannot rollback with autocommit set!");
/* */ }
/* 682 */ this.con.rollback(savepoint);
/* */ }
/* */
/* */ int getTrackStatements()
/* */ {
/* 687 */ return this.mcf.trackStatements;
/* */ }
/* */
/* */ boolean isTransactionQueryTimeout()
/* */ {
/* 692 */ return this.mcf.isTransactionQueryTimeout;
/* */ }
/* */
/* */ int getQueryTimeout()
/* */ {
/* 697 */ return this.mcf.getQueryTimeout();
/* */ }
/* */
/* */ protected void checkException(SQLException e) throws ResourceException
/* */ {
/* 702 */ connectionError(e);
/* 703 */ throw new JBossResourceException("SQLException", e);
/* */ }
/* */
/* */ static
/* */ {
/* 101 */ Class connectionFactory = null;
/* */ try
/* */ {
/* 104 */ BaseWrapperManagedConnection.class; connectionFactory = Class.forName("org.jboss.resource.adapter.jdbc.jdk6.WrappedConnectionFactoryJDK6");
/* */ }
/* */ catch (ClassNotFoundException e)
/* */ {
/* */ try
/* */ {
/* 110 */ BaseWrapperManagedConnection.class; connectionFactory = Class.forName("org.jboss.resource.adapter.jdbc.jdk5.WrappedConnectionFactoryJDK5");
/* */ }
/* */ catch (ClassNotFoundException ex)
/* */ {
/* 114 */ throw new RuntimeException("Unabled to load wrapped connection factory", ex);
/* */ }
/* */ }
/* */ try
/* */ {
/* 119 */ wrappedConnectionFactory = (WrappedConnectionFactory)connectionFactory.newInstance();
/* */ }
/* */ catch (Exception e)
/* */ {
/* 123 */ throw new RuntimeException("Error initializign connection factory", e);
/* */ }
/* */ }
/* */ }
/* Location: /home/mnovotny/projects/EMBEDDED_JBOSS_BETA3_COMMUNITY/embedded/output/lib/embedded-jboss/lib/jboss-embedded-all.jar
* Qualified Name: org.jboss.resource.adapter.jdbc.BaseWrapperManagedConnection
* JD-Core Version: 0.6.0
*/