/*
 * JORAM: Java(TM) Open Reliable Asynchronous Messaging
 * Copyright (C) 2002 INRIA
 * Contact: joram-team@objectweb.org
 * 
 * This library 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 any later version.
 * 
 * This library 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 library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 * 
 * Initial developer(s): Jeff Mesnil (jmesnil@inrialpes.fr)
 * Contributor(s): Andreas Mueller <am@iit.de>.
 */

package org.objectweb.jtests.jms.conform.session;

import org.objectweb.jtests.jms.framework.*;
import junit.framework.*;

import javax.jms.*;
import java.util.Hashtable;

/**
 * Test topic sessions
 * <br />
 * See JMS specifications, §4.4 Session
 * 
 * @author Jeff Mesnil (jmesnil@inrialpes.fr)
 * @version $Id: TopicSessionTest.java,v 1.3 2003/08/27 04:33:33 patriot1burke Exp $
 */
public class TopicSessionTest extends PubSubTestCase {

    /**
     * Test that if we rollback a transaction which has consumed a message,
     * the message is effectively redelivered.
     */
    public void testRollbackReceivedMessage() {
	try {
	    publisherConnection.stop();
	    // publisherSession has been declared has non transacted
	    // we recreate it as a transacted session
	    publisherSession = publisherConnection.createTopicSession(true,0);
	    assertEquals(true, publisherSession.getTransacted());
	    // we also recreate the publisher
	    publisher = publisherSession.createPublisher(publisherTopic);
	    publisherConnection.start();
      
	    subscriberConnection.stop();
	    // subscriberSession has been declared has non transacted
	    // we recreate it as a transacted session
	    subscriberSession = subscriberConnection.createTopicSession(true,0);
	    assertEquals(true, subscriberSession.getTransacted());
	    // we also recreate the subscriber
	    subscriber = subscriberSession.createSubscriber(subscriberTopic);
	    subscriberConnection.start();
      
	    // we create a message...
	    TextMessage message = publisherSession.createTextMessage();
	    message.setText("testRollbackReceivedMessage");
	    // ... publish it ...
	    publisher.publish(message);
	    // ... and commit the transaction
	    publisherSession.commit();
      
	    // we receive it
	    Message msg1 = subscriber.receive(1000);
	    assertTrue("no message received", msg1 != null);
	    assertTrue(msg1 instanceof TextMessage);
	    assertEquals("testRollbackReceivedMessage", ((TextMessage)msg1).getText());
	
	    // we rollback the transaction of subscriberSession
	    subscriberSession.rollback();
      
	    // we expect to receive a second time the message
	    Message msg2 = subscriber.receive(1000);
	    assertTrue("no message received after rollbacking subscriber session.", msg2 != null);
	    assertTrue(msg2 instanceof TextMessage);
	    assertEquals("testRollbackReceivedMessage", ((TextMessage)msg2).getText());
      
      
	    // finally we commit the subscriberSession transaction
	    subscriberSession.commit();
	} catch (Exception e) {
	    fail(e);
	}
    }

    /**
     * Test that a durable subscriber effectively receives the messages sent to its
     * topic while it was inactive.
     */
    public void testDurableSubscriber() {
	try {
	    subscriber = subscriberSession.createDurableSubscriber(subscriberTopic,"testTopic");
	    subscriberConnection.close();
	    subscriberConnection = null;
      
	    TextMessage message = publisherSession.createTextMessage();
	    message.setText("test");
	    publisher.publish(message);

	    subscriberConnection = subscriberTCF.createTopicConnection();
	    if (subscriberConnection.getClientID() == null) {
		subscriberConnection.setClientID("subscriberConnection");
	    }	    
	    subscriberSession = subscriberConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
	    subscriber = subscriberSession.createDurableSubscriber(subscriberTopic, "testTopic");
	    subscriberConnection.start();

	    TextMessage m = (TextMessage)subscriber.receiveNoWait();
	    assertTrue(m != null);
	    assertEquals("test", m.getText());
	} catch (JMSException e) {
	    fail(e);
	}
      finally
      {
         try
         {
            subscriberSession.unsubscribe("testTopic");
         }
         catch (JMSException e)
         {
            fail(e);
         }
      } 
    }

    /**
     * Test the unsubscription of a durable subscriber.
     */
    public void testUnsubscribe() {
	try {
	    subscriber = subscriberSession.createDurableSubscriber(subscriberTopic,"topic");
	    subscriber.close();
	    // nothing should happen when unsubscribing the durable subscriber
	    subscriberSession.unsubscribe("topic");
	} catch (JMSException e) {
	    fail(e);
	}
    }

    /**
     * Test that a call to the <code>createDurableSubscriber()</code> method with an invalid
     * message selector throws a <code>javax.jms.InvalidSelectorException</code>.
     */
    public void testCreateDurableSubscriber_2() {
	try {
	    subscriberSession.createDurableSubscriber(subscriberTopic, 
						      "topic",
						      "definitely not a message selector!",
						      true);
	    fail("Should throw a javax.jms.InvalidSelectorException.\n");
	} catch (InvalidSelectorException e) {
	} catch (JMSException e) {
	    fail("Should throw a javax.jms.InvalidSelectorException, not a "+ e);
	}
    }

    /**
     * Test that a call to the <code>createDurableSubscriber()</code> method with an invalid
     * <code>Topic</code> throws a <code>javax.jms.InvalidDestinationException</code>.
     */
    public void testCreateDurableSubscriber_1() {
	try {
	    subscriberSession.createDurableSubscriber((Topic)null, "topic");
	    fail("Should throw a javax.jms.InvalidDestinationException.\n");
	} catch (InvalidDestinationException e) {
	} catch (JMSException e) {
	    fail("Should throw a javax.jms.InvalidDestinationException, not a "+ e);
	}
    }

    /**
     * Test that a call to the <code>createSubscriber()</code> method with an invalid
     * message selector throws a <code>javax.jms.InvalidSelectorException</code>.
     */
    public void testCreateSubscriber_2() {
	try {
	    subscriberSession.createSubscriber(subscriberTopic, 
					       "definitely not a message selector!",
					       true);
	    fail("Should throw a javax.jms.InvalidSelectorException.\n");
	} catch (InvalidSelectorException e) {
	} catch (JMSException e) {
	    fail("Should throw a javax.jms.InvalidSelectorException, not a "+ e);
	}
    }

    /**
     * Test that a call to the <code>createSubscriber()</code> method with an invalid
     * <code>Topic</code> throws a <code>javax.jms.InvalidDestinationException</code>.
     */
    public void testCreateSubscriber_1() {
	try {
	    subscriberSession.createSubscriber((Topic)null);
	    fail("Should throw a javax.jms.InvalidDestinationException.\n");
	} catch (InvalidDestinationException e) {
	} catch (JMSException e) {
	    fail("Should throw a javax.jms.InvalidDestinationException, not a "+ e);
	}
    }
    
    /** 
     * Method to use this class in a Test suite
     */
    public static Test suite() {
	return new TestSuite(TopicSessionTest.class);
    }
  
    public TopicSessionTest(String name) {
	super(name);
    }
}
