Package org.jboss.jms.client.container

Source Code of org.jboss.jms.client.container.SessionAspect$AsfMessageHolder

/*
  * JBoss, Home of Professional Open Source
  * Copyright 2005, 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.jms.client.container;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import javax.jms.IllegalStateException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ServerSessionPool;
import javax.jms.Session;
import javax.jms.TransactionInProgressException;

import org.jboss.aop.joinpoint.Invocation;
import org.jboss.aop.joinpoint.MethodInvocation;
import org.jboss.jms.client.JBossConnectionConsumer;
import org.jboss.jms.client.delegate.ClientSessionDelegate;
import org.jboss.jms.client.delegate.DelegateSupport;
import org.jboss.jms.client.remoting.MessageCallbackHandler;
import org.jboss.jms.client.state.ConnectionState;
import org.jboss.jms.client.state.SessionState;
import org.jboss.jms.delegate.ConnectionDelegate;
import org.jboss.jms.delegate.SessionDelegate;
import org.jboss.jms.destination.JBossDestination;
import org.jboss.jms.message.BytesMessageProxy;
import org.jboss.jms.message.JBossBytesMessage;
import org.jboss.jms.message.JBossMapMessage;
import org.jboss.jms.message.JBossMessage;
import org.jboss.jms.message.JBossObjectMessage;
import org.jboss.jms.message.JBossStreamMessage;
import org.jboss.jms.message.JBossTextMessage;
import org.jboss.jms.message.MapMessageProxy;
import org.jboss.jms.message.MessageProxy;
import org.jboss.jms.message.ObjectMessageProxy;
import org.jboss.jms.message.StreamMessageProxy;
import org.jboss.jms.message.TextMessageProxy;
import org.jboss.jms.server.endpoint.DefaultCancel;
import org.jboss.jms.server.endpoint.DeliveryInfo;
import org.jboss.jms.tx.LocalTx;
import org.jboss.jms.tx.ResourceManager;
import org.jboss.logging.Logger;

/**
* This aspect handles JMS session related logic
*
* This aspect is PER_VM
*
* @author <a href="mailto:tim.fox@jboss.com>Tim Fox</a>
* @author <a href="mailto:ovidiu@jboss.com>Ovidiu Feodorov</a>
*
* $Id: SessionAspect.java 2470 2007-02-27 19:33:48Z timfox $
*/
public class SessionAspect
{
   // Constants -----------------------------------------------------
  
   private static final Logger log = Logger.getLogger(SessionAspect.class);
  
   // Attributes ----------------------------------------------------
  
   private boolean trace = log.isTraceEnabled();
  
   // Static --------------------------------------------------------
  
   // Constructors --------------------------------------------------
  
   // Public --------------------------------------------------------
  
   public Object handleClosing(Invocation invocation) throws Throwable
   {
      MethodInvocation mi = (MethodInvocation)invocation;
      SessionState state = getState(invocation);
      SessionDelegate del = (SessionDelegate)mi.getTargetObject();
           
      if (trace) { log.trace("handleClosing()"); }

      //Sanity check
      if (state.isXA())
      {
         if (trace) { log.trace("Session is XA"); }
        
         ConnectionState connState = (ConnectionState)state.getParent();
        
         ResourceManager rm = connState.getResourceManager();
        
         // An XASession should never be closed if there is prepared ack work that has not yet been
         // committed or rolled back. Imagine if messages had been consumed in the session, and
         // prepared but not committed. Then the connection was explicitly closed causing the
         // session to close. Closing the session causes any outstanding delivered but unacked
         // messages to be cancelled to the server which means they would be available for other
         // consumers to consume. If another consumer then consumes them, then recover() is called
         // and the original transaction is committed, then this means the same message has been
         // delivered twice which breaks the once and only once delivery guarantee.
        
         if (rm.checkForAcksInSession(state.getSessionID()))
         {
            throw new IllegalStateException(
               "Attempt to close an XASession when there are still uncommitted acknowledgements!");
         }       
      }
           
      int ackMode = state.getAcknowledgeMode();
 
      //We need to either ack (for auto_ack) or cancel (for client_ack)
      //any deliveries - this is because the message listener might have closed
      //before on message had finished executing
     
      if (ackMode == Session.AUTO_ACKNOWLEDGE)
      {
         //Acknowledge or cancel any outstanding auto ack
        
         DeliveryInfo remainingAutoAck = state.getAutoAckInfo();
        
         if (remainingAutoAck != null)
         {
            if (trace) { log.trace(this + " handleClosing(). Found remaining auto ack. Will ack " + remainingAutoAck); }
           
            try
            {
               ackDelivery(del, remainingAutoAck);
              
               if (trace) { log.trace(this + " acked it"); }              
            }
            finally
            {                       
               state.setAutoAckInfo(null);
            }
         }
      }
      else if (ackMode == Session.DUPS_OK_ACKNOWLEDGE)
      {
         //Ack any remaining deliveries
                         
         if (!state.getClientAckList().isEmpty())
         {              
            try
            {
               del.acknowledgeDeliveries(state.getClientAckList());
            }
            finally
            {           
               state.getClientAckList().clear();
              
               state.setAutoAckInfo(null);
            }
         }
      }
      else if (ackMode == Session.CLIENT_ACKNOWLEDGE)
      {
         // Cancel any oustanding deliveries
         // We cancel any client ack or transactional, we do this explicitly so we can pass the
         // updated delivery count information from client to server. We could just do this on the
         // server but we would lose delivery count info.
                 
         // CLIENT_ACKNOWLEDGE cannot be used with MDBs (i.e. no connection consumer)
         // so is always safe to cancel on this session                 
        
         cancelDeliveries(del, state.getClientAckList());
        
         state.getClientAckList().clear();
      }
      else if (state.isTransacted() && !state.isXA())
      {
         //We need to explicitly cancel any deliveries back to the server
         //from the resource manager, otherwise delivery count won't be updated
        
         ConnectionState connState = (ConnectionState)state.getParent();
        
         ResourceManager rm = connState.getResourceManager();
        
         List dels = rm.getDeliveriesForSession(state.getSessionID());
        
         cancelDeliveries(del, dels);       
      }
           
     
      return invocation.invokeNext();
   }     
  
