package AKSpackage;
import javax.ejb.EntityBean;
import javax.ejb.EntityContext;
import javax.ejb.CreateException;
import javax.ejb.FinderException;
import javax.ejb.RemoveException;
import javax.ejb.EJBHome;
import javax.ejb.Handle;
import javax.ejb.EJBObject;
import java.util.*;
import java.rmi.*;
import java.sql.*;
import javax.sql.*;
import javax.naming.*;

public class sampleBMPBean implements EntityBean 
{
  // sampleBMPBean.java

    // Database related variables...
    private Connection databaseConn;
    private DataSource theDataSource;    
    private PreparedStatement prepStatement;
    private static final String DATA_SOURCE_NAME = "sampleBMPDS";
    private boolean dirty = false;


    public EntityContext ctx;
    private String code;
    private String name;
    private String email;

    private static final String BMP_INSERT_STATEMENT =
      "INSERT INTO CUSTOMER (CODE, NAME, EMAIL) VALUES (?, ?, ?)";
    private static final String BMP_UPDATE_STATEMENT =
      "UPDATE CUSTOMER SET NAME=?, EMAIL=? WHERE CODE=?";
    private static final String BMP_DELETE_STATEMENT =
      "DELETE FROM CUSTOMER WHERE CODE=?";
    private static final String BMP_FIND_ALL_STATEMENT =
      "SELECT CODE, NAME, EMAIL FROM CUSTOMER";
    private static final String BMP_FIND_PK_STATEMENT =
      "SELECT CODE, NAME, EMAIL FROM CUSTOMER WHERE CODE = ?";
    private static final String BMP_FIND_EMAIL_STATEMENT =
      "SELECT CODE FROM CUSTOMER WHERE EMAIL = ?";

    public sampleBMPBean()
    {
      // Empty constructor, don't initialize here but in the create().
      // passivate() may destroy these attributes in the case of pooling
    }

    public String ejbCreate(String code, String name, String email)
      throws CreateException, RemoteException
    {
    	
    
      this.name = name;
      this.code = code;
      this.email = email;
      
      System.out.println("sampleBMPBean.ejbCreate(): " + code + " " + name + " " + email);
      try {
        databaseConn = getDatabaseConnection(DATA_SOURCE_NAME);
        prepStatement = databaseConn.prepareStatement(BMP_INSERT_STATEMENT);
        prepStatement.setString(1, code);
        prepStatement.setString(2, name);
        prepStatement.setString(3, email);
        prepStatement.executeUpdate();
        dirty = false;
        return code;
        
      } catch (SQLException sqlE) {
      	try {
      	  ejbFindByPrimaryKey(this.code);
      	  throw new javax.ejb.DuplicateKeyException("key: " + code );
      	} catch ( Exception ig1 ) {
      	  // ignore exception
      	}
      	
      	try { 
          String w = databaseConn.getWarnings().toString(); 
          throw new CreateException("Error Creating Bean:" + sqlE.getMessage() + " SQL Warnings" + w );
        } catch (Exception ig2) {} 
        
      } finally {
        try { prepStatement.close();} catch (Exception e) {}
        try { databaseConn.close(); } catch (Exception e) {}
      }
      return code;
    }

    public void ejbPostCreate(String code, String name, String email)
      throws CreateException, RemoteException
    {
      //System.out.println("sampleBMPBean.ejbPostCreate(): begin");
    }

    public String ejbFindByPrimaryKey(String key)
      throws FinderException, RemoteException
    {
      if (key == null) {
        throw new FinderException("Primary key cannot be null");
      }
      try {
        databaseConn = getDatabaseConnection(DATA_SOURCE_NAME);
        prepStatement = databaseConn.prepareStatement(BMP_FIND_PK_STATEMENT);
        prepStatement.setString(1, key);
        prepStatement.executeQuery();
        ResultSet rs = prepStatement.getResultSet();
        if (rs.next()) {
          code = rs.getString(1);
          name = rs.getString(2);
          email = rs.getString(3);
        //System.out.println("sampleBMPBean.ejbfindByPrimaryKey()" + " " + code + " " + name + " " + email);
        } else {
          throw new FinderException("Failed to select this key: " + key );
        }
      } catch (SQLException e) {
        throw new FinderException(e.getMessage());
      } finally {
        try { prepStatement.close();} catch (Exception e) {}
        try { databaseConn.close(); } catch (Exception e) {}
      }
      return code;
    }

    public Collection ejbFindAll() throws FinderException, RemoteException
    {
      //System.out.println("sampleBMPBean.ejbFindAll(): begin");
      Vector recs = new Vector();
      try {
        databaseConn = getDatabaseConnection(DATA_SOURCE_NAME);
        prepStatement = databaseConn.prepareStatement(BMP_FIND_ALL_STATEMENT);
        prepStatement.executeQuery();
        ResultSet rs = prepStatement.getResultSet();

        while (rs.next()) {
          recs.add(rs.getString(1));
        }
        
      } catch (SQLException e) {
        throw new FinderException(e.getMessage());
      } finally {
        try { prepStatement.close();} catch (Exception e) {}
        try { databaseConn.close(); } catch (Exception e) {}      
      }
      return recs;
    }

    public String ejbFindByEmail(String email)
      throws FinderException, RemoteException
    {
      //System.out.println("sampleBMPBean.ejbFindByName(): begin");
      if (email == null) {
        throw new FinderException("email cannot be null");
      }

      try {
        databaseConn = getDatabaseConnection(DATA_SOURCE_NAME);
        prepStatement = databaseConn.prepareStatement(BMP_FIND_EMAIL_STATEMENT);
        prepStatement.setString(1, email);
        prepStatement.executeQuery();
        ResultSet rs = prepStatement.getResultSet();
        
        if (rs.next()) {
          code = rs.getString(1);
        }
        
      } catch (SQLException e) {
        throw new FinderException(e.getMessage());
      } finally {
        try { prepStatement.close();} catch (Exception e) {}
        try { databaseConn.close(); } catch (Exception e) {}      
      }
      return code;
    }

