package ejava.transactions.demo;

import javax.ejb.SessionContext;
import javax.ejb.SessionBean;
import javax.ejb.EJBException;
import javax.naming.InitialContext;
import javax.naming.Context;
import javax.jms.MapMessage;
import javax.jms.TopicPublisher;
import javax.jms.Topic;
import javax.jms.TopicSession;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.JMSException;
import javax.rmi.PortableRemoteObject;
import java.rmi.RemoteException;

public class TellerEJB implements SessionBean {
   TopicConnection connection_;
   TopicSession session_;
   TopicPublisher publisher_;
   MapMessage msg_;
   
   public void reset(AccountRemote account) {
      try {
         msg_.setString("type", "reset");
         msg_.setString("from", account.getId());
	 publisher_.publish(msg_);

         account.reset();
      }
      catch (JMSException ex) {
         ctx_.setRollbackOnly();
         throw new EJBException("jms error with transfer", ex);
      }
      catch (RemoteException ex) {
         ctx_.setRollbackOnly();
         throw new EJBException("remote error with account", ex);
      }
   }


   public void transfer(
      AccountRemote fromAccount, AccountRemote toAccount, float amount) 
      throws AccountException {

      try {
         msg_.setString("type", "transfer");
         msg_.setString("from", fromAccount.getId());
         msg_.setString("to", toAccount.getId());
         msg_.setFloat("amount", amount);
	 publisher_.publish(msg_);

         toAccount.deposit(amount);
	 fromAccount.withdraw(amount);
//	 session_.commit();
      }
      catch (AccountException ex) {
         ctx_.setRollbackOnly();
//	 try { session_.rollback(); }
//	 catch (JMSException ignored) {}
	 throw ex;
      }
      catch (JMSException ex) {
         throw new EJBException("jms error with transfer", ex);
      }
      catch (RemoteException ex) {
         throw new EJBException("remote error with account", ex);
      }
   }

   public void ejbCreate() {
      try {
         Context jndi = new InitialContext();
         TopicConnectionFactory cFactory = (TopicConnectionFactory)
	       PortableRemoteObject.narrow(
	       jndi.lookup("java:comp/env/jms/myConnectionFactory"),
	       TopicConnectionFactory.class);
         Topic topic = (Topic)jndi.lookup("java:comp/env/jms/myTopic");

         connection_ = cFactory.createTopicConnection();
	 session_ = connection_.createTopicSession(
//	    true, TopicSession.AUTO_ACKNOWLEDGE);
	    false, TopicSession.AUTO_ACKNOWLEDGE);
         publisher_ = session_.createPublisher(topic);
	 msg_ = session_.createMapMessage();
      }
      catch (Exception ex) {
         throw new EJBException(ex);
      }
   }

   public void ejbRemove() {
      try {
         publisher_.close();
	 session_.close();
	 connection_.close();
      }
      catch (JMSException ignore) {}
   }
   public void ejbActivate() {}
   public void ejbPassivate() {}
   public void setSessionContext(SessionContext ctx) { ctx_ = ctx; }
   protected SessionContext ctx_;
}
