Coverage Report - org.mule.transport.jdbc.xa.ConnectionWrapper
 
Classes in this File Line Coverage Branch Coverage Complexity
ConnectionWrapper
0%
0/133
0%
0/28
0
 
 1  
 /*
 2  
  * $Id: ConnectionWrapper.java 20322 2010-11-24 16:15:31Z epere4 $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 
 11  
 package org.mule.transport.jdbc.xa;
 12  
 
 13  
 import org.mule.api.transaction.Transaction;
 14  
 import org.mule.api.transaction.TransactionException;
 15  
 import org.mule.config.i18n.CoreMessages;
 16  
 import org.mule.transaction.IllegalTransactionStateException;
 17  
 import org.mule.transaction.TransactionCoordination;
 18  
 import org.mule.transaction.XaTransaction;
 19  
 
 20  
 import java.lang.reflect.Proxy;
 21  
 import java.sql.Array;
 22  
 import java.sql.Blob;
 23  
 import java.sql.CallableStatement;
 24  
 import java.sql.Clob;
 25  
 import java.sql.Connection;
 26  
 import java.sql.DatabaseMetaData;
 27  
 import java.sql.NClob;
 28  
 import java.sql.PreparedStatement;
 29  
 import java.sql.SQLClientInfoException;
 30  
 import java.sql.SQLException;
 31  
 import java.sql.SQLWarning;
 32  
 import java.sql.SQLXML;
 33  
 import java.sql.Savepoint;
 34  
 import java.sql.Statement;
 35  
 import java.sql.Struct;
 36  
 import java.util.Map;
 37  
 import java.util.Properties;
 38  
 
 39  
 import javax.sql.XAConnection;
 40  
 import javax.transaction.xa.XAResource;
 41  
 
 42  
 import org.apache.commons.logging.Log;
 43  
 import org.apache.commons.logging.LogFactory;
 44  
 
 45  
 /**
 46  
  * Using for unification XAConnection and Connection
 47  
  */
 48  
 public class ConnectionWrapper implements Connection, XaTransaction.MuleXaObject
 49  
 {
 50  
     private final XAConnection xaConnection;
 51  
     private Connection connection;
 52  
 
 53  
     /**
 54  
      * This is the lock object that guards access to {@link #enlistedXAResource}.
 55  
      */
 56  0
     private final Object enlistedXAResourceLock = new Object();
 57  
     /**
 58  
      * @GuardedBy {@link #enlistedXAResourceLock}
 59  
      */
 60  
     private XAResource enlistedXAResource;
 61  
 
 62  0
     protected static final transient Log logger = LogFactory.getLog(ConnectionWrapper.class);
 63  0
     private volatile boolean reuseObject = false;
 64  
 
 65  
     public ConnectionWrapper(XAConnection xaCon) throws SQLException
 66  0
     {
 67  0
         this.xaConnection = xaCon;
 68  0
         this.connection = xaCon.getConnection();
 69  0
     }
 70  
 
 71  
     public int getHoldability() throws SQLException
 72  
     {
 73  0
         return connection.getHoldability();
 74  
     }
 75  
 
 76  
     public int getTransactionIsolation() throws SQLException
 77  
     {
 78  0
         return connection.getTransactionIsolation();
 79  
     }
 80  
 
 81  
     public void clearWarnings() throws SQLException
 82  
     {
 83  0
         connection.clearWarnings();
 84  0
     }
 85  
 
 86  
     public void close() throws SQLException
 87  
     {
 88  0
         connection.close();
 89  
         try
 90  
         {
 91  0
             xaConnection.close();
 92  
         }
 93  0
         catch (SQLException e)
 94  
         {
 95  0
             logger.info(
 96  
                 "Exception while explicitely closing the xaConnection (some providers require this). "
 97  
                                 + "The exception will be ignored and only logged: " + e.getMessage(), e);
 98  0
         }
 99  0
     }
 100  
 
 101  
     public void commit() throws SQLException
 102  
     {
 103  0
         connection.commit();
 104  0
     }
 105  
 
 106  
     public void rollback() throws SQLException
 107  
     {
 108  0
         connection.rollback();
 109  0
     }
 110  
 
 111  
     public boolean getAutoCommit() throws SQLException
 112  
     {
 113  0
         return connection.getAutoCommit();
 114  
     }
 115  
 
 116  
     public boolean isClosed() throws SQLException
 117  
     {
 118  0
         return connection.isClosed();
 119  
     }
 120  
 
 121  
     public boolean isReadOnly() throws SQLException
 122  
     {
 123  0
         return connection.isReadOnly();
 124  
     }
 125  
 
 126  
     public void setHoldability(int holdability) throws SQLException
 127  
     {
 128  0
         connection.setHoldability(holdability);
 129  0
     }
 130  
 
 131  
     public void setTransactionIsolation(int level) throws SQLException
 132  
     {
 133  0
         connection.setTransactionIsolation(level);
 134  0
     }
 135  
 
 136  
     public void setAutoCommit(boolean autoCommit) throws SQLException
 137  
     {
 138  0
         connection.setAutoCommit(autoCommit);
 139  0
     }
 140  
 
 141  
     public void setReadOnly(boolean readOnly) throws SQLException
 142  
     {
 143  0
         connection.setReadOnly(readOnly);
 144  0
     }
 145  
 
 146  
     public String getCatalog() throws SQLException
 147  
     {
 148  0
         return connection.getCatalog();
 149  
     }
 150  
 
 151  
     public void setCatalog(String catalog) throws SQLException
 152  
     {
 153  0
         connection.setCatalog(catalog);
 154  0
     }
 155  
 
 156  
     public DatabaseMetaData getMetaData() throws SQLException
 157  
     {
 158  0
         return connection.getMetaData();
 159  
     }
 160  
 
 161  
     public SQLWarning getWarnings() throws SQLException
 162  
     {
 163  0
         return connection.getWarnings();
 164  
     }
 165  
 
 166  
     public Savepoint setSavepoint() throws SQLException
 167  
     {
 168  0
         return connection.setSavepoint();
 169  
     }
 170  
 
 171  
     public void releaseSavepoint(Savepoint savepoint) throws SQLException
 172  
     {
 173  0
         connection.releaseSavepoint(savepoint);
 174  0
     }
 175  
 
 176  
     public void rollback(Savepoint savepoint) throws SQLException
 177  
     {
 178  0
         connection.rollback();
 179  0
     }
 180  
 
 181  
     public Statement createStatement() throws SQLException
 182  
     {
 183  0
         Statement st = connection.createStatement();
 184  0
         return (Statement) Proxy.newProxyInstance(Statement.class.getClassLoader(),
 185  
                                                   new Class[]{Statement.class}, new StatementInvocationHandler(this, st));
 186  
     }
 187  
 
 188  
     public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException
 189  
     {
 190  0
         Statement st = connection.createStatement(resultSetType, resultSetConcurrency);
 191  0
         return (Statement) Proxy.newProxyInstance(Statement.class.getClassLoader(),
 192  
                                                   new Class[]{Statement.class}, new StatementInvocationHandler(this, st));
 193  
     }
 194  
 
 195  
     public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
 196  
             throws SQLException
 197  
     {
 198  0
         Statement st = connection.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
 199  0
         return (Statement) Proxy.newProxyInstance(Statement.class.getClassLoader(),
 200  
                                                   new Class[]{Statement.class}, new StatementInvocationHandler(this, st));
 201  
     }
 202  
 
 203  
     public Map getTypeMap() throws SQLException
 204  
     {
 205  0
         return connection.getTypeMap();
 206  
     }
 207  
 
 208  
     public void setTypeMap(Map<String, Class<?>> map) throws SQLException
 209  
     {
 210  0
         connection.setTypeMap(map);
 211  0
     }
 212  
 
 213  
     public String nativeSQL(String sql) throws SQLException
 214  
     {
 215  0
         return connection.nativeSQL(sql);
 216  
     }
 217  
 
 218  
     public CallableStatement prepareCall(String sql) throws SQLException
 219  
     {
 220  0
         CallableStatement cs = connection.prepareCall(sql);
 221  0
         return (CallableStatement) Proxy.newProxyInstance(CallableStatement.class.getClassLoader(),
 222  
                                                           new Class[]{CallableStatement.class}, new StatementInvocationHandler(this, cs));
 223  
     }
 224  
 
 225  
     public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency)
 226  
             throws SQLException
 227  
     {
 228  0
         CallableStatement cs = connection.prepareCall(sql, resultSetType, resultSetConcurrency);
 229  0
         return (CallableStatement) Proxy.newProxyInstance(CallableStatement.class.getClassLoader(),
 230  
                                                           new Class[]{CallableStatement.class}, new StatementInvocationHandler(this, cs));
 231  
     }
 232  
 
 233  
     public CallableStatement prepareCall(String sql,
 234  
                                          int resultSetType,
 235  
                                          int resultSetConcurrency,
 236  
                                          int resultSetHoldability) throws SQLException
 237  
     {
 238  0
         CallableStatement cs = connection.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
 239  0
         return (CallableStatement) Proxy.newProxyInstance(CallableStatement.class.getClassLoader(),
 240  
                                                           new Class[]{CallableStatement.class}, new StatementInvocationHandler(this, cs));
 241  
     }
 242  
 
 243  
     public PreparedStatement prepareStatement(String sql) throws SQLException
 244  
     {
 245  0
         PreparedStatement ps = connection.prepareStatement(sql);
 246  0
         return (PreparedStatement) Proxy.newProxyInstance(PreparedStatement.class.getClassLoader(),
 247  
                                                           new Class[]{PreparedStatement.class}, new StatementInvocationHandler(this, ps));
 248  
     }
 249  
 
 250  
     public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException
 251  
     {
 252  0
         PreparedStatement ps = connection.prepareStatement(sql, autoGeneratedKeys);
 253  0
         return (PreparedStatement) Proxy.newProxyInstance(PreparedStatement.class.getClassLoader(),
 254  
                                                           new Class[]{PreparedStatement.class}, new StatementInvocationHandler(this, ps));
 255  
     }
 256  
 
 257  
     public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)
 258  
             throws SQLException
 259  
     {
 260  0
         PreparedStatement ps = connection.prepareStatement(sql, resultSetType, resultSetConcurrency);
 261  0
         return (PreparedStatement) Proxy.newProxyInstance(PreparedStatement.class.getClassLoader(),
 262  
                                                           new Class[]{PreparedStatement.class}, new StatementInvocationHandler(this, ps));
 263  
     }
 264  
 
 265  
     public PreparedStatement prepareStatement(String sql,
 266  
                                               int resultSetType,
 267  
                                               int resultSetConcurrency,
 268  
                                               int resultSetHoldability) throws SQLException
 269  
     {
 270  0
         PreparedStatement ps = connection.prepareStatement(sql, resultSetType, resultSetConcurrency,
 271  
                                                            resultSetHoldability);
 272  0
         return (PreparedStatement) Proxy.newProxyInstance(PreparedStatement.class.getClassLoader(),
 273  
                                                           new Class[]{PreparedStatement.class}, new StatementInvocationHandler(this, ps));
 274  
     }
 275  
 
 276  
     public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException
 277  
     {
 278  0
         PreparedStatement ps = connection.prepareStatement(sql, columnIndexes);
 279  0
         return (PreparedStatement) Proxy.newProxyInstance(PreparedStatement.class.getClassLoader(),
 280  
                                                           new Class[]{PreparedStatement.class}, new StatementInvocationHandler(this, ps));
 281  
     }
 282  
 
 283  
     public Savepoint setSavepoint(String name) throws SQLException
 284  
     {
 285  0
         return connection.setSavepoint(name);
 286  
     }
 287  
 
 288  
     public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException
 289  
     {
 290  0
         PreparedStatement ps = connection.prepareStatement(sql, columnNames);
 291  0
         return (PreparedStatement) Proxy.newProxyInstance(PreparedStatement.class.getClassLoader(),
 292  
                                                           new Class[]{PreparedStatement.class}, new StatementInvocationHandler(this, ps));
 293  
     }
 294  
 
 295  
     public boolean enlist() throws TransactionException
 296  
     {
 297  
         try
 298  
         {
 299  0
             connection.setAutoCommit(false);
 300  
         }
 301  0
         catch (SQLException e)
 302  
         {
 303  0
             throw new TransactionException(e);
 304  0
         }
 305  
         
 306  0
         if (isEnlisted())
 307  
         {
 308  0
             return false;
 309  
         }
 310  0
         if (logger.isDebugEnabled())
 311  
         {
 312  0
             logger.debug("Enlistment request: " + this);
 313  
         }
 314  
 
 315  0
         Transaction transaction = TransactionCoordination.getInstance().getTransaction();
 316  0
         if (transaction == null)
 317  
         {
 318  0
             throw new IllegalTransactionStateException(CoreMessages.noMuleTransactionAvailable());
 319  
         }
 320  0
         if (!(transaction instanceof XaTransaction))
 321  
         {
 322  0
             throw new IllegalTransactionStateException(CoreMessages.notMuleXaTransaction(transaction));
 323  
         }
 324  
 
 325  0
         synchronized (enlistedXAResourceLock)
 326  
         {
 327  0
             if (!isEnlisted())
 328  
             {
 329  0
                 final XAResource xaResource = getXAResourceFromXATransaction();
 330  0
                 boolean wasAbleToEnlist = ((XaTransaction) transaction).enlistResource(xaResource);
 331  0
                 if (wasAbleToEnlist)
 332  
                 {
 333  0
                     enlistedXAResource = xaResource;
 334  
                 }
 335  
             }
 336  0
         }
 337  
         
 338  0
         return isEnlisted();
 339  
     }
 340  
 
 341  
     protected XAResource getXAResourceFromXATransaction() throws TransactionException
 342  
     {
 343  
         try
 344  
         {
 345  0
             return xaConnection.getXAResource();
 346  
         }
 347  0
         catch (SQLException e)
 348  
         {
 349  0
             throw new TransactionException(e);
 350  
         }
 351  
     }
 352  
 
 353  
     public boolean delist() throws Exception
 354  
     {
 355  0
         if (!isEnlisted())
 356  
         {
 357  0
             return false;
 358  
         }
 359  0
         if (logger.isDebugEnabled())
 360  
         {
 361  0
             logger.debug("Delistment request: " + this);
 362  
         }
 363  
 
 364  0
         Transaction transaction = TransactionCoordination.getInstance().getTransaction();
 365  0
         if (transaction == null)
 366  
         {
 367  0
             throw new IllegalTransactionStateException(CoreMessages.noMuleTransactionAvailable());
 368  
         }
 369  0
         if (!(transaction instanceof XaTransaction))
 370  
         {
 371  0
             throw new IllegalTransactionStateException(CoreMessages.notMuleXaTransaction(transaction));
 372  
         }
 373  
 
 374  0
         synchronized (enlistedXAResourceLock)
 375  
         {
 376  0
             if (isEnlisted())
 377  
             {
 378  0
                 boolean wasAbleToDelist = ((XaTransaction) transaction).delistResource(enlistedXAResource,
 379  
                     XAResource.TMSUCCESS);
 380  0
                 if (wasAbleToDelist)
 381  
                 {
 382  0
                     enlistedXAResource = null;
 383  
                 }
 384  
             }
 385  0
             return !isEnlisted();
 386  0
         }
 387  
     }
 388  
 
 389  
 
 390  
     public boolean isEnlisted()
 391  
     {
 392  0
         synchronized (enlistedXAResourceLock)
 393  
         {
 394  0
             return enlistedXAResource != null;
 395  0
         }
 396  
     }
 397  
 
 398  
     public boolean isReuseObject()
 399  
     {
 400  0
         return reuseObject;
 401  
     }
 402  
 
 403  
     public void setReuseObject(boolean reuseObject)
 404  
     {
 405  0
         this.reuseObject = reuseObject;
 406  0
     }
 407  
 
 408  
     public Object getTargetObject()
 409  
     {
 410  0
         return xaConnection;
 411  
     }
 412  
 
 413  
     public Array createArrayOf(String typeName, Object[] elements) throws SQLException
 414  
     {
 415  0
         return connection.createArrayOf(typeName, elements);
 416  
     }
 417  
 
 418  
     public Blob createBlob() throws SQLException
 419  
     {
 420  0
         return connection.createBlob();
 421  
     }
 422  
 
 423  
     public Clob createClob() throws SQLException
 424  
     {
 425  0
         return connection.createClob();
 426  
     }
 427  
 
 428  
     public NClob createNClob() throws SQLException
 429  
     {
 430  0
         return connection.createNClob();
 431  
     }
 432  
 
 433  
     public SQLXML createSQLXML() throws SQLException
 434  
     {
 435  0
         return connection.createSQLXML();
 436  
     }
 437  
 
 438  
     public Struct createStruct(String typeName, Object[] attributes) throws SQLException
 439  
     {
 440  0
         return connection.createStruct(typeName, attributes);
 441  
     }
 442  
 
 443  
     public Properties getClientInfo() throws SQLException
 444  
     {
 445  0
         return connection.getClientInfo();
 446  
     }
 447  
 
 448  
     public String getClientInfo(String name) throws SQLException
 449  
     {
 450  0
         return connection.getClientInfo(name);
 451  
     }
 452  
 
 453  
     public boolean isValid(int timeout) throws SQLException
 454  
     {
 455  0
         return connection.isValid(timeout);
 456  
     }
 457  
 
 458  
     public void setClientInfo(Properties properties) throws SQLClientInfoException
 459  
     {
 460  0
         connection.setClientInfo(properties);
 461  0
     }
 462  
 
 463  
     public void setClientInfo(String name, String value) throws SQLClientInfoException
 464  
     {
 465  0
         connection.setClientInfo(name, value);
 466  0
     }
 467  
 
 468  
     public boolean isWrapperFor(Class<?> iface) throws SQLException
 469  
     {
 470  0
         return connection.isWrapperFor(iface);
 471  
     }
 472  
 
 473  
     public <T> T unwrap(Class<T> iface) throws SQLException
 474  
     {
 475  0
         return connection.unwrap(iface);
 476  
     }
 477  
 }