Package com.sun.messaging.jms.ra

Source Code of com.sun.messaging.jms.ra.ConnectionAdapter

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2000-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License").  You
* may not use this file except in compliance with the License.  You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt.  See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license."  If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above.  However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/

package com.sun.messaging.jms.ra;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.logging.Logger;

import javax.jms.ConnectionConsumer;
import javax.jms.Destination;
import javax.jms.ExceptionListener;
import javax.jms.JMSException;
import javax.jms.Queue;
import javax.jms.QueueSession;
import javax.jms.ServerSessionPool;
import javax.jms.Session;
import javax.jms.Topic;
import javax.jms.TopicSession;
import javax.resource.ResourceException;
import javax.resource.spi.ConnectionEvent;

import com.sun.messaging.jmq.jmsclient.XAQueueSessionImpl;
import com.sun.messaging.jmq.jmsclient.XASessionImpl;
import com.sun.messaging.jmq.jmsclient.XATopicSessionImpl;
/**
* Implements the JMS Connection interface for the GlassFish Message Queue Resource Adapter
*
*/
public class ConnectionAdapter implements javax.jms.Connection, javax.jms.QueueConnection, javax.jms.TopicConnection {
 
    /** The ResourceAdapter instance associated with this instance */
    private com.sun.messaging.jms.ra.ResourceAdapter ra = null;

    /** The ManagedConnection instance that created this instance */
    private com.sun.messaging.jms.ra.ManagedConnection mc = null;

    /** The XAConection instance wrapped by this ConnectionAdapter */
    public com.sun.messaging.jmq.jmsclient.XAConnectionImpl xac = null;

    /** The XASession instance created by this ConnectionAdapter */
    private com.sun.messaging.jms.ra.SessionAdapter sa = null;

    /** Flags whether further creation of session is allowed per J2EE1.4 */
    private boolean sessions_allowed = true;

    /** The set of sessions created by this connection */
    private Set<SessionAdapter> sessions = null;

    /** Flags whether the connection has been destroyed */
    private boolean destroyed = false;

    /** Flags whether the adapter has been closed */
    private boolean closed = false;

    /** Flags whether the connection is in an Application Client Container */
    private boolean inACC = true;

  /* Loggers */
  private static transient final String _className = "com.sun.messaging.jms.ra.ConnectionAdapter";
  protected static transient final String _lgrNameJMSConnection = "javax.jms.Connection.mqjmsra";
  protected static transient final String _lgrNameOutboundConnection = "javax.resourceadapter.mqjmsra.outbound.connection";
  protected static transient final Logger _loggerOC = Logger.getLogger(_lgrNameOutboundConnection);
  protected static transient final Logger _loggerJC = Logger.getLogger(_lgrNameJMSConnection);
  protected static transient final String _lgrMIDPrefix = "MQJMSRA_CA";
  protected static transient final String _lgrMID_EET = _lgrMIDPrefix + "1001: ";
  protected static transient final String _lgrMID_INF = _lgrMIDPrefix + "1101: ";
  protected static transient final String _lgrMID_WRN = _lgrMIDPrefix + "2001: ";
  protected static transient final String _lgrMID_ERR = _lgrMIDPrefix + "3001: ";
  protected static transient final String _lgrMID_EXC = _lgrMIDPrefix + "4001: ";
  /**
   * @param mc
   * @param xac
   * @param ra
   * @throws ResourceException
   */
  public ConnectionAdapter(com.sun.messaging.jms.ra.ManagedConnection mc,
      com.sun.messaging.jmq.jmsclient.XAConnectionImpl xac, com.sun.messaging.jms.ra.ResourceAdapter ra)
      throws ResourceException {
   
    Object params[] = new Object[3];
    params[0] = mc;
    params[1] = xac;
    params[2] = ra;

    _loggerOC.entering(_className, "constructor()", params);

    this.mc = mc;
    this.xac = xac;
    this.ra = ra;
    sessions = new HashSet<SessionAdapter>();

    if (ra != null) {
      inACC = ra.getInAppClientContainer();
      if (ra.getInClusteredContainer()
          && this.getManagedConnection().getManagedConnectionFactory()
              .isUseSharedSubscriptionInClusteredContainer()) {
        xac.setRANamespaceUID(ra._getRAUID());
      }
    }
    // System.out.println("MQRA:CA:Constructor-inACC="+inACC);
    // xac.dump(System.out);
  }

