package examples.jms.trader;

import java.io.*;
import java.rmi.RemoteException;
import java.util.*;
import javax.ejb.*;
import javax.jms.*;
import javax.transaction.*;
import javax.naming.*;
import examples.ejb.basic.statelessSession.*;

/**
 * This example sends a "buy" or "sell" message to a JMS Topic from the Java servlet 
 * <font face="Courier New" size = -1>TraderServlet</font>. 
 * The <font face="Courier New" size = -1>TraderReceive</font> client receives the messages and 
 * invokes an EJBean to process the messages.
 *
 * @author Copyright (c) 1999-2000 by BEA Systems, Inc. All Rights Reserved.  
 */
public class TraderReceive
{
  public final static String JNDI_FACTORY="weblogic.jndi.WLInitialContextFactory";
  public final static String JMS_FACTORY="jms.connection.traderFactory";
  public final static String EJB_HOME="statelessSession.TraderHome";
  public final static String TOPIC="javax.jms.exampleTopic";
  public final static String TX="javax.transaction.UserTransaction";

  private TopicConnectionFactory connectionFactory;
  private TopicConnection connection;
  private TopicSession session;
  private TopicSubscriber subscriber;
  private Topic topic;
  private Trader ejbTrader;
  private UserTransaction tx;

  // MessageListener interface
  public void processMessages()
  {
    while(true) {
      try {
        System.out.println("Waiting to receive message...");
        Message msg = subscriber.receive();

        if (msg instanceof MapMessage) {
          Exception e = null;
          try {
            tx.begin();
            MapMessage m = (MapMessage) msg;
            String customerName = m.getString("CustomerName"); 
            String tradeType = m.getString("TradeType");
            String symbol = m.getString("Symbol"); 
            int numberOfShares = m.getInt("Shares"); 
            try {
              TradeResult tr = null;
            
              if ("buy".equalsIgnoreCase(tradeType)) {
                tr = ejbTrader.buy(symbol, numberOfShares);
                System.out.println("Bought " + tr.getNumberTraded());
                tx.commit();
              } else {
                if ("sell".equalsIgnoreCase(tradeType)) {
                  tr = ejbTrader.sell(symbol, numberOfShares);
                  System.out.println("Sold " + tr.getNumberTraded());
                  tx.commit();
                } else {
                  System.out.println("Rolling Back Transaction");
                  tx.rollback();
                  System.out.println("Unknown TradeType: "+tradeType);
                }
              }
            } catch (RollbackException re) {
              e = re;
            } catch (HeuristicRollbackException hre) {
              e = hre;
            } catch (HeuristicMixedException hme) {
              e = hme;
            } catch (RemoteException re) {
              e = re;
            }
            if (e != null) {
              e.printStackTrace();
            }
          } catch (SystemException se) {
            e = se;
          } catch (NotSupportedException nse) {
            nse.printStackTrace();
          }
        }
      } catch (JMSException jmse) {
        try {
          tx.rollback();
        } catch (SystemException se) {}
        jmse.printStackTrace();
      }
    }
  }

  /**
   * Create all the necessary objects for receiving messages from a JMS Topic.  
   * The session is transacted so that calling the EJB occurs in the same
   * transaction as dequeueing the message.
   */
  public void init(Context ctx, String topicName)
       throws NamingException, JMSException, RemoteException, CreateException
  {
    connectionFactory = (TopicConnectionFactory) ctx.lookup(JMS_FACTORY);

    connection = connectionFactory.createTopicConnection();
    session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
    try {
      topic = (Topic) ctx.lookup(topicName);
    } catch (NamingException ne) {
      topic = session.createTopic(topicName);
      ctx.bind(topicName, topic);
    }
    subscriber = session.createDurableSubscriber(topic, "traderReceive");
    TraderHome brokerage = (TraderHome) ctx.lookup(EJB_HOME);
    ejbTrader = brokerage.create();
    tx = (javax.transaction.UserTransaction) ctx.lookup(TX);
    connection.start();
  }

  /**
   * Close JMS objects.
   */
  public void close()
       throws JMSException
  {
    subscriber.close();
    session.close();
    connection.close();
  }


  public static void main(String[] args)
       throws Exception 
  {
    if (args.length != 1) {
      System.out.println("Usage: java examples.jms.trader.TraderReceive WebLogicURL");
      return;
    }
    InitialContext ic = getInitialContext(args[0]);
    TraderReceive demo = new TraderReceive();
    demo.init(ic, TOPIC);

    demo.processMessages();
    demo.close();
  }

  private static InitialContext getInitialContext(String url)
       throws NamingException
  {
    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
    env.put(Context.PROVIDER_URL, url);
    return new InitialContext(env);
  }

}




