Package org.jboss.internal.soa.esb.rosetta.pooling

Source Code of org.jboss.internal.soa.esb.rosetta.pooling.JmsXASession

/*
* JBoss, Home of Professional Open Source
* Copyright 2006, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.internal.soa.esb.rosetta.pooling;

import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.QueueBrowser;
import javax.jms.TopicSubscriber;
import javax.jms.XASession;
import javax.transaction.Synchronization;
import javax.transaction.xa.XAResource;

import org.jboss.internal.soa.esb.rosetta.pooling.JmsConnectionPool.JmsSessionPool;
import org.jboss.soa.esb.common.TransactionStrategy;
import org.jboss.soa.esb.common.TransactionStrategyException;

/**
* Wrapper for JMS XA session class, responsible for tracking resources and the pooling.
*/
class JmsXASession extends JmsSession implements Synchronization
{
    /**
     * The connection pool.
     */
    private final JmsConnectionPool connectionPool ;
   
    /**
     * The session delegate.
     */
    private final XASession xaSessionDelegate ;
   
    /**
     * Cleanup actions
     */
    private enum Cleanup { close, release }
   
    /**
     * The cleanup action for the synchronization.
     */
    private Cleanup cleanupAction = Cleanup.close ;
    /**
     * Flag representing whether the wrappers are valid or not.
     */
    private AtomicBoolean wrapperValid = new AtomicBoolean(true) ;
    /**
     * Use count for tracking references.
     */
    private AtomicInteger refCount = new AtomicInteger(0) ;
   
    /**
     * Duplicate the session wrapper.
     * @param connectionPool The current connection pool
     * @param sessionPool The current session pool
     * @param session The underlying session.
     * @param id The pool instance id.
     * @param requestedAcknowledgeMode The requested acknowledge mode for this session.
     * @param acknowledgeMode The original acknowledge mode for this session.
     */
    JmsXASession(final JmsConnectionPool connectionPool, final JmsSessionPool sessionPool, final XASession session,
        final long id, final int requestedAcknowledgeMode, final int acknowledgeMode)
    {
        super(connectionPool, sessionPool, new WrappedXASession(connectionPool, session), session, id, requestedAcknowledgeMode, acknowledgeMode) ;
        this.connectionPool = connectionPool ;
        this.xaSessionDelegate = (XASession)getSessionDelegate() ;
    }
   
    /**
     * Create the session wrapper.
     * @param connectionPool The current connection pool
     * @param sessionPool The current session pool
     * @param session The session delegate.
     * @param id The pool instance id.
     * @param requestedAcknowledgeMode The requested acknowledge mode for this session.
     * @throws JMSException
     */
    JmsXASession(final JmsConnectionPool connectionPool, final JmsSessionPool sessionPool, final XASession session, final long id, final int requestedAcknowledgeMode)
        throws JMSException
    {
        super(connectionPool, sessionPool, new WrappedXASession(connectionPool, session), session, id, requestedAcknowledgeMode) ;
        this.connectionPool = connectionPool ;
        this.xaSessionDelegate = (XASession)getSessionDelegate() ;
    }
   
    @Override
    public void commit() throws JMSException
    {
        // Handled by the transaction
    }
   
    @Override
    public void rollback() throws JMSException
    {
        try
        {
            TransactionStrategy.getTransactionStrategy(true).rollbackOnly() ;
        }
        catch (final TransactionStrategyException tse)
        {
            final JMSException ex = new JMSException("Failed to rollback transaction") ;
            ex.initCause(tse) ;
            throw ex ;
        }
    }
   
    @Override
    protected MessageProducer getMessageProducer(MessageProducer messageProducer)
    {
        return new WrappedMessageProducer(connectionPool, this, messageProducer, wrapperValid) ;
    }

    @Override
    protected MessageConsumer getMessageConsumer(MessageConsumer messageConsumer)
    {
        return new WrappedMessageConsumer(connectionPool, this, messageConsumer, wrapperValid) ;
    }
   
    @Override
    protected QueueBrowser getQueueBrowser(QueueBrowser queueBrowser)
    {
        return new WrappedQueueBrowser(connectionPool, this, queueBrowser, wrapperValid) ;
    }
   
    @Override
    protected TopicSubscriber getTopicSubscriber(TopicSubscriber topicSubscriber)
    {
        return new WrappedTopicSubscriber(connectionPool, this, topicSubscriber, wrapperValid) ;
    }
   
    private void releaseSession()
    {
        try
        {
            connectionPool.handleReleaseSession(this) ;
        }
        finally
        {
            wrapperValid.set(false) ;
            wrapperValid = new AtomicBoolean(true) ;
        }
    }
   
    private void closeSession()
    {
        try
        {
            connectionPool.handleCloseSession(this) ;
        }
        finally
        {
            wrapperValid.set(false) ;
            wrapperValid = new AtomicBoolean(true) ;
        }
    }

    public JmsSession duplicateSession()
    {
        invalid = true ;
        return new JmsXASession(connectionPool, getSessionPool(), (XASession)getSession(), getId(), getRequestedAcknowledgeMode(), acknowledgeMode) ;
    }
   
    protected void incrementReferenceCount()
    {
        refCount.incrementAndGet() ;
    }
   
    protected synchronized void handleCloseSession(final JmsConnectionPool jmsConnectionPool)
    {
        final boolean associated = connectionPool.isAssociated(this) ;
        final int count = refCount.decrementAndGet() ;
        if (!associated && (count == 0))
        {
            if (cleanupAction == Cleanup.release)
            {
                releaseSession() ;
            }
            else
            {
                closeSession() ;
            }
        }
    }
   
    protected synchronized void handleReleaseSession(JmsConnectionPool jmsConnectionPool)
    {
        final boolean associated = connectionPool.isAssociated(this) ;
        final int count = refCount.decrementAndGet() ;
        if (associated)
        {
            cleanupAction = Cleanup.release ;
        }
        else if (count == 0)
        {
            releaseSession() ;
        }
    }
   
    protected synchronized void associate()
        throws JMSException
    {
        if (invalid)
        {
            throw new JMSException("Session no longer valid") ;
        }
        if (!connectionPool.isAssociated(this))
        {
            final TransactionStrategy transactionStrategy = TransactionStrategy.getTransactionStrategy(true) ;
            try
            {
                if (!transactionStrategy.isActive())
                {
                    throw new JMSException("No active transaction") ;
                }
               
                transactionStrategy.registerSynchronization(this) ;
                setSuspect(true) ;
                final XAResource resource = xaSessionDelegate.getXAResource() ;
                transactionStrategy.enlistResource(resource) ;
            }
            catch (final TransactionStrategyException tse)
            {
                final JMSException ex = new JMSException("Failed to initialise transaction resources") ;
                ex.initCause(tse) ;
                throw ex ;
            }
            try
            {
                connectionPool.associateTransaction(this) ;
            }
            catch (final ConnectionException ce)
            {
                final JMSException ex = new JMSException("Failed to associate session with the current transaction") ;
                ex.initCause(ce) ;
                throw ex ;
            }
           
            setSuspect(false) ;
        }
    }
   
    public void beforeCompletion()
    {
    }
   
    public synchronized void afterCompletion(final int result)
    {
        connectionPool.disassociateTransaction(this) ;
        if (refCount.get() == 0)
        {
            if (cleanupAction == Cleanup.close)
            {
                closeSession() ;
            }
            else
            {
                releaseSession() ;
            }
        }
    }
}
TOP

Related Classes of org.jboss.internal.soa.esb.rosetta.pooling.JmsXASession

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.