  /*
   * @see javax.jms.Connection#setClientID(java.lang.String)
   */
  public void setClientID(String clientId) throws JMSException {
    _loggerJC.entering(_className, "setClientID()", clientId);
    // System.out.println("MQRA:CA:setClientID-to-"+clientId);
    if (!inACC) {
      throw new com.sun.messaging.jms.JMSException("MQRA:CA:Unsupported-setClientID()");
    }
    checkClosed();
    xac.setClientID(clientId);
  }

  /*
   * @see javax.jms.Connection#getClientID()
   */
  public String getClientID() throws JMSException {
    _loggerJC.entering(_className, "getClientID()");
    checkClosed();
    return xac.getClientID();
  }

  /*
   * @see javax.jms.Connection#setExceptionListener(javax.jms.ExceptionListener)
   */
  public void setExceptionListener(ExceptionListener listener) throws JMSException {
    _loggerJC.entering(_className, "setExceptionListener()", listener);
    if (!inACC) {
      throw new com.sun.messaging.jms.JMSException("MQRA:CA:Unsupported-setExceptionListener()");
    }
    checkClosed();
    xac.setExceptionListener(listener);
  }

  /*
   * @see javax.jms.Connection#getExceptionListener()
   */
  public ExceptionListener getExceptionListener() throws JMSException {
    checkClosed();
    return xac.getExceptionListener();
  }

  /*
   * @see javax.jms.Connection#getMetaData()
   */
  public javax.jms.ConnectionMetaData getMetaData() throws JMSException {
    checkClosed();
    return xac.getMetaData();
  }

  /*
   * @see javax.jms.Connection#start()
   */
  public void start() throws JMSException {
    checkClosed();
    xac.start();
  }

  /*
   * @see javax.jms.Connection#stop()
   */
  public void stop() throws JMSException {
    if (!inACC) {
      throw new com.sun.messaging.jms.JMSException("MQRA:CA:Unsupported-stop()");
    }
    checkClosed();
    xac.stop();
  }

  /*
   * @see javax.jms.Connection#close()
   */
  public void close() throws JMSException {
    _loggerOC.fine(_lgrMID_INF + "close():xacId=" + xac._getConnectionID() + ":clientId=" + xac.getClientID());

    synchronized (this) {
      if (closed) {
        return;
      }
      closed = true;
      // System.out.println("MQRA:CA:close:xac has clientID="+xac.getClientID());
      if (!xac._isClosed()) {
        xac.stop();
      }
      // Close Sessions
      synchronized (sessions) {
        Iterator<SessionAdapter> it = sessions.iterator();

        while (it.hasNext()) {
          SessionAdapter sa = it.next();
          if (sa != null) {
            sa.closeAdapter();
          }
        }
        // Clear HashSet
        sessions.clear();
        sessions_allowed = true;
        this.sa = null;
      }
      // System.out.println("MQRA:CA:close:call xac._closeForPooling()");
      try {
        if (!getManagedConnection().xaTransactionActive()){
          _loggerOC.fine(_lgrMID_INF + "close():xacId=" + xac._getConnectionID() + ":unsetting clientId");
          xac._closeForPooling();
        } else {
          // there's still an uncommitted transaction: defer the call to _closeForPooling() until after the commit
        }

      } catch (JMSException jmse) {
        System.err.println("MQRA:CA:close:Got JMSExc during _closeForPooling:ignoring:" + jmse.getMessage());
        jmse.printStackTrace();
      }
      // System.out.println("MQRA:CA:close:Sending ConClosedEvent");
      mc.sendEvent(ConnectionEvent.CONNECTION_CLOSED, null, this);
//      closed = true;
//      if (false) {
//        if (inACC) {
//          // System.out.println("MQRA:CA:close:inACC:Sending ConErrEvent");
//          mc.sendEvent(ConnectionEvent.CONNECTION_ERROR_OCCURRED, null, this);
//        }
//      }
//      if (false) { // !(inACC)
//        // Force the connection to close if it has a clientID so that the cientID can be re-used
//        // try {
//        // System.out.println("MQRA:CA:close:xac is closed="+xac._isClosed());
//        if (!xac._isClosed() && (xac._getClientID() != null)) {
//          // System.out.println("MQRA:CA:close:Sending ConErrEvent");
//          mc.sendEvent(ConnectionEvent.CONNECTION_ERROR_OCCURRED, null, this);
//        }
//        // } catch (JMSException jmse) {
//        // System.out.println("MQRA:CA:close:Got JMSExc while sending ERROR EVT");
//        // }
//      }
    }
  }