   public Object handleClose(Invocation invocation) throws Throwable
   {     
      Object res = invocation.invokeNext();
     
      SessionState state = getState(invocation);

      ConnectionState connState = (ConnectionState)state.getParent();

      Object xid = state.getCurrentTxId();

      if (xid != null)
      {
         //Remove transaction from the resource manager
         connState.getResourceManager().removeTx(xid);
      }

      // We must explicitly shutdown the executor

      state.getExecutor().shutdownNow();

      return res;
   }
  
   public Object handlePreDeliver(Invocation invocation) throws Throwable
   {
      MethodInvocation mi = (MethodInvocation)invocation;
      SessionState state = getState(invocation);
     
      int ackMode = state.getAcknowledgeMode();
     
      Object[] args = mi.getArguments();
      DeliveryInfo info = (DeliveryInfo)args[0];
     
      if (ackMode == Session.CLIENT_ACKNOWLEDGE)
      {
         // We collect acknowledgments in the list
        
         if (trace) { log.trace(this + " added to CLIENT_ACKNOWLEDGE list delivery " + info); }
        
         // Sanity check
         if (info.getConnectionConsumerSession() != null)
         {
            throw new IllegalStateException(
               "CLIENT_ACKNOWLEDGE cannot be used with a connection consumer");
         }
                 
         state.getClientAckList().add(info);
      }
      else if (ackMode == Session.AUTO_ACKNOWLEDGE)
      {
         // We collect the single acknowledgement in the state.
                          
         if (trace) { log.trace(this + " added " + info + " to session state"); }
        
         state.setAutoAckInfo(info);        
      }
      else if (ackMode == Session.DUPS_OK_ACKNOWLEDGE)
      {
         if (trace) { log.trace(this + " added to DUPS_OK_ACKNOWLEDGE list delivery " + info); }
        
         state.getClientAckList().add(info);
        
         //Also set here - this would be used for recovery in a message listener
         state.setAutoAckInfo(info);
      }
      else
      {            
         Object txID = state.getCurrentTxId();
  
         if (txID != null)
         {
            // the session is non-XA and transacted, or XA and enrolled in a global transaction. An
            // XA session that has not been enrolled in a global transaction behaves as a
            // transacted session.
           
            ConnectionState connState = (ConnectionState)state.getParent();
  
            if (trace) { log.trace("sending acknowlegment transactionally, queueing on resource manager"); }
  
            // If the ack is for a delivery that came through via a connection consumer then we use
            // the connectionConsumer session as the session id, otherwise we use this sessions'
            // session ID
           
            ClientSessionDelegate connectionConsumerDelegate =
               (ClientSessionDelegate)info.getConnectionConsumerSession();
           
            int sessionId = connectionConsumerDelegate != null ?
               connectionConsumerDelegate.getID() : state.getSessionID();
           
            connState.getResourceManager().addAck(txID, sessionId, info);
         }       
      }
     
      return null;
   }
  
