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