  /*
   * @see javax.jms.Connection#createConnectionConsumer(javax.jms.Destination, java.lang.String, javax.jms.ServerSessionPool, int)
   */
  public ConnectionConsumer createConnectionConsumer(Destination dest, String messageSelector,
      ServerSessionPool sessionPool, int maxMessages) throws JMSException {
    UnsupportedOperationException uoex = new UnsupportedOperationException("createConnectionConsumer");
    String code = "2";
    checkClosed();
    throw new com.sun.messaging.jms.JMSException("MQRA:CA:Unsupported-createConnectionConsumer", code, uoex);
    // return xac.createConnectionConsumer(dest, messageSelector, sessionPool, maxMessages);
  }
  /*
   * @see javax.jms.QueueConnection#createConnectionConsumer(javax.jms.Queue, java.lang.String, javax.jms.ServerSessionPool, int)
   */
  public ConnectionConsumer createConnectionConsumer(Queue queue, String messageSelector,
      ServerSessionPool sessionPool, int maxMessages) throws JMSException {
    UnsupportedOperationException uoex = new UnsupportedOperationException("createConnectionConsumer");
    String code = "2";
    checkClosed();
    throw new com.sun.messaging.jms.JMSException("MQRA:CA:Unsupported-createConnectionConsumer", code, uoex);
    // return xac.createConnectionConsumer(queue, messageSelector, sessionPool, maxMessages);
  }

  /*
   * @see javax.jms.TopicConnection#createConnectionConsumer(javax.jms.Topic, java.lang.String, javax.jms.ServerSessionPool, int)
   */
  public ConnectionConsumer createConnectionConsumer(Topic topic, String messageSelector,
      ServerSessionPool sessionPool, int maxMessages) throws JMSException {
    UnsupportedOperationException uoex = new UnsupportedOperationException("createConnectionConsumer");
    String code = "2";
    checkClosed();
    throw new com.sun.messaging.jms.JMSException("MQRA:CA:Unsupported-createConnectionConsumer", code, uoex);
    // return xac.createConnectionConsumer(topic, messageSelector, sessionPool, maxMessages);
  }

  /*
   * @see javax.jms.Connection#createDurableConnectionConsumer(javax.jms.Topic, java.lang.String, java.lang.String, javax.jms.ServerSessionPool, int)
   */
  public ConnectionConsumer createDurableConnectionConsumer(Topic topic, String subscriptionName,
      String messageSelector, ServerSessionPool sessionPool, int maxMessages) throws JMSException {
    UnsupportedOperationException uoex = new UnsupportedOperationException("createConnectionConsumer");
    String code = "2";
    checkClosed();
    throw new com.sun.messaging.jms.JMSException("MQRA:CA:Unsupported-createDurableConnectionConsumer", code, uoex);
    // return xac.createDurableConnectionConsumer(topic, subscriptionName,
    // messageSelector, sessionPool, maxMessages);
  }

  /*
   * @see javax.jms.Connection#createSession(boolean, int)
   */
  public Session createSession(boolean transacted, int acknowledgeMode) throws JMSException {
    // System.out.println("MQRA:CA:createSession()-"+transacted+":"+acknowledgeMode);
    checkClosed();
    if (sessions_allowed == false) {
      throw new com.sun.messaging.jms.JMSException(
          "MQRA:CA:createSession failed-Only one JMS Session allowed when managed connection is involved in a transaction");
    }
    try {
      if (!inACC && mc.xaTransactionActive()) {
        // no more sessions if we are not in the application client container & XA txn is active
        sessions_allowed = true; // false;
      }
    } catch (Exception ee) {
      sessions_allowed = true; // false;
    }
   
    XASessionImpl xas;
    if (ResourceAdapter._isFixCR6760301()){
      // Override arguments
      xas = (XASessionImpl) xac.createSession(overrideTransacted(transacted),
          overrideAcknowledgeMode(acknowledgeMode), (inACC ? null : mc));
    } else {
      xas = (XASessionImpl) xac.createSession((mc.xaTransactionStarted() ? true : transacted),
      acknowledgeMode, (inACC ? null : mc));
    }
   
    SessionAdapter sess_adapter = new SessionAdapter(this, xac, xas);
    addSessionAdapter(sess_adapter);
    return sess_adapter;
  }
 