   public Object handlePostDeliver(Invocation invocation) throws Throwable
   {
      MethodInvocation mi = (MethodInvocation)invocation;
      SessionState state = getState(invocation);
     
      int ackMode = state.getAcknowledgeMode();
     
      if (ackMode == Session.AUTO_ACKNOWLEDGE)
      {
         // We auto acknowledge.

         SessionDelegate sd = (SessionDelegate)mi.getTargetObject();

         // It is possible that session.recover() is called inside a message listener onMessage
         // method - i.e. between the invocations of preDeliver and postDeliver. In this case we
         // don't want to acknowledge the last delivered messages - since it will be redelivered.
         if (!state.isRecoverCalled())
         {
            DeliveryInfo delivery = state.getAutoAckInfo();
           
            if (delivery == null)
            {
               throw new IllegalStateException("Cannot find delivery to AUTO_ACKNOWLEDGE");
            }
                                
            if (trace) { log.trace(this + " auto acknowledging delivery " + delivery); }
             

            // We clear the state in a finally so then we don't get a knock on
            // exception on the next ack since we haven't cleared the state. See
            // http://jira.jboss.org/jira/browse/JBMESSAGING-852

            //This is ok since the message is acked after delivery, then the client
            //could get duplicates anyway
           
            try
            {
               ackDelivery(sd, delivery);
            }
            finally
            {
               state.setAutoAckInfo(null);              
            }
         }        
         else
         {
            if (trace) { log.trace(this + " recover called, so NOT acknowledging"); }

            state.setRecoverCalled(false);
         }
      }
      else if (ackMode == Session.DUPS_OK_ACKNOWLEDGE)
      {
         List acks = state.getClientAckList();
        
         if (!state.isRecoverCalled())
         {
            if (acks.size() >= state.getDupsOKBatchSize())
            {
               // We clear the state in a finally
               // http://jira.jboss.org/jira/browse/JBMESSAGING-852
  
               SessionDelegate sd = (SessionDelegate)mi.getTargetObject();
                                         
               try
               {
                  sd.acknowledgeDeliveries(acks);
               }
               finally
               {                 
                  acks.clear();
                  state.setAutoAckInfo(null);
               }
            }   
         }
         else
         {
            if (trace) { log.trace(this + " recover called, so NOT acknowledging"); }

            state.setRecoverCalled(false);
         }
         state.setAutoAckInfo(null);
                 
      }

      return null;
   }
  
   /**
    * Used for client acknowledge.
    */
   public Object handleAcknowledgeAll(Invocation invocation) throws Throwable
   {   
      MethodInvocation mi = (MethodInvocation)invocation;
      SessionState state = getState(invocation);
      SessionDelegate del = (SessionDelegate)mi.getTargetObject();           
   
      if (!state.getClientAckList().isEmpty())
      {                
         //CLIENT_ACKNOWLEDGE can't be used with a MDB so it is safe to always acknowledge all
         //on this session (rather than the connection consumer session)
         del.acknowledgeDeliveries(state.getClientAckList());
     
         state.getClientAckList().clear();
      }     
       
      return null;
   }
                      
   /*
    * Called when session.recover is called
    */
   public Object handleRecover(Invocation invocation) throws Throwable
   {
      if (trace) { log.trace("recover called"); }
     
      MethodInvocation mi = (MethodInvocation)invocation;
           
      SessionState state = getState(invocation);
     
      if (state.isTransacted())
      {
         throw new IllegalStateException("Cannot recover a transacted session");
      }
     
      if (trace) { log.trace("recovering the session"); }
      
      //Call redeliver
      SessionDelegate del = (SessionDelegate)mi.getTargetObject();
     
      int ackMode = state.getAcknowledgeMode();
     
      if (ackMode == Session.CLIENT_ACKNOWLEDGE)
      {
         List dels = state.getClientAckList();
        
         state.setClientAckList(new ArrayList());
        
         del.redeliver(dels);
      }
      else if (ackMode == Session.AUTO_ACKNOWLEDGE || ackMode == Session.DUPS_OK_ACKNOWLEDGE)
      {
         DeliveryInfo info = state.getAutoAckInfo();
        
         //Don't recover if it's already to cancel
        
         if (info != null)
         {
            List redels = new ArrayList();
           
            redels.add(info);
           
            del.redeliver(redels);
           
            state.setAutoAckInfo(null);           
         }
      }  
       
      state.setRecoverCalled(true);
     
      return null
   }
  
