/*
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 1999 Bull S.A.
 * Contact: jonas-team@objectweb.org
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

package org.objectweb.jonas.jtests.beans.jdbcra;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Enumeration;
import java.util.Vector;

import javax.ejb.CreateException;
import javax.ejb.EJBException;
import javax.ejb.EntityBean;
import javax.ejb.EntityContext;
import javax.ejb.FinderException;
import javax.ejb.ObjectNotFoundException;
import javax.ejb.RemoveException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;

import org.objectweb.jonas.common.Log;
import org.objectweb.util.monolog.api.BasicLevel;
import org.objectweb.util.monolog.api.Logger;

/**
 *
 */

public class JdbcRA2EBRBean implements EntityBean {

    private DataSource dataSource2 = null;

    static private Logger logger = null;
    EntityContext ejbContext;

    // ------------------------------------------------------------------
    // State of the bean. 
    // 
    // ------------------------------------------------------------------

    public Integer accno;
    public String customer;
    public double balance;

    // ------------------------------------------------------------------
    // EntityBean implementation
    // ------------------------------------------------------------------

    public void setEntityContext(EntityContext ctx) {

        if (logger == null) {
            logger = Log.getLogger("org.objectweb.jonas_tests");
        }
        logger.log(BasicLevel.DEBUG, "");
        ejbContext = ctx;
    }

    public void unsetEntityContext() {
        logger.log(BasicLevel.DEBUG, "");
        ejbContext = null;
    }
    
    public void ejbRemove() throws RemoveException {
        logger.log(BasicLevel.DEBUG, "");

        // Access database to remove bean in table

        Connection conn = null;
        PreparedStatement stmt = null;

	try {
	    // get a connection for this transaction context

            conn = getConnection();

	    // delete Object in DB

	    stmt = conn.prepareStatement("delete from jdbc_xa2 where xa_accno=?");
	    Integer pk = (Integer) ejbContext.getPrimaryKey();
	    stmt.setInt(1, pk.intValue());
	    stmt.executeUpdate();
	} catch (SQLException e) {
	    throw new RemoveException ("Failed to delete bean from database"+e);
	} finally {
	    try {
		if (stmt != null) stmt.close();       // close statement
		if (conn != null) conn.close();       // release connection
	    } catch (Exception ignore) {
	    }
	}
    }

    public void ejbLoad() {
        logger.log(BasicLevel.DEBUG, "");

        // Access database to load bean state from table

        Connection conn = null;
        PreparedStatement stmt = null;

	try {
	    // get a connection for this transaction context

            conn = getConnection();

	    // find account in DB

	    stmt = conn.prepareStatement("select xa_customer,xa_balance from jdbc_xa2 where xa_accno=?");
	    Integer pk = (Integer) ejbContext.getPrimaryKey();
	    stmt.setInt(1, pk.intValue());
	    ResultSet rs = stmt.executeQuery();

            if (rs.next() == false) {
                throw new EJBException("Failed to load bean from database");
            }

	    // update object state

	    accno = pk;
	    customer = rs.getString("xa_customer");
	    balance  = rs.getDouble("xa_balance");

	} catch (SQLException e) {	
	    throw new EJBException("Failed to load bean from database "+e);
	} finally {
	    try {
		if (stmt != null) stmt.close();       // close statement
		if (conn != null) conn.close();       // release connection
	    } catch (Exception ignore) {
	  }
	}

    }

    public void ejbStore() {
        logger.log(BasicLevel.DEBUG, "");

        // Access database to store bean state in table

        Connection conn = null;
        PreparedStatement stmt = null;

	try {
	    // get a connection for this transaction context

            conn = getConnection();

	    // store Object state in DB

	    stmt = conn.prepareStatement("update jdbc_xa2 set xa_customer=?,xa_balance=? where xa_accno=?");
	    stmt.setString(1, customer);
	    stmt.setDouble(2, balance);
	    Integer pk = (Integer) ejbContext.getPrimaryKey();
	    stmt.setInt(3, pk.intValue());
	    stmt.executeUpdate();

	} catch (SQLException e) {
	    throw new EJBException("Failed to store bean to database "+e);
	} finally {
	    try {
		if (stmt != null) stmt.close();       // close statement
		if (conn != null) conn.close();       // release connection
	    } catch (Exception ignore) {
	  }
	}

    }