  /*
   * @see javax.jms.QueueConnection#createQueueSession(boolean, int)
   */
  public QueueSession createQueueSession(boolean transacted, int acknowledgeMode) throws JMSException {
    // System.out.println("MQRA:CA:createQueueSession()-"+transacted+":"+acknowledgeMode);
    checkClosed();
    if (sessions_allowed == false) {
      throw new com.sun.messaging.jms.JMSException(
          "MQRA:CA:createQueueSession failed-Only one JMS Session allowed when managed connection is involved in a transaction");
    }
    try {
      if (!inACC && mc.xaTransactionActive()) {
        // no more sessions if we are not in the application client container & XA txn is active
        sessions_allowed = true; // false;
      }
    } catch (Exception ee) {
      sessions_allowed = true; // false;
    }
   
    XAQueueSessionImpl xas;
    if (ResourceAdapter._isFixCR6760301()){
      // Override arguments
      xas = (XAQueueSessionImpl) xac.createQueueSession(overrideTransacted(transacted),
          overrideAcknowledgeMode(acknowledgeMode), (inACC ? null : mc));
    } else {
      xas = (XAQueueSessionImpl) xac.createQueueSession((mc.xaTransactionStarted() ? true
      : transacted), acknowledgeMode, (inACC ? null : mc));
    }
   
    SessionAdapter sess_adapter = new SessionAdapter(this, xac, xas);
    sess_adapter.setQueueSession();
    addSessionAdapter(sess_adapter);
    return sess_adapter;
  }


  /*
   * @see javax.jms.TopicConnection#createTopicSession(boolean, int)
   */
  public TopicSession createTopicSession(boolean transacted, int acknowledgeMode) throws JMSException {
    // System.out.println("MQRA:CA:createTopicSession()-"+transacted+":"+acknowledgeMode);
    checkClosed();
    if (sessions_allowed == false) {
      throw new com.sun.messaging.jms.JMSException(
          "MQRA:CA:createTopicSession failed-Only one JMS Session allowed when managed connection is involved in a transaction");
    }
    try {
      if (!inACC && mc.xaTransactionActive()) {
        // no more sessions if we are not in the application client container & XA txn is active
        sessions_allowed = true; // false;
      }
    } catch (Exception ee) {
      sessions_allowed = true; // false;
    }
   
    XATopicSessionImpl xas;
    if (ResourceAdapter._isFixCR6760301()){
      // Override arguments
      xas = (XATopicSessionImpl) xac.createTopicSession(overrideTransacted(transacted),
          overrideAcknowledgeMode(acknowledgeMode), (inACC ? null : mc));
    } else {
      xas = (XATopicSessionImpl) xac.createTopicSession((mc.xaTransactionStarted() ? true
      : transacted), acknowledgeMode, (inACC ? null : mc));
    }
       
    SessionAdapter sess_adapter = new SessionAdapter(this, xac, xas);
    sess_adapter.setTopicSession();
    addSessionAdapter(sess_adapter);
    return sess_adapter;
  }
 
  private boolean overrideTransacted(boolean suppliedTransactedArgument) {
   
    if (mc.xaTransactionStarted()) return true;
   
    boolean actualTransactedArg;
    if (inACC) {
      actualTransactedArg = suppliedTransactedArgument;
    } else {
      // override args to createSession() when in an EJB or web container
      // in accordance with EJB spec section 13.3.5 "Use of JMS APIs in Transactions"
      // This isn't very clear on what happens when there is no transaction,
      // but I (Nigel) have made the decision that if XA is not being used,
      // the session should be non-transacted
      actualTransactedArg = false;
    }
    return actualTransactedArg;
  }
 
  private int overrideAcknowledgeMode(int suppliedAcknowledgeModeArgument){
    int actualAcknowledgeModeArg;
    if (inACC){
      actualAcknowledgeModeArg=suppliedAcknowledgeModeArgument;
    } else {
      if (suppliedAcknowledgeModeArgument==Session.CLIENT_ACKNOWLEDGE) {
        // EJB spec section 13.3.5 "Use of JMS APIs in Transactions" says
        // "The Bean Provider should not use the JMS acknowledge method either within a transaction
        // or within an unspecified transaction context. Message acknowledgment in an unspecified
        // transaction context is handled by the container."
        //
        // The same restriction applies in web container: JavaEE Spec: "EE.6.7 Java Message Service (JMS) 1.1 Requirements" says
        // "In general, the behavior of a JMS provider should be the same in both the EJB container and the web container.
        // The EJB specification describes restrictions on the use of JMS in an EJB container,
        // as well as the interaction of JMS with transactions in an EJB container.
        // Applications running in the web container should follow the same restrictions.
        actualAcknowledgeModeArg=Session.AUTO_ACKNOWLEDGE;
      } else {
        // allow auto-ack and dups-OK
        actualAcknowledgeModeArg=suppliedAcknowledgeModeArgument;
      }
    }
    return actualAcknowledgeModeArg;
  }

