Coverage Report - org.mule.util.xa.DefaultXASession
 
Classes in this File Line Coverage Branch Coverage Complexity
DefaultXASession
0%
0/126
0%
0/78
5.125
 
 1  
 /*
 2  
  * $Id: DefaultXASession.java 19191 2010-08-25 21:05:23Z tcarlson $
 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.util.xa;
 12  
 
 13  
 import javax.transaction.Status;
 14  
 import javax.transaction.xa.XAException;
 15  
 import javax.transaction.xa.XAResource;
 16  
 import javax.transaction.xa.Xid;
 17  
 
 18  
 import org.apache.commons.logging.Log;
 19  
 import org.apache.commons.logging.LogFactory;
 20  
 
 21  
 /**
 22  
  * TODO document
 23  
  */
 24  
 public class DefaultXASession implements XAResource
 25  
 {
 26  
 
 27  
     /**
 28  
      * logger used by this class
 29  
      */
 30  0
     protected transient Log logger = LogFactory.getLog(getClass());
 31  
 
 32  
     protected AbstractTransactionContext localContext;
 33  
     protected Xid localXid;
 34  
     protected AbstractXAResourceManager resourceManager;
 35  
 
 36  
     public DefaultXASession(AbstractXAResourceManager resourceManager)
 37  0
     {
 38  0
         this.localContext = null;
 39  0
         this.localXid = null;
 40  0
         this.resourceManager = resourceManager;
 41  0
     }
 42  
 
 43  
     public XAResource getXAResource()
 44  
     {
 45  0
         return this;
 46  
     }
 47  
 
 48  
     public Object getResourceManager()
 49  
     {
 50  0
         return resourceManager;
 51  
     }
 52  
 
 53  
     //
 54  
     // Local transaction implementation
 55  
     //
 56  
     public void begin() throws ResourceManagerException
 57  
     {
 58  0
         if (localXid != null)
 59  
         {
 60  0
             throw new IllegalStateException(
 61  
                 "Cannot start local transaction. An XA transaction is already in progress.");
 62  
         }
 63  0
         if (localContext != null)
 64  
         {
 65  0
             throw new IllegalStateException(
 66  
                 "Cannot start local transaction. A local transaction already in progress.");
 67  
         }
 68  0
         localContext = resourceManager.createTransactionContext(this);
 69  0
         resourceManager.beginTransaction(localContext);
 70  0
     }
 71  
 
 72  
     public void commit() throws ResourceManagerException
 73  
     {
 74  0
         if (localXid != null)
 75  
         {
 76  0
             throw new IllegalStateException(
 77  
                 "Cannot commit local transaction as an XA transaction is in progress.");
 78  
         }
 79  0
         if (localContext == null)
 80  
         {
 81  0
             throw new IllegalStateException("Cannot commit local transaction as no transaction was begun");
 82  
         }
 83  0
         resourceManager.commitTransaction(localContext);
 84  0
         localContext = null;
 85  0
     }
 86  
 
 87  
     public void rollback() throws ResourceManagerException
 88  
     {
 89  0
         if (localXid != null)
 90  
         {
 91  0
             throw new IllegalStateException(
 92  
                 "Cannot rollback local transaction as an XA transaction is in progress.");
 93  
         }
 94  0
         if (localContext == null)
 95  
         {
 96  0
             throw new IllegalStateException("Cannot commit local transaction as no transaction was begun");
 97  
         }
 98  0
         resourceManager.rollbackTransaction(localContext);
 99  0
         localContext = null;
 100  0
     }
 101  
 
 102  
     //
 103  
     // XAResource implementation
 104  
     //
 105  
 
 106  
     public boolean isSameRM(XAResource xares) throws XAException
 107  
     {
 108  0
         return xares instanceof DefaultXASession
 109  
                && ((DefaultXASession) xares).getResourceManager().equals(resourceManager);
 110  
     }
 111  
 
 112  
     public Xid[] recover(int flag) throws XAException
 113  
     {
 114  0
         return null;
 115  
     }
 116  
 
 117  
     public void start(Xid xid, int flags) throws XAException
 118  
     {
 119  0
         if (logger.isDebugEnabled())
 120  
         {
 121  0
             logger.debug(new StringBuffer(128).append("Thread ").append(Thread.currentThread()).append(
 122  
                 flags == TMNOFLAGS ? " starts" : flags == TMJOIN ? " joins" : " resumes").append(
 123  
                 " work on behalf of transaction branch ").append(xid).toString());
 124  
         }
 125  
         // A local transaction is already begun
 126  0
         if (this.localContext != null)
 127  
         {
 128  0
             throw new XAException(XAException.XAER_PROTO);
 129  
         }
 130  
         // This session has already been associated with an xid
 131  0
         if (this.localXid != null)
 132  
         {
 133  0
             throw new XAException(XAException.XAER_PROTO);
 134  
         }
 135  0
         switch (flags)
 136  
         {
 137  
             // a new transaction
 138  
             case TMNOFLAGS :
 139  
             case TMJOIN :
 140  
             default :
 141  
                 try
 142  
                 {
 143  0
                     localContext = resourceManager.createTransactionContext(this);
 144  0
                     resourceManager.beginTransaction(localContext);
 145  
                 }
 146  0
                 catch (Exception e)
 147  
                 {
 148  
                     // TODO MULE-863: Is logging necessary?
 149  0
                     logger.error("Could not create new transactional resource", e);
 150  0
                     throw (XAException) new XAException(e.getMessage()).initCause(e);
 151  0
                 }
 152  
                 break;
 153  
             case TMRESUME :
 154  0
                 localContext = resourceManager.getSuspendedTransactionalResource(xid);
 155  0
                 if (localContext == null)
 156  
                 {
 157  0
                     throw new XAException(XAException.XAER_NOTA);
 158  
                 }
 159  
                 // TODO: resume context
 160  0
                 resourceManager.removeSuspendedTransactionalResource(xid);
 161  
                 break;
 162  
         }
 163  0
         localXid = xid;
 164  0
         resourceManager.addActiveTransactionalResource(localXid, localContext);
 165  0
     }
 166  
 
 167  
     public void end(Xid xid, int flags) throws XAException
 168  
     {
 169  0
         if (logger.isDebugEnabled())
 170  
         {
 171  0
             logger.debug(new StringBuffer(128).append("Thread ").append(Thread.currentThread()).append(
 172  
                 flags == TMSUSPEND ? " suspends" : flags == TMFAIL ? " fails" : " ends").append(
 173  
                 " work on behalf of transaction branch ").append(xid).toString());
 174  
         }
 175  
         // No transaction is already begun
 176  0
         if (localContext == null)
 177  
         {
 178  0
             throw new XAException(XAException.XAER_NOTA);
 179  
         }
 180  
         // This session has already been associated with an xid
 181  0
         if (localXid == null || !localXid.equals(xid))
 182  
         {
 183  0
             throw new XAException(XAException.XAER_PROTO);
 184  
         }
 185  
 
 186  
         try
 187  
         {
 188  0
             switch (flags)
 189  
             {
 190  
                 case TMSUSPEND :
 191  
                     // TODO: suspend context
 192  0
                     resourceManager.addSuspendedTransactionalResource(localXid, localContext);
 193  0
                     resourceManager.removeActiveTransactionalResource(localXid);
 194  0
                     break;
 195  
                 case TMFAIL :
 196  0
                     resourceManager.setTransactionRollbackOnly(localContext);
 197  0
                     break;
 198  
                 case TMSUCCESS : // no-op
 199  
                 default :        // no-op
 200  
                     break;
 201  
             }
 202  
         }
 203  0
         catch (ResourceManagerException e)
 204  
         {
 205  0
             throw (XAException) new XAException(XAException.XAER_RMERR).initCause(e);
 206  0
         }
 207  0
         localXid = null;
 208  0
         localContext = null;
 209  0
     }
 210  
 
 211  
     public void commit(Xid xid, boolean onePhase) throws XAException
 212  
     {
 213  0
         if (xid == null)
 214  
         {
 215  0
             throw new XAException(XAException.XAER_PROTO);
 216  
         }
 217  0
         AbstractTransactionContext context = resourceManager.getActiveTransactionalResource(xid);
 218  0
         if (context == null)
 219  
         {
 220  0
             throw new XAException(XAException.XAER_NOTA);
 221  
         }
 222  0
         if (logger.isDebugEnabled())
 223  
         {
 224  0
             logger.debug("Committing transaction branch " + xid);
 225  
         }
 226  0
         if (context.status == Status.STATUS_MARKED_ROLLBACK)
 227  
         {
 228  0
             throw new XAException(XAException.XA_RBROLLBACK);
 229  
         }
 230  
 
 231  
         try
 232  
         {
 233  0
             if (context.status != Status.STATUS_PREPARED)
 234  
             {
 235  0
                 if (onePhase)
 236  
                 {
 237  0
                     resourceManager.prepareTransaction(context);
 238  
                 }
 239  
                 else
 240  
                 {
 241  0
                     throw new XAException(XAException.XAER_PROTO);
 242  
                 }
 243  
             }
 244  0
             resourceManager.commitTransaction(context);
 245  
         }
 246  0
         catch (ResourceManagerException e)
 247  
         {
 248  0
             throw (XAException) new XAException(XAException.XAER_RMERR).initCause(e);
 249  0
         }
 250  0
         resourceManager.removeActiveTransactionalResource(xid);
 251  0
         resourceManager.removeSuspendedTransactionalResource(xid);
 252  0
     }
 253  
 
 254  
     public void rollback(Xid xid) throws XAException
 255  
     {
 256  0
         if (xid == null)
 257  
         {
 258  0
             throw new XAException(XAException.XAER_PROTO);
 259  
         }
 260  0
         AbstractTransactionContext context = resourceManager.getActiveTransactionalResource(xid);
 261  0
         if (context == null)
 262  
         {
 263  0
             throw new XAException(XAException.XAER_NOTA);
 264  
         }
 265  0
         if (logger.isDebugEnabled())
 266  
         {
 267  0
             logger.debug("Rolling back transaction branch " + xid);
 268  
         }
 269  
         try
 270  
         {
 271  0
             resourceManager.rollbackTransaction(context);
 272  
         }
 273  0
         catch (ResourceManagerException e)
 274  
         {
 275  0
             throw (XAException) new XAException(XAException.XAER_RMERR).initCause(e);
 276  0
         }
 277  0
         resourceManager.removeActiveTransactionalResource(xid);
 278  0
         resourceManager.removeSuspendedTransactionalResource(xid);
 279  0
     }
 280  
 
 281  
     public int prepare(Xid xid) throws XAException
 282  
     {
 283  0
         if (xid == null)
 284  
         {
 285  0
             throw new XAException(XAException.XAER_PROTO);
 286  
         }
 287  
 
 288  0
         AbstractTransactionContext context = resourceManager.getTransactionalResource(xid);
 289  0
         if (context == null)
 290  
         {
 291  0
             throw new XAException(XAException.XAER_NOTA);
 292  
         }
 293  
 
 294  0
         if (logger.isDebugEnabled())
 295  
         {
 296  0
             logger.debug("Preparing transaction branch " + xid);
 297  
         }
 298  
 
 299  0
         if (context.status == Status.STATUS_MARKED_ROLLBACK)
 300  
         {
 301  0
             throw new XAException(XAException.XA_RBROLLBACK);
 302  
         }
 303  
 
 304  
         try
 305  
         {
 306  0
             return resourceManager.prepareTransaction(context);
 307  
         }
 308  0
         catch (ResourceManagerException e)
 309  
         {
 310  0
             throw (XAException) new XAException(XAException.XAER_RMERR).initCause(e);
 311  
         }
 312  
     }
 313  
 
 314  
     public void forget(Xid xid) throws XAException
 315  
     {
 316  0
         if (logger.isDebugEnabled())
 317  
         {
 318  0
             logger.debug("Forgetting transaction branch " + xid);
 319  
         }
 320  0
         AbstractTransactionContext context = resourceManager.getTransactionalResource(xid);
 321  0
         if (context == null)
 322  
         {
 323  0
             throw new XAException(XAException.XAER_NOTA);
 324  
         }
 325  0
         resourceManager.removeActiveTransactionalResource(xid);
 326  0
         resourceManager.removeSuspendedTransactionalResource(xid);
 327  0
     }
 328  
 
 329  
     public int getTransactionTimeout() throws XAException
 330  
     {
 331  0
         return (int)(resourceManager.getDefaultTransactionTimeout() / 1000);
 332  
     }
 333  
 
 334  
     public boolean setTransactionTimeout(int timeout) throws XAException
 335  
     {
 336  0
         resourceManager.setDefaultTransactionTimeout(timeout * 1000);
 337  0
         return false;
 338  
     }
 339  
 
 340  
 }