   /**
    * Redelivery occurs in two situations:
    *
    * 1) When session.recover() is called (JMS1.1 4.4.11)
    *
    * "A session's recover method is used to stop a session and restart it with its first
    * unacknowledged message. In effect, the session's series of delivered messages is reset to the
    * point after its last acknowledged message."
    *
    * An important note here is that session recovery is LOCAL to the session. Session recovery DOES
    * NOT result in delivered messages being cancelled back to the channel where they can be
    * redelivered - since that may result in them being picked up by another session, which would
    * break the semantics of recovery as described in the spec.
    *
    * 2) When session rollback occurs (JMS1.1 4.4.7). On rollback of a session the spec is clear
    * that session recovery occurs:
    *
    * "If a transaction rollback is done, its produced messages are destroyed and its consumed
    * messages are automatically recovered. For more information on session recovery, see Section
    * 4.4.11 'Message Acknowledgment.'"
    *
    * So on rollback we do session recovery (local redelivery) in the same as if session.recover()
    * was called.
    *
    * All cancellation at rollback is driven from the client side - we always attempt to redeliver
    * messages to their original consumers if they are still open, or then cancel them to the server
    * if they are not. Cancelling them to the server explicitly allows the delivery count to be updated.
    *
    *
    */
   public Object handleRedeliver(Invocation invocation) throws Throwable
   {           
      MethodInvocation mi = (MethodInvocation)invocation;
      SessionState state = getState(invocation);           
           
      // We put the messages back in the front of their appropriate consumer buffers
     
      List toRedeliver = (List)mi.getArguments()[0];
      
      if (trace) { log.trace(this + " handleRedeliver() called: " + toRedeliver); }
     
      SessionDelegate del = (SessionDelegate)mi.getTargetObject();
     
      // Need to be redelivered in reverse order.
      for (int i = toRedeliver.size() - 1; i >= 0; i--)
      {
         DeliveryInfo info = (DeliveryInfo)toRedeliver.get(i);
         MessageProxy proxy = info.getMessageProxy();       
        
         MessageCallbackHandler handler = state.getCallbackHandler(info.getConsumerId());
             
         if (handler == null)
         {
            // This is ok. The original consumer has closed, so we cancel the message
           
            //FIXME - this needs to be done atomically for all cancels
           
            cancelDelivery(del, info);
         }
         else
         {
            if (trace) { log.trace("Adding proxy back to front of buffer"); }
           
            handler.addToFrontOfBuffer(proxy);
         }                                   
      }
             
      return null
   }
  
   public Object handleCommit(Invocation invocation) throws Throwable
   {
      SessionState state = getState(invocation);

      if (!state.isTransacted())
      {
         throw new IllegalStateException("Cannot commit a non-transacted session");
      }

      if (state.isXA())
      {
         throw new TransactionInProgressException("Cannot call commit on an XA session");
      }

      ConnectionState connState = (ConnectionState)state.getParent();
      ConnectionDelegate conn = (ConnectionDelegate)connState.getDelegate();
 
      try
      {
         connState.getResourceManager().commitLocal((LocalTx)state.getCurrentTxId(), conn);
      }
      finally
      {
         //Start new local tx
         Object xid = connState.getResourceManager().createLocalTx();

         state.setCurrentTxId(xid);
      }
     
      //TODO on commit we don't want to ACK any messages that have exceeded the max delivery count OR

      return null;
   }

   public Object handleRollback(Invocation invocation) throws Throwable
   {
      SessionState state = getState(invocation);

      if (!state.isTransacted())
      {
         throw new IllegalStateException("Cannot rollback a non-transacted session");
      }

      if (state.isXA())
      {
         throw new TransactionInProgressException("Cannot call rollback on an XA session");
      }
     
      ConnectionState connState = (ConnectionState)state.getParent();
      ResourceManager rm = connState.getResourceManager();
      try
      {
         rm.rollbackLocal((LocalTx)state.getCurrentTxId());
      }
      finally
      {
         // start new local tx
         Object xid = rm.createLocalTx();
         state.setCurrentTxId(xid);
      }

      return null;
   }
  