  /**
   * Check whether closed and if so throw an IllegalStateExceptio9n
   * @throws JMSException
   */
  void checkClosed() throws JMSException {
    if (closed) {
      throw new com.sun.messaging.jms.IllegalStateException("MQRA:CA:Illegal:Connection is closed");
    }
  }

  /**
   * Add the specified SessionAdapter to the set of Sessions
   * @param sa
   */
  void addSessionAdapter(SessionAdapter sa) {
    synchronized (sessions) {
      sessions.add(sa);
      if (this.sa == null) {
        this.sa = sa;
      }
      if (!inACC) {
        // no more sessions if we are not in the application client container
        sessions_allowed = false;
      }
    }
  }

  /**
   * Remove the specified SessionAdapter from the set of Sessions
   * @param sa
   */
  void removeSessionAdapter(SessionAdapter sa) {
    synchronized (sessions) {
      sessions.remove(sa);
      // Allow sessions if the only one got closed
      if (sessions_allowed == false && sessions.isEmpty()) {
        sessions_allowed = true;
        this.sa = null;
      }
    }
  }

  /**
   * @param newmc
   * @throws ResourceException
   */
  public void associateManagedConnection(com.sun.messaging.jms.ra.ManagedConnection newmc) throws ResourceException {
    if (destroyed) {
      System.err.println("MQRA:CA:associateMC:cnxn is destroyed. DebugState="
          + xac.getDebugState(false).toString());
      throw new javax.resource.spi.IllegalStateException(
          "MQRA:CA:unable to associate ManagedConnection - Connection is destoryed");
    }
    // Switch association from current mc to newmc
    if (newmc != null) {
      this.mc = newmc;
    }
  }

  /**
   *
   */
  public void destroy() {
    // System.out.println("MQRA:CA:destroy()");
    try {
      xac.close();
    } catch (JMSException jmse) {
      System.err.println("MQRA:CA:destroy:Exception on phys cnxn close-ignoring:" + jmse.getMessage());
    }
  }

  /**
   *
   */
  public void cleanup() {
    // System.out.println("MQRA:CA:cleanup()");
    // Close Sessions
    synchronized (sessions) {
      Iterator<SessionAdapter> it = sessions.iterator();

      while (it.hasNext()) {
        SessionAdapter sa = (SessionAdapter) it.next();
        if (sa != null) {
          // try {
          sa.closeAdapter();
          // } catch (JMSException jmse) {
          // System.err.println("MQRA:CA:cleanup():Exception on SessionAdapter close-ignoring"+jmse.getMessage());
          // jmse.printStackTrace();
          // }
        }
      }
      // Clear HashSet
      sessions.clear();
      sessions_allowed = true;
      this.sa = null;
    }
  }

  /**
   * @return
   */
  protected com.sun.messaging.jms.ra.ResourceAdapter getResourceAdapter() {
    return ra;
  }

  /**
   * @return
   */
  public SessionAdapter getSessionAdapter() {
    return sa;
  }

  public com.sun.messaging.jms.ra.ManagedConnection getManagedConnection() {
    return mc;
  }

  /**
   * @param clientId
   * @throws JMSException
   */
  public void open(String clientId) throws JMSException {
    synchronized (this) {
//      System.out.println("MQRA:CA:open():inACC=" + inACC + ":cid=" + clientId);
//      if (false) {
//        if ("cts".equals(clientId)) {
//          if (inACC) {
//            // System.out.println("MQRA:CA:open():inACC:setting-cts1");
//            xac._setClientID("cts1");
//          } else {
//            // System.out.println("MQRA:CA:open():NOTinACC:setting-cts2");
//            xac._setClientID("cts2");
//          }
//        } else {
//
//          xac._setClientID(clientId);
//
//        }
//      }
      xac._setClientID(clientId);
      closed = false;
    }
  }

  /**
   *
   */
  public void open() {
    closed = false;
  }

  /**
   * Check whether the connection adapter has been closed and,
   * if it has been, restore it to a state ready for returning to the pool
   *
   * @throws JMSException
   */
  public void closeForPoolingIfClosed() throws JMSException {
    if (closed){
        xac._closeForPooling();
    }
  }
}
TOP

Related Classes of com.sun.messaging.jms.ra.ConnectionAdapter

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.