package ejava.examples.uid.ejb;

import javax.ejb.EntityBean;
import javax.ejb.EntityContext;
import javax.ejb.EJBException;
import javax.naming.InitialContext;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.rmi.RemoteException;

/**
   This bean class manages the generation of a unique id for client
   accessors. It uses BMP to manage interaction with the tracked
   sequence number in the database.
*/
public class UIDGeneratorEJB 
   implements UIDGeneratorLBI, UIDGeneratorBI, EntityBean {
   private DataSource dataSource_;
   private String tableName_;
   private int sequenceNum_;

   /**
      There is only one UIDGenerator. It will logically be assigned a 
      primary key value of 0.
   */
   public Integer ejbFind() {
      return new Integer(0);
   }

   public Integer ejbFindByPrimaryKey(Integer dummy) {
      return new Integer(0);
   }

   /**
      Creates a unique UID.
   */
   public UID createUID() {
      return new UID(String.valueOf(++sequenceNum_)); 
   }

   /**
      Loads the previous UID value handed out.
   */
   public void ejbLoad() {
      Connection connection = null;
      Statement statement = null;
      ResultSet rs = null;
      try {
         connection = dataSource_.getConnection();
         statement = connection.createStatement();
	 rs = statement.executeQuery(
	    "select seqNum from " + tableName_ + " for update");
         rs.next();
	 sequenceNum_ = rs.getInt(1);
      }
      catch (SQLException ex) {
         throw new EJBException("error loading sequence value:"+ex);
      }
      finally {
         try {
            if (rs != null) rs.close();
            if (statement != null) statement.close();
            if (connection != null) connection.close();
         }
	 catch (SQLException ex) {
	    throw new EJBException("error releasing resources:"+ex);
	 }
      }
   }

   /**
      Stores the last value handed out.
   */
   public void ejbStore() {
      Connection connection = null;
      Statement statement = null;
      ResultSet rs = null;
      try {
         connection = dataSource_.getConnection();
         statement = connection.createStatement();
	 statement.executeUpdate(
	    "update " + tableName_ + " set seqNum = " + sequenceNum_);
      }
      catch (SQLException ex) {
         throw new EJBException("error saving sequence value:"+ex);
      }
      finally {
         try {
            if (rs != null) rs.close();
            if (statement != null) statement.close();
            if (connection != null) connection.close();
         }
	 catch (SQLException ex) {
	    throw new EJBException("error releasing resources:"+ex);
	 }
      }
   }
   
   public void ejbPassivate() {}
   public void ejbActivate() {}

   /**
      Clients don't create or remove UIDGenerators. They just find the
      one and only instance and use it.
   */
   public void ejbRemove() { 
      throw new EJBException("cannot remove UIDGenerators"); 
   }

   private EntityContext entityCtx_;
   public void setEntityContext(EntityContext entityCtx) {
      entityCtx_ = entityCtx;

      try {
         Context ctx = new InitialContext();
	 dataSource_ = (DataSource)ctx.lookup("java:comp/env/jdbc/uidDB");
	 tableName_  = (String)ctx.lookup("java:comp/env/jdbc/tableName");
      }
      catch (NamingException ex) {
         throw new EJBException("error configuring UIDGeneratorBean:"+ex);
      }
   }
   public void unsetEntityContext() { entityCtx_ = null; }
}