   public Object handleSend(Invocation invocation) throws Throwable
   {
      SessionState state = getState(invocation);
      Object txID = state.getCurrentTxId();

      if (txID != null)
      {
         // the session is non-XA and transacted, or XA and enrolled in a global transaction, so
         // we add the message to a transaction instead of sending it now. An XA session that has
         // not been enrolled in a global transaction behaves as a non-transacted session.

         ConnectionState connState = (ConnectionState)state.getParent();
         MethodInvocation mi = (MethodInvocation)invocation;
         Message m = (Message)mi.getArguments()[0];

         if (trace) { log.trace("sending message " + m + " transactionally, queueing on resource manager txID=" + txID + " sessionID= " + state.getSessionID()); }

         connState.getResourceManager().addMessage(txID, state.getSessionID(), (JBossMessage)m);

         // ... and we don't invoke any further interceptors in the stack
         return null;
      }

      if (trace) { log.trace("sending message NON-transactionally"); }

      return invocation.invokeNext();
   }
  
   public Object handleGetXAResource(Invocation invocation) throws Throwable
   {
      return getState(invocation).getXAResource();
   }
  
   public Object handleGetTransacted(Invocation invocation) throws Throwable
   {
      return getState(invocation).isTransacted() ? Boolean.TRUE : Boolean.FALSE;
   }
  
   public Object handleGetAcknowledgeMode(Invocation invocation) throws Throwable
   {
      return new Integer(getState(invocation).getAcknowledgeMode());
   }
  
   public Object handleCreateMessage(Invocation invocation) throws Throwable
   {
      JBossMessage jbm = new JBossMessage(0);
      
      return new MessageProxy(jbm);
   }
  
   public Object handleCreateBytesMessage(Invocation invocation) throws Throwable
   {
      JBossBytesMessage jbm = new JBossBytesMessage(0);
        
      return new BytesMessageProxy(jbm);
   }
  
   public Object handleCreateMapMessage(Invocation invocation) throws Throwable
   {
      JBossMapMessage jbm = new JBossMapMessage(0);
      
      return new MapMessageProxy(jbm);     
   }
  
   public Object handleCreateObjectMessage(Invocation invocation) throws Throwable
   {
      JBossObjectMessage jbm = new JBossObjectMessage(0);
      
      MethodInvocation mi = (MethodInvocation)invocation;
     
      if (mi.getArguments() != null)
      {
         jbm.setObject((Serializable)mi.getArguments()[0]);
      }
     
      return new ObjectMessageProxy(jbm);
   }
  
   public Object handleCreateStreamMessage(Invocation invocation) throws Throwable
   {
      JBossStreamMessage jbm = new JBossStreamMessage(0);
     
      return new StreamMessageProxy(jbm);
   }
  
   public Object handleCreateTextMessage(Invocation invocation) throws Throwable
  
      JBossTextMessage jbm = new JBossTextMessage(0);
     
      MethodInvocation mi = (MethodInvocation)invocation;
     
      if (mi.getArguments() != null)
      {
         jbm.setText((String)mi.getArguments()[0]);
      }
     