    public void ejbPassivate() {
        logger.log(BasicLevel.DEBUG, "");
    }

    public void ejbActivate() {
        logger.log(BasicLevel.DEBUG, "");
    }

    public void ejbPostCreate(int val_accno, String val_customer, double val_balance){
        logger.log(BasicLevel.DEBUG, "");
    }

    public void ejbPostCreate(){
        logger.log(BasicLevel.DEBUG, "");
    }

    public java.lang.Integer ejbCreate(int val_accno, String val_customer, double val_balance)
        throws CreateException {

        logger.log(BasicLevel.DEBUG, "");

        // Init here the bean fields
	// Init object state
	accno = new Integer(val_accno);
	customer = val_customer;
	balance = val_balance;

	Connection conn = null;

	PreparedStatement stmt = null;

	try {
	    // get a connection for this transaction context

            conn = getConnection();

	    // create object in DB

	    stmt = conn.prepareStatement("insert into jdbc_xa2 (xa_accno, xa_customer, xa_balance) values (?, ?, ?)");
	    stmt.setInt(1, accno.intValue());
	    stmt.setString(2, customer);
	    stmt.setDouble(3, balance);
	    stmt.executeUpdate();
	} catch (SQLException e) {
	    throw new CreateException("Failed to create bean in database: "+e);
	} finally {
	    try {
		if (stmt != null) stmt.close();	// close statement
		if (conn != null) conn.close();	// release connection
	    } catch (Exception ignore) {
	  }
	}

	// Return the primary key

	return accno;

    }

    public java.lang.Integer ejbFindByPrimaryKey(Integer pk)
        throws ObjectNotFoundException, FinderException {
        logger.log(BasicLevel.DEBUG, "");

        // Access database to find entry in table

        Connection conn = null;
        PreparedStatement stmt = null;

	try {
	    // get a connection for this transaction context

            conn = getConnection();

	    // lookup for this primary key in DB

	    stmt = conn.prepareStatement("select xa_accno from jdbc_xa2 where xa_accno=?");
	    stmt.setInt(1, pk.intValue());
	    ResultSet rs = stmt.executeQuery();

	    if (rs.next() == false) {
		throw new javax.ejb.ObjectNotFoundException();
	    }

	} catch (SQLException e) {
	    throw new javax.ejb.FinderException("Failed to executeQuery " +e);
	} finally {
	    try {
		if (stmt != null) stmt.close();       // close statement
		if (conn != null) conn.close();       // release connection
	    } catch (Exception ignore) {
	  }
	}

        return pk;
    }


    /**
     * Find Account by its account number
     *
     * @return pk The primary key
     *
     * @exception FinderException - Failed to execute the query.
     * @exception ObjectNotFoundException - Object not found for this account number
     */

    public Integer ejbFindByNumber(int accno) 
	throws ObjectNotFoundException, FinderException {

	Connection conn = null;
	PreparedStatement stmt = null;

	try {
	    // get a connection for this transaction context

            conn = getConnection();

	    // lookup for this primary key in DB

	    stmt = conn.prepareStatement("select xa_accno from jdbc_xa2 where xa_accno=?");
	    stmt.setInt(1, accno);
	    ResultSet rs = stmt.executeQuery();

	    if (rs.next() == false) {
		throw new javax.ejb.ObjectNotFoundException();
	    }

	} catch (SQLException e) {
	    throw new javax.ejb.FinderException("Failed to executeQuery " +e);
	} finally {
	    try {
		if (stmt != null) stmt.close();       // close statement
		if (conn != null) conn.close();       // release connection
	    } catch (Exception ignore) {
	  }
	}

	// return a primary key for this account

	return new Integer(accno);
    }

    /**
     * Creates an enumeration of primary keys for all accounts
     *
     * @return pkv The primary keys
     *
     * @exception FinderException - Failed to execute the query.
     */

