package com.atomikos.examples.tomcat.jms;

import java.io.IOException;

import javax.jms.Destination;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.UserTransaction;

import com.atomikos.jms.AtomikosConnectionFactoryBean;
import com.atomikos.jms.extra.AbstractJmsSenderTemplate;
import com.atomikos.jms.extra.SingleThreadedJmsSenderTemplate;
@SuppressWarnings("serial")
public class JmsDemoServlet extends HttpServlet{

	private static final String QUEUE = "jms/queue/MyQueue";
	private SingleThreadedJmsSenderTemplate senderSession;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		try {
			sendMessage("hello world");
			resp.setContentType("text/plain");
			resp.getWriter().write("Message publised on queue: "+QUEUE);
		} catch (Exception e) {
			throw new ServletException(e);
		}
		
		
	}
	
	public void init() throws ServletException {
		// create a reusable sender session
		try {
			senderSession =  createSenderTemplate();
		} catch (Exception e) {
			e.printStackTrace();
			throw new ServletException(e); 
		}
	}
	
	/**
     * Create a JMS sender template (a managed session for sending).
     * @param url The url of the ActiveMQ broker to connect to.
     * @param qName The name of the queue to send to.
     */

	private SingleThreadedJmsSenderTemplate createSenderTemplate ( )
    throws Exception
    {
        //setup the Atomikos session for sending messages on
    	SingleThreadedJmsSenderTemplate session = new SingleThreadedJmsSenderTemplate();
        session.setAtomikosConnectionFactoryBean ( lookupForConnectionFactory() );
        session.setDestination ( lookupForDestination() );
        session.init();
        return session;
    }
    
    
    private Destination lookupForDestination() throws NamingException {
    	Context initCtx = new InitialContext();
    	Context ctx = (Context) initCtx.lookup("java:comp/env");
		return (Destination) ctx.lookup(QUEUE);
	}

	private AtomikosConnectionFactoryBean lookupForConnectionFactory() throws NamingException {
		Context initCtx = new InitialContext();
		Context ctx = (Context) initCtx.lookup("java:comp/env");
		return (AtomikosConnectionFactoryBean) ctx.lookup("jms/AtomikosXAConnectionFactory");
	}

	/**
     * Send a message in a transaction.
     * @param msg The message to send.
     * @param sender The QueueSenderSession to use.
     */

	private void sendMessageInTransaction ( String text , AbstractJmsSenderTemplate sender )
    throws Exception
    {
        //get a handle to the Atomikos transaction service
    	UserTransaction userTransaction = findUserTransaction();
        userTransaction.setTransactionTimeout ( 120 );
        //start a transaction to send in
        userTransaction.begin();

        //send a message
        sender.sendTextMessage ( text );

        //commit means send, rollback means cancel
        userTransaction.commit();
    }
    
    private UserTransaction findUserTransaction() throws NamingException {
		Context initCtx = new InitialContext();
		Context ctx = (Context) initCtx.lookup("java:comp");
		return (UserTransaction) ctx.lookup("UserTransaction");
	}
    
    private void sendMessage(String textMessage) throws Exception {



		// our sender session is self-maintaining, so the following
		// can be repeated as many times as you like
		sendMessageInTransaction(textMessage, senderSession);
		System.out.println("Sent message with text: " + textMessage);

		
	}
    
    
}