      return new TextMessageProxy(jbm);
   }  
  
  
  
   public Object handleSetMessageListener(Invocation invocation) throws Throwable
   {
      if (trace) { log.trace("setMessageListener()"); }
     
      MethodInvocation mi = (MethodInvocation)invocation;
     
      MessageListener listener = (MessageListener)mi.getArguments()[0];
     
      if (listener == null)
      {
         throw new IllegalStateException("Cannot set a null MessageListener on the session");
      }
     
      getState(invocation).setDistinguishedListener(listener);
     
      return null;
   }
  
   public Object handleGetMessageListener(Invocation invocation) throws Throwable
   {
      if (trace) { log.trace("getMessageListener()"); }
     
      return getState(invocation).getDistinguishedListener();
   }
  
   public Object handleCreateConnectionConsumer(Invocation invocation) throws Throwable
   {
      if (trace) { log.trace("createConnectionConsumer()"); }
     
      MethodInvocation mi = (MethodInvocation)invocation;
     
      JBossDestination dest = (JBossDestination)mi.getArguments()[0];
      String subscriptionName = (String)mi.getArguments()[1];
      String messageSelector = (String)mi.getArguments()[2];
      ServerSessionPool sessionPool = (ServerSessionPool)mi.getArguments()[3];
      int maxMessages = ((Integer)mi.getArguments()[4]).intValue();
     
      return new JBossConnectionConsumer((ConnectionDelegate)mi.getTargetObject(), dest,
                                         subscriptionName, messageSelector, sessionPool,
                                         maxMessages);
   }
  
   public Object handleAddAsfMessage(Invocation invocation) throws Throwable
   {
      if (trace) { log.trace("addAsfMessage()"); }
     
      MethodInvocation mi = (MethodInvocation)invocation;
     
      // Load the session with a message to be processed during a subsequent call to run()

      MessageProxy m = (MessageProxy)mi.getArguments()[0];
      int theConsumerID = ((Integer)mi.getArguments()[1]).intValue();
      String queueName = (String)mi.getArguments()[2];
      int maxDeliveries = ((Integer)mi.getArguments()[3]).intValue();
      SessionDelegate connectionConsumerDelegate = ((SessionDelegate)mi.getArguments()[4]);
     
      if (m == null)
      {
         throw new IllegalStateException("Cannot add a null message to the session");
      }

      AsfMessageHolder holder = new AsfMessageHolder();
      holder.msg = m;
      holder.consumerID = theConsumerID;
      holder.queueName = queueName;
      holder.maxDeliveries = maxDeliveries;
      holder.connectionConsumerDelegate = connectionConsumerDelegate;
     
      getState(invocation).getASFMessages().add(holder);
     
      return null;
   }

   public Object handleRun(Invocation invocation) throws Throwable
   {
      if (trace) { log.trace("run()"); }
     
      MethodInvocation mi = (MethodInvocation)invocation;
           
      //This is the delegate for the session from the pool
      SessionDelegate del = (SessionDelegate)mi.getTargetObject();
     
      SessionState state = getState(invocation);
     
      int ackMode = state.getAcknowledgeMode();

      LinkedList msgs = state.getASFMessages();
     
      while (msgs.size() > 0)
      {
         AsfMessageHolder holder = (AsfMessageHolder)msgs.removeFirst();

         if (trace) { log.trace("sending " + holder.msg + " to the message listener" ); }
        
         MessageCallbackHandler.callOnMessage(del, state.getDistinguishedListener(), holder.consumerID,
                                              holder.queueName, false,
                                              holder.msg, ackMode, holder.maxDeliveries,
                                              holder.connectionConsumerDelegate);                         
      }
     
      return null;
   }
  
  

   public String toString()
   {
      return "SessionAspect[" + Integer.toHexString(hashCode()) + "]";
   }

  

   // Class YYY overrides -------------------------------------------

   // Protected -----------------------------------------------------

   // Package Private -----------------------------------------------

   // Private -------------------------------------------------------
  
   private SessionState getState(Invocation inv)
   {
      return (SessionState)((DelegateSupport)inv.getTargetObject()).getState();
   }
  
   private void ackDelivery(SessionDelegate sess, DeliveryInfo delivery) throws Exception
   {
      SessionDelegate connectionConsumerSession = delivery.getConnectionConsumerSession();
     
      //If the delivery was obtained via a connection consumer we need to ack via that
      //otherwise we just use this session
     
      SessionDelegate sessionToUse = connectionConsumerSession != null ? connectionConsumerSession : sess;
     
      sessionToUse.acknowledgeDelivery(delivery);     
   }
  
   private void cancelDelivery(SessionDelegate sess, DeliveryInfo delivery) throws Exception
   {
      SessionDelegate connectionConsumerSession = delivery.getConnectionConsumerSession();
     
      //If the delivery was obtained via a connection consumer we need to cancel via that
      //otherwise we just use this session
     
      SessionDelegate sessionToUse = connectionConsumerSession != null ? connectionConsumerSession : sess;
     
      sessionToUse.cancelDelivery(new DefaultCancel(delivery.getDeliveryID(),
                                  delivery.getMessageProxy().getDeliveryCount(), false, false));     
   }
  
   private void cancelDeliveries(SessionDelegate del, List deliveryInfos) throws Exception
   {
      List cancels = new ArrayList();
     
      for (Iterator i = deliveryInfos.iterator(); i.hasNext(); )
      {
         DeliveryInfo ack = (DeliveryInfo)i.next();           
        
         DefaultCancel cancel = new DefaultCancel(ack.getMessageProxy().getDeliveryId(),
                                                  ack.getMessageProxy().getDeliveryCount(),
                                                  false, false);
        
         cancels.add(cancel);
     
     
      if (!cancels.isEmpty())
      {
         del.cancelDeliveries(cancels);
      }
   }

   // Inner Classes -------------------------------------------------
  
   private static class AsfMessageHolder
   {
      private MessageProxy msg;
      private int consumerID;
      private String queueName;
      private int maxDeliveries;
      private SessionDelegate connectionConsumerDelegate;
   }
  
}

TOP

Related Classes of org.jboss.jms.client.container.SessionAspect$AsfMessageHolder

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.