package jwsunleashed.trading.ejb;

import java.rmi.*;
import java.util.*;
import javax.ejb.*;
import java.sql.*;
import javax.sql.*;
import javax.naming.*;

public abstract class AutoKeyEJB implements EntityBean
{
/** The entity context provided by the EJB container. An entity bean must
    hold on to the context it is given. */

    private EntityContext context;

/** The database connection used by this entity bean */

    private Connection conn;

/** An EJB must have a public, parameterless constructor */

    public AutoKeyEJB()
    {
    }

/** Called by the EJB container to set this entity's context */

    public void setEntityContext(EntityContext aContext)
    {
        context = aContext;
    }

/** Called by the EJB container to clear this entity's context */

    public void unsetEntityContext()
    {
        context = null;
    }

/** Returns the name of the database to use for retrieving the new key */
    public abstract String getKeyDatabaseName();

/** Returns the name of the table to use for retrieving the new key.
    Use this method if your database doesn't support sequences */
    public abstract String getKeyTableName();

/** Returns the name of the key column in the key table or sequence */
    public abstract String getKeyColumnName();

/** Called by the EJB container when a client calls the create() method in
    the home interface */

    public abstract Integer ejbCreate()
        throws CreateException;

/** Called by the EJB container after ejbCreate to allow the bean to do
    any additional setup that may be required. */
    public void ejbPostCreate()
        throws CreateException
    {
    }

/** Called by the EJB container to tell put the bean into active mode */

    public void ejbActivate()
        throws EJBException
    {
    }

/** Called by the EJB container to tell this bean that it is being
    deactivated and placed back into the pool */

    public void ejbPassivate()
        throws EJBException
    {
    }

/** Called by the container to tell the entity bean to read its data from
    the database */

    public void ejbLoad()
        throws EJBException
    {
    }

/** Called by the EJB container to tell the entity bean to
    write its data out to the database */
    public void ejbStore()
        throws EJBException
    {
    }

/** Called by the EJB container to tell this bean that it has been
    removed. */

    public void ejbRemove()
        throws EJBException
    {
    }

/** Although this class uses CMP, you still need to locate a connection
 *  in order to generate the primary key (Person generates its own unique
 *  id automatically.
 */
    protected Connection getConnection()
        throws SQLException, NamingException
    {
// Get a reference to the naming service
        InitialContext context = new InitialContext();

// Get the data source for the database
        DataSource ds = (DataSource) context.lookup(
            "java:comp/env/jdbc/"+getKeyDatabaseName());

// Ask the data source to allocate a database connection
        return ds.getConnection();
    }

/** Uses a separate database table to generate a unique ID number.
    You should perform the update before you read the value
    to make sure you don't have any locking problems.
    */
    protected int getNextId()
        throws SQLException
    {
        Connection conn = null;

        try
        {
            conn = getConnection();

// Increment the next ID number
            PreparedStatement ps = conn.prepareStatement(
                "update "+getKeyTableName()+" set "+
                getKeyColumnName()+" = "+getKeyColumnName()+" + 1");
            
            if (ps.executeUpdate() != 1)
            {
                throw new SQLException("Unable to generate "+getKeyColumnName());
            }

            ps.close();

// Read the next ID number
            ps = conn.prepareStatement(
                "select "+getKeyColumnName()+" from "+getKeyTableName());

            ResultSet rs = ps.executeQuery();

            if (rs.next())
            {
                return rs.getInt(getKeyColumnName());
            }
            else
            {
                throw new SQLException("Unable to generate id "+getKeyColumnName());
            }
        }
        catch (NamingException exc)
        {
            exc.printStackTrace();
            throw new SQLException("Unable to generate id", exc.toString());
        }
        finally
        {
            try
            {
                conn.close();
            }
            catch (Exception ignore) {}
        }
    }
}
