import java.util.*;
import java.rmi.*;
import javax.ejb.*;
import javax.jms.*;
import javax.naming.*;
import java.io.*;
import javax.rmi.*;

/**
 * Utility class for managing connections to a JMS installation.
 */
final public class NotificationBase {
	private static final boolean debug = System.getProperty("NotificationBase.debug") != null;

	//we cache TopicConnectionFactory, TopicConnection
	private static HashMap connections = new HashMap();
    private TopicConnectionFactory _factory;
	//a cached Session for creating Messages
    private TopicSession _session;

    private NotificationBase () {
    }

    public NotificationBase(TopicConnectionFactory factory) {
		if ( factory == null ) {
			throw new NullPointerException ("NotificationBase received null TopicConnectionFactory");
		}
        this._factory = factory;
    }

    private TopicConnectionFactory getFactory() {
        return _factory;
    }

    public TopicPublisher getPublisher(Topic topic)
    throws JMSException, NamingException {
	    return getSession().createPublisher(topic);
    }

    public TopicSubscriber getSubscriber(Topic topic)
    throws JMSException, NamingException {
		return getSession().createSubscriber (topic);
	}

    public synchronized ObjectMessage getObjectMessage (Serializable notification)
    throws NamingException, JMSException {
        ObjectMessage message = getCachedSession().createObjectMessage(notification);
        return message;
    }

    private TopicConnection getConnection()
    throws NamingException, JMSException {
		synchronized (connections) {
			//first check in the cache
			TopicConnection c = (TopicConnection)connections.get(getFactory());
			if (c == null ) {
//				c = getFactory().createTopicConnection("vdhanda", "vdhanda1");
				c = getFactory().createTopicConnection();
				c.setExceptionListener(new ExceptionListener () {
				    public void onException(JMSException ex) {
						System.out.println("TopicConnection on " +
							getFactory() +
							" received " +
						    ex.toString());
							if ( debug ) {
								ex.printStackTrace();
							}
				    }
				});
				System.out.println("Starting connection...");
				c.start();
				System.out.println("Connection started!");
				//update cache
				connections.put (getFactory(), c);
			}

			return c;
		}
    }

    private TopicSession getCachedSession ()
    throws JMSException, NamingException {
        if ( _session == null ) {
            _session = getSession();
        }

        return _session ;
    }

    private TopicSession getSession ()
    throws JMSException, NamingException {
		return getConnection().createTopicSession(
			false,
            Session.CLIENT_ACKNOWLEDGE);
    }

    public void close() {
        if ( _session != null ) {
            try {
                _session.close();
            }
            catch (JMSException ex) {
				System.err.println ("NotificationBase.close: " + ex.toString());
            }
            finally {
                _session = null;
            }
        }
    }

    protected void finalize() throws java.lang.Throwable {
		close();
        super.finalize();
    }

	public static void main (String[] args) {
		try {
			Context context = new InitialContext();
			TopicConnectionFactory factory =
				(TopicConnectionFactory)
					PortableRemoteObject.narrow(
						context.lookup("java:comp/env/jms/notificationFactory"),
						TopicConnectionFactory.class);
			NotificationBase base = new NotificationBase (factory);
			base.getSubscriber(
				(Topic)PortableRemoteObject.narrow(
					context.lookup("java:comp/env/jms/categoryNotification"),
					Topic.class));
		}
		catch (Exception ex) {
			ex.printStackTrace();
		}
		finally {
			System.out.println("Exiting ...");
			System.exit(0);
		}
	}
}