/* JFox, the OpenSource J2EE Application Server
 *
 * Distributable under GNU LGPL license by gun.org
 * more details please visit http://www.huihoo.org/jfox
 */

package org.jfox.jms;

import java.io.Serializable;
import java.rmi.RemoteException;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.XAConnection;
import javax.jms.XAConnectionFactory;
import javax.jms.XAQueueConnection;
import javax.jms.XAQueueConnectionFactory;
import javax.jms.XATopicConnection;
import javax.jms.XATopicConnectionFactory;

import org.jfox.jms.connector.ConnectorHelper;
import org.jfox.jms.connector.JMSConnectorService;
import org.jfox.jms.connector.Protocol;
import org.jfox.jndi.InitialContextHelper;

/**
 * @author <a href="mailto:young_yy@hotmail.com">Young Yang</a>
 */

public class JMSConnectionFactory implements
        ConnectionFactory,
        QueueConnectionFactory,
        TopicConnectionFactory,
        XAConnectionFactory,
        XAQueueConnectionFactory,
        XATopicConnectionFactory,
        Serializable {
    protected Protocol protocol = Protocol.JRMP;

    private JMSConnectorService broker = null;

    public Connection createConnection() throws JMSException {
        return createConnection(null, null);
    }

    public Connection createConnection(String userName, String password) throws JMSException {
        return createConnection(userName, password, protocol, false);
    }

    public QueueConnection createQueueConnection() throws JMSException {
        throw new JMSException("not support now!");
    }

    public QueueConnection createQueueConnection(String userName, String password) throws JMSException {
        throw new JMSException("not support now!");
    }

    public TopicConnection createTopicConnection() throws JMSException {
        throw new JMSException("not support now!");
    }

    public TopicConnection createTopicConnection(String userName, String password) throws JMSException {
        throw new JMSException("not support now!");
    }

    public XAConnection createXAConnection() throws JMSException {
        return createXAConnection(null, null);
    }

    public XAConnection createXAConnection(String userName, String password) throws JMSException {
        return createConnection(userName, password, protocol, true);
    }

    public XAQueueConnection createXAQueueConnection() throws JMSException {
        throw new JMSException("not support now!");
    }

    public XAQueueConnection createXAQueueConnection(String userName, String password) throws JMSException {
        throw new JMSException("not support now!");
    }

    public XATopicConnection createXATopicConnection() throws JMSException {
        throw new JMSException("not support now!");
    }

    public XATopicConnection createXATopicConnection(String userName, String password) throws JMSException {
        throw new JMSException("not support now!");
    }

    public void setProtocol(Protocol protocol) {
        this.protocol = protocol;
    }

    /**
     * first lookup the Stub by proptocol
     * then run the ping
     *
     * @return
     * @throws JMSException
     */
    protected synchronized JMSConnection createConnection(String userName, String password, Protocol protocol, boolean isXA) throws JMSException {
        if(broker == null) {
            broker = lookupConnectorService(protocol);
        }
        try {
            broker.ping();
        }
        catch(RemoteException e) {
            e.printStackTrace();
            throw new JMSException("create connection with protocol " + protocol + " failed: " + e.getMessage());
        }
        JMSConnection conn = new JMSConnection(broker, isXA);
        return conn;
    }

    /**
     * lookup ConnectorService from jndi
     *
     * @param protocol
     * @return
     */
    private JMSConnectorService lookupConnectorService(Protocol protocol) {
        try {
            Object obj = InitialContextHelper.getInitialContext().lookup(ConnectorHelper.getConnectorJNDIName(protocol));
            JMSConnectorService broker = (JMSConnectorService) javax.rmi.PortableRemoteObject.narrow(obj, JMSConnectorService.class);
            return broker;
        }
        catch(Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static void main(String[] args) {

    }
}