    public Enumeration ejbFindAllAccounts() throws FinderException {

	Connection conn = null;
	PreparedStatement stmt = null;

	Vector pkv = new Vector();

	try {
	    // get a connection for this transaction context

            conn = getConnection();

	    // Lookup for all accounts in DB

	    stmt = conn.prepareStatement("select xa_accno from jdbc_xa2");
	    ResultSet rs = stmt.executeQuery();

	    // Build the vector of primary keys

	    while (rs.next()) {
		Integer pk = new Integer(rs.getInt("xa_accno"));
		pkv.addElement((Object)pk);
	    };

	} catch (SQLException e) {
	    throw new javax.ejb.FinderException("Failed to executeQuery " +e);
	} finally {
	    try {
		if (stmt != null) stmt.close();       // close statement
		if (conn != null) conn.close();       // release connection
	    } catch (Exception ignore) {
	  }
	}

	// return primary keys
	return pkv.elements();
    }

    public java.lang.Integer ejbCreate()
        throws CreateException{

        logger.log(BasicLevel.DEBUG, "");

	// Init object state

	Connection conn = null;
	Statement stmt = null;
        Integer tempint = new Integer(0);

	try {
	    // get a connection for this transaction context

            conn = getConnection();

	    // create object in DB

	    stmt = conn.createStatement();
	    stmt.addBatch("insert into jdbc_xa2 (xa_accno, xa_customer, xa_balance) values (201, 'Albert Smith', 500)");
	    stmt.addBatch("insert into jdbc_xa2 (xa_accno, xa_customer, xa_balance) values (202, 'Bob Smith', 500)");
	    stmt.addBatch("insert into jdbc_xa2 (xa_accno, xa_customer, xa_balance) values (203, 'Carl Smith', 500)");
	    stmt.addBatch("insert into jdbc_xa2 (xa_accno, xa_customer, xa_balance) values (204, 'David Smith', 500)");
	    stmt.addBatch("insert into jdbc_xa2 (xa_accno, xa_customer, xa_balance) values (205, 'Edward Smith', 500)");
	    int[] upCounts = stmt.executeBatch();

	} catch (SQLException e) {
	    throw new CreateException("Failed to create bean in database: "+e);
	} finally {
	    try {
		if (stmt != null) stmt.close();	// close statement
		if (conn != null) conn.close();	// release connection
	    } catch (Exception ignore) {
	  }
	}
        return tempint;
    }

    /**
     * @return  the connection from the dataSource
     * @exception EJBException  Thrown by the method if the dataSource is not found
     *                          in the naming.
     * @exception SQLException may be thrown by dataSource.getConnection()
     */

    private Connection getConnection() throws EJBException, SQLException {

        Connection myconn2 = null;

	if (dataSource2 == null) {

	    // Finds DataSource from JNDI

	    Context    initialContext = null;

	    try {
		initialContext = new InitialContext();
		dataSource2 = (DataSource)initialContext.lookup("java:comp/env/jdbc/JdbcRA2Ds");
	    } catch (Exception e) {
		throw new javax.ejb.EJBException("Cannot lookup dataSource2 "+e);
	    }
	}

        try {
             myconn2 = dataSource2.getConnection();
        } catch (Exception e) {
             throw new javax.ejb.EJBException("Cannot getConnection dataSource2 "+e);
        }

	return myconn2;
    }

    /*========================= Account implementation ============================*/

    /**
     * Business method for returning the balance.
     *
     * @return balance
     *
     */

    public double getBalance(){
	return balance;
    }

    /**
     * Business method for updating the balance.
     *
     * @param d balance to update
     * 
     */

    public void setBalance(double d){
	balance = balance + d;
    }

    /**
     * Business method for returning the customer.
     *
     * @return customer
     *
     */

    public String  getCustomer(){
	return customer;
    }

    /**
     * Business method for changing the customer name.
     *
     * @param c customer to update
     * 
     */

    public void setCustomer(String c) {
	customer = c;
    }

    /**
     * Business method to get the Account number
     */

    public int getNumber() {
	return accno.intValue();
    }

}