    public void ejbLoad() throws RemoteException
    {
      //Container invokes this method to instruct the instance to
      //synchronize its state by loading it from the underlying database
      //System.out.println("sampleBMPBean.ejbLoad(): begin");
      try {
        String key = (String) ctx.getPrimaryKey();
        ejbFindByPrimaryKey(key);
      } catch (FinderException e) {
        throw new RemoteException (e.getMessage());
      }
    }

    public void ejbStore() throws RemoteException
    {
      //Container invokes this method to instruct the instance to
      //synchronize its state by storing it to the underlying database
      //System.out.println("sampleBMPBean.ejbStore(): begin");
      if ( dirty == false ) return;
      try {
        code = (String) ctx.getPrimaryKey();
        databaseConn = getDatabaseConnection(DATA_SOURCE_NAME);
        prepStatement = databaseConn.prepareStatement(BMP_UPDATE_STATEMENT);
        prepStatement.setString(1, name);
        prepStatement.setString(2, email);
        prepStatement.setString(3, code);
        if (prepStatement.executeUpdate() != 1) {
          throw new RemoteException("Failed to update record");
        }
      } catch (SQLException e) {
        throw new RemoteException(e.getMessage());
      } finally {
        try { prepStatement.close();} catch (Exception e) {}
        try { databaseConn.close(); } catch (Exception e) {}            
      }
      dirty = false;
    }

    public void ejbRemove() throws RemoveException, RemoteException
    {
      //Container invokes this method befor it removes the EJB object
      //that is currently associated with the instance
      //System.out.println("sampleBMPBean.ejbRemove(): begin");
      try {
        code = (String) ctx.getPrimaryKey();
        databaseConn = getDatabaseConnection(DATA_SOURCE_NAME);
        prepStatement = databaseConn.prepareStatement(BMP_DELETE_STATEMENT);
        prepStatement.setString(1, code);
        if (prepStatement.executeUpdate() != 1) {
          throw new RemoteException("Failed to delete record");
        }
      } catch (SQLException e) {
        throw new RemoteException(e.getMessage());
      } finally {
        try { prepStatement.close();} catch (Exception e) {}
        try { databaseConn.close(); } catch (Exception e) {}    
      }
    }

    public void ejbActivate() throws RemoteException
    {
      // Container invokes this method when the instance is taken out
      // of the pool of available instances to become associated with
      // a specific EJB object
      System.out.println("sampleBMPBean.ejbActivate(): begin");
    }

    public void ejbPassivate()
    {
      // Container invokes this method on an instance before the instance
      // becomes disassociated with a specific EJB object
      System.out.println("sampleBMPBean.ejbPassivate(): begin");
    }

    /*
      TO DO 
      MOVE ALL OF THE SQL STRINGS AS CONTEXT VARIABLES SO THEY
      CAN BE EASILY CONFIGURED BY THE USER...
    **/
    public void setEntityContext(EntityContext ctx)
    {
      //Set the associated entity context
      System.out.println("sampleBMPBean.setEntityContext(): begin");
      this.ctx = ctx;
      
      // TO DO 
      // MOVE ALL OF THE SQL STRINGS AS CONTEXT VARIABLES SO THEY
      // CAN BE EASILY CONFIGURED BY THE USER...
      // this will preload the DataSource and the Initial Context Load
      try { 
        getDatabaseConnection(DATA_SOURCE_NAME);
        } catch ( Exception e) {
          System.out.println("sampleBMPBean.setEntityContext(): " +
                e.getLocalizedMessage());
        }

    }

    public void unsetEntityContext()
    {
      //Unset the associated entity context
      System.out.println("sampleBMPBean.unsetEntityContext(): begin");
      this.ctx = null;
    }

    /**
     * GETTERS AND SETTERS
     */
    public String getCode()
    {
      code = (String) ctx.getPrimaryKey();
      return this.code;
    }

    public String getName()
    {
      return this.name;
    }
    
    public String getEmail()
    {
      return this.email;
    }

    public void setCode(String code)
    {
      this.code = code;
    }

    public void setName(String name)
    {
      this.name = name;
    }

    public void setEmail(String email) {
      this.email = email;
    }

    public EJBHome getEJBHome()
    {
      return ctx.getEJBHome();
    }

    public Handle getHandle() throws RemoteException
    {
      return ctx.getEJBObject().getHandle();
    }

    public Object getPrimaryKey() throws RemoteException
    {
      return ctx.getEJBObject().getPrimaryKey();
    }

    public boolean isIdentical(EJBObject remote) throws RemoteException
    {
      return ctx.getEJBObject().isIdentical(remote);
    }

    public void remove() throws RemoveException, RemoteException {
      ctx.getEJBObject().remove();
    }
    

  private Connection getDatabaseConnection(String dsName)
       throws SQLException, RemoteException
  {
    
    try {
      if ( theDataSource == null ) {  	
        Context ic = new InitialContext();
        theDataSource = (DataSource) ic.lookup(dsName);
	  }     
    } catch (Exception e) {
      e.printStackTrace();
      throw new RemoteException("IN sampleBMPBean.getDatabaseConnection() " + e.getMessage());
    }
    return theDataSource.getConnection();
  }  
}