Coverage Report - org.mule.transport.jms.xa.SessionInvocationHandler
 
Classes in this File Line Coverage Branch Coverage Complexity
SessionInvocationHandler
66%
57/87
49%
36/74
4.9
 
 1  
 /*
 2  
  * $Id: SessionInvocationHandler.java 12181 2008-06-26 20:05:55Z dirk.olmes $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.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  
 package org.mule.transport.jms.xa;
 11  
 
 12  
 import org.mule.api.transaction.Transaction;
 13  
 import org.mule.config.i18n.CoreMessages;
 14  
 import org.mule.transaction.IllegalTransactionStateException;
 15  
 import org.mule.transaction.TransactionCoordination;
 16  
 import org.mule.transaction.XaTransaction;
 17  
 
 18  
 import java.lang.ref.Reference;
 19  
 import java.lang.ref.WeakReference;
 20  
 import java.lang.reflect.InvocationHandler;
 21  
 import java.lang.reflect.Method;
 22  
 import java.lang.reflect.Proxy;
 23  
 
 24  
 import javax.jms.JMSException;
 25  
 import javax.jms.MessageConsumer;
 26  
 import javax.jms.MessageProducer;
 27  
 import javax.jms.QueueReceiver;
 28  
 import javax.jms.QueueSender;
 29  
 import javax.jms.Session;
 30  
 import javax.jms.TopicPublisher;
 31  
 import javax.jms.TopicSubscriber;
 32  
 import javax.jms.XAQueueSession;
 33  
 import javax.jms.XASession;
 34  
 import javax.jms.XATopicSession;
 35  
 import javax.transaction.xa.XAResource;
 36  
 
 37  
 import org.apache.commons.logging.Log;
 38  
 import org.apache.commons.logging.LogFactory;
 39  
 
 40  
 public class SessionInvocationHandler implements InvocationHandler
 41  
 {
 42  6
     protected static final transient Log logger = LogFactory.getLog(SessionInvocationHandler.class);
 43  
 
 44  
     private XASession xaSession;
 45  
     private XAResource xaResource;
 46  66
     private volatile boolean enlisted = false;
 47  65
     private volatile boolean reuseObject = false;
 48  
     private final Reference underlyingObject;
 49  
     private static final Method SESSION_CLOSE_METHOD;
 50  
 
 51  
     static
 52  
     {
 53  
         try
 54  
         {
 55  6
             SESSION_CLOSE_METHOD = Session.class.getMethod("close", (Class[])null);
 56  
         }
 57  0
         catch (NoSuchMethodException e)
 58  
         {
 59  0
             throw new RuntimeException(e);
 60  6
         }
 61  6
     }
 62  
 
 63  
     public SessionInvocationHandler(XASession xaSession) throws JMSException
 64  66
     {
 65  64
         this.xaSession = xaSession;
 66  65
         underlyingObject = new WeakReference(xaSession.getSession());
 67  63
         this.xaResource = new XAResourceWrapper(xaSession.getXAResource(), this);
 68  65
     }
 69  
 
 70  
     public SessionInvocationHandler(XAQueueSession xaSession) throws JMSException
 71  0
     {
 72  0
         this.xaSession = xaSession;
 73  0
         underlyingObject = new WeakReference(xaSession.getQueueSession());
 74  0
         this.xaResource = new XAResourceWrapper(xaSession.getXAResource(), this);
 75  0
     }
 76  
 
 77  
     public SessionInvocationHandler(XATopicSession xaSession) throws JMSException
 78  0
     {
 79  0
         this.xaSession = xaSession;
 80  0
         underlyingObject = new WeakReference(xaSession.getTopicSession());
 81  0
         this.xaResource = new XAResourceWrapper(xaSession.getXAResource(), this);
 82  0
     }
 83  
 
 84  
     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
 85  
     {
 86  549
         if (logger.isDebugEnabled())
 87  
         {
 88  0
             logger.debug("Invoking " + method);
 89  
         }
 90  548
         if (underlyingObject.get() == null)
 91  
         {
 92  0
             throw new IllegalStateException("Underlying session is null, XASession " + xaSession);
 93  
         }
 94  
 
 95  
         // processing method from MuleXaObject
 96  548
         if (XaTransaction.MuleXaObject.DELIST_METHOD_NAME.equals(method.getName()))
 97  
         {
 98  34
             return Boolean.valueOf(delist());
 99  
         }
 100  513
         else if (XaTransaction.MuleXaObject.ENLIST_METHOD_NAME.equals(method.getName()))
 101  
         {
 102  66
             return Boolean.valueOf(enlist());
 103  
         }
 104  446
         else if (XaTransaction.MuleXaObject.SET_REUSE_OBJECT_METHOD_NAME.equals(method.getName()))
 105  
         {
 106  51
             reuseObject = ((Boolean) args[0]).booleanValue();
 107  50
             return null;
 108  
         }
 109  396
         else if (XaTransaction.MuleXaObject.IS_REUSE_OBJECT_METHOD_NAME.equals(method.getName()))
 110  
         {
 111  67
             return Boolean.valueOf(reuseObject);
 112  
         }
 113  328
         else if (XaTransaction.MuleXaObject.GET_TARGET_OBJECT_METHOD_NAME.equals(method.getName()))
 114  
         {
 115  0
             return getTargetObject();
 116  
         }
 117  328
         else if (XaTransaction.MuleXaObject.CLOSE_METHOD_NAME.equals(method.getName()))
 118  
         {
 119  61
             return SESSION_CLOSE_METHOD.invoke(underlyingObject.get(), args);
 120  
         }
 121  
         //close will be directly called on session object
 122  
 
 123  268
         Object result = method.invoke(underlyingObject.get(), args);
 124  
 
 125  268
         if (result instanceof TopicSubscriber)
 126  
         {
 127  8
             result = Proxy.newProxyInstance(Session.class.getClassLoader(),
 128  
                                             new Class[]{TopicSubscriber.class}, new ConsumerProducerInvocationHandler(this, result));
 129  
         }
 130  259
         else if (result instanceof QueueReceiver)
 131  
         {
 132  0
             result = Proxy.newProxyInstance(Session.class.getClassLoader(),
 133  
                                             new Class[]{QueueReceiver.class}, new ConsumerProducerInvocationHandler(this, result));
 134  
         }
 135  260
         else if (result instanceof MessageConsumer)
 136  
         {
 137  42
             result = Proxy.newProxyInstance(Session.class.getClassLoader(),
 138  
                                             new Class[]{MessageConsumer.class}, new ConsumerProducerInvocationHandler(this, result));
 139  
         }
 140  218
         else if (result instanceof TopicPublisher)
 141  
         {
 142  0
             result = Proxy.newProxyInstance(Session.class.getClassLoader(),
 143  
                                             new Class[]{TopicPublisher.class}, new ConsumerProducerInvocationHandler(this, result));
 144  
         }
 145  218
         else if (result instanceof QueueSender)
 146  
         {
 147  0
             result = Proxy.newProxyInstance(Session.class.getClassLoader(),
 148  
                                             new Class[]{QueueSender.class}, new ConsumerProducerInvocationHandler(this, result));
 149  
         }
 150  218
         else if (result instanceof MessageProducer)
 151  
         {
 152  26
             result = Proxy.newProxyInstance(Session.class.getClassLoader(),
 153  
                                             new Class[]{MessageProducer.class}, new ConsumerProducerInvocationHandler(this, result));
 154  
         }
 155  267
         return result;
 156  
     }
 157  
 
 158  
     public boolean enlist() throws Exception
 159  
     {
 160  67
         if (isEnlisted())
 161  
         {
 162  0
             return false;
 163  
         }
 164  
 
 165  67
         if (logger.isDebugEnabled())
 166  
         {
 167  0
             logger.debug("Enlistment request: " + this);
 168  
         }
 169  
 
 170  67
         Transaction transaction = TransactionCoordination.getInstance().getTransaction();
 171  66
         if (transaction == null)
 172  
         {
 173  0
             throw new IllegalTransactionStateException(CoreMessages.noMuleTransactionAvailable());
 174  
         }
 175  67
         if (!(transaction instanceof XaTransaction))
 176  
         {
 177  0
             throw new IllegalTransactionStateException(CoreMessages.notMuleXaTransaction(transaction));
 178  
         }
 179  
 
 180  67
         if (!isEnlisted())
 181  
         {
 182  67
             if (logger.isDebugEnabled())
 183  
             {
 184  0
                 logger.debug("Enlisting resource " + xaResource + " in xa transaction " + transaction);
 185  
             }
 186  
 
 187  67
             enlisted = ((XaTransaction) transaction).enlistResource(xaResource);
 188  
         }
 189  
         
 190  67
         return enlisted;
 191  
     }
 192  
 
 193  
     public boolean delist() throws Exception
 194  
     {
 195  34
         if (!isEnlisted())
 196  
         {
 197  0
             return false;
 198  
         }
 199  
 
 200  34
         if (logger.isDebugEnabled())
 201  
         {
 202  0
             logger.debug("Delistment request: " + this);
 203  
         }
 204  
 
 205  34
         Transaction transaction = TransactionCoordination.getInstance().getTransaction();
 206  34
         if (transaction == null)
 207  
         {
 208  0
             throw new IllegalTransactionStateException(CoreMessages.noMuleTransactionAvailable());
 209  
         }
 210  34
         if (!(transaction instanceof XaTransaction))
 211  
         {
 212  0
             throw new IllegalTransactionStateException(CoreMessages.notMuleXaTransaction(transaction));
 213  
         }
 214  
 
 215  34
         if (isEnlisted())
 216  
         {
 217  34
             if (logger.isDebugEnabled())
 218  
             {
 219  0
                 logger.debug("Delisting resource " + xaResource + " in xa transaction " + transaction);
 220  
             }
 221  
 
 222  34
             enlisted = !((XaTransaction) transaction).delistResource(xaResource, XAResource.TMSUCCESS);
 223  
         }
 224  34
         return !isEnlisted();
 225  
     }
 226  
 
 227  
     public boolean isEnlisted()
 228  
     {
 229  236
         return enlisted;
 230  
     }
 231  
 
 232  
     public void setEnlisted(boolean enlisted)
 233  
     {
 234  46
         this.enlisted = enlisted;
 235  46
     }
 236  
 
 237  
     public XASession getTargetObject()
 238  
     {
 239  0
         return xaSession;
 240  
     }
 241  
 
 242  
     public XAResource getXAResource()
 243  
     {
 244  0
         return xaResource;
 245  
     }
 246  
 
 247  
 }