/**
 * 
 * Copyright 2004 Protique Ltd
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License. 
 * 
 **/
package org.codehaus.activemq;

import javax.jms.JMSException;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TopicSession;
import javax.jms.XAConnection;
import javax.jms.XAQueueConnection;
import javax.jms.XAQueueSession;
import javax.jms.XASession;
import javax.jms.XATopicConnection;
import javax.jms.XATopicSession;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.activemq.message.ResponseReceipt;
import org.codehaus.activemq.message.TransactionInfo;
import org.codehaus.activemq.message.XATransactionInfo;
import org.codehaus.activemq.transport.TransportChannel;

/**
 * The XAConnection interface extends the capability of Connection by providing
 * an XASession (optional).
 * <p/>
 * The XAConnection interface is optional. JMS providers are not required to
 * support this interface. This interface is for use by JMS providers to
 * support transactional environments. Client programs are strongly encouraged
 * to use the transactional support  available in their environment, rather
 * than use these XA  interfaces directly.
 *
 * @version $Revision: 1.5 $
 * @see javax.jms.Connection
 * @see javax.jms.ConnectionFactory
 * @see javax.jms.QueueConnection
 * @see javax.jms.TopicConnection
 * @see javax.jms.TopicConnectionFactory
 * @see javax.jms.QueueConnection
 * @see javax.jms.QueueConnectionFactory
 */
public class ActiveMQXAConnection extends ActiveMQConnection implements XATopicConnection, XAQueueConnection, XAConnection {

    private static final Log log = LogFactory.getLog(ActiveMQXAConnection.class);
    private final String resourceManagerId;

	public ActiveMQXAConnection(ActiveMQConnectionFactory factory, String theUserName, String thePassword, TransportChannel transportChannel) throws JMSException {
        super(factory, theUserName, thePassword, transportChannel);
        resourceManagerId = determineResourceManagerId();
    }

    public ActiveMQXAConnection(ActiveMQConnectionFactory factory, String theUserName, String thePassword) throws JMSException {
        super(factory, theUserName, thePassword);
        resourceManagerId = determineResourceManagerId();
    }

    
    /**
     * Get's the resource manager id.
     */
    private String determineResourceManagerId() throws JMSException {

        XATransactionInfo info = new XATransactionInfo();
        info.setId(this.packetIdGenerator.generateId());
        info.setType(TransactionInfo.GET_RM_ID);

        ResponseReceipt receipt = (ResponseReceipt) syncSendRequest(info);
        String rmId = (String) receipt.getResult();
        assert rmId != null;
        return rmId;
    }

    public XASession createXASession() throws JMSException {
        return createActiveMQXASession(Session.SESSION_TRANSACTED);
    }

    public QueueSession createQueueSession(boolean transacted, int acknowledgeMode) throws JMSException {
        return new ActiveMQQueueSession(createActiveMQXASession(acknowledgeMode));
    }

    public TopicSession createTopicSession(boolean transacted, int acknowledgeMode) throws JMSException {
        return new ActiveMQTopicSession(createActiveMQXASession(acknowledgeMode));
    }

    public Session createSession(boolean transacted, int acknowledgeMode) throws JMSException {
        return createActiveMQXASession(acknowledgeMode);
    }

    public XATopicSession createXATopicSession() throws JMSException {
        return createActiveMQXASession(Session.SESSION_TRANSACTED);
    }

    public XAQueueSession createXAQueueSession() throws JMSException {
        return createActiveMQXASession(Session.SESSION_TRANSACTED);
    }

    protected ActiveMQXASession createActiveMQXASession(int acknowledgeMode) throws JMSException {
        checkClosed();
        sendConnectionInfoToBroker();
        return new ActiveMQXASession(this, acknowledgeMode);
    }

    /**
     * @return Returns the resourceManagerId.
     */
    public String getResourceManagerId() {
        return resourceManagerId;
    }
}