/*
 * 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.ebasic;

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

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

import org.objectweb.util.monolog.api.BasicLevel;

/**
 * This is an entity bean with "bean managed persistence". The state of an
 *  instance is stored into a relational database.
 * The table must exist.
 * @author Philippe Durieux, Philippe Coq
 */
public class SimpleEB extends SimpleEC implements EntityBean {

    static final String tableName = "ebasicSimpleEB";

    // Database related information
    private DataSource dataSource = null;
    private static String dataSourceName;


    public void ejbLoad() {
        logger.log(BasicLevel.DEBUG, "");
        String testname  = (String)entityContext.getPrimaryKey();
        PreparedStatement loadPstmt = null;
        Connection        conn      = null;
        try {
            conn = getConnection();
            loadPstmt = conn.prepareStatement("select c_info, c_numtest, c_testname  from "+tableName+" where c_testname=?");

            // PK fields
            loadPstmt.setString(1, testname);
            ResultSet rs = loadPstmt.executeQuery();
            if (rs.next() == false) {
                throw new javax.ejb.EJBException("Failed to load bean from database "+testname);
            };
            info    = rs.getInt(1);
            testname = rs.getString(3);
            numtest  = rs.getInt(2);
	    
        } catch (SQLException e) {
            throw new javax.ejb.EJBException("Failed to load bean from database" +e);
        } finally {
            try{
                loadPstmt.close();
                // remove next line to test what happen when close is forgot.
                conn.close();
            } catch(Exception e) {
                System.err.println("ejbLoad: Ignore exception:"+e);
            }
        }

    }

    public void ejbStore() {
        logger.log(BasicLevel.DEBUG, "");
        String testname = (String)entityContext.getPrimaryKey();
        PreparedStatement storePstmt = null;
        Connection        conn       = null;
	
        try {
            conn = getConnection();
            storePstmt = conn.prepareStatement("update "+tableName+" set c_info=?,c_numtest=? where c_testname=?");

            storePstmt.setString(3, testname);
            storePstmt.setInt(1, info);
            storePstmt.setInt(2, numtest);
            storePstmt.executeUpdate();
        } catch (SQLException e) {
            throw new javax.ejb.EJBException("Failed to store bean to database "+testname);
	    
        } finally {
            try{
                storePstmt.close();
                conn.close();
            } catch(Exception e) {
                System.err.println("ejbStore: Ignore exception:"+e);
            }
        }
    }

    public void ejbRemove() {
        logger.log(BasicLevel.DEBUG, "");
        String testname  = (String)entityContext.getPrimaryKey();
        PreparedStatement removePstmt = null;
        Connection        conn        = null;
        try {
            conn = getConnection();
            removePstmt = conn.prepareStatement("delete from "+tableName+" where c_testname=?");
            // PK fields
            removePstmt.setString(1, testname );
            removePstmt.executeUpdate();
        } catch (SQLException e) {
            throw new javax.ejb.EJBException("Failed to delete bean from database "+testname);
        } finally {
            try{
                removePstmt.close();
                conn.close();
            } catch(Exception e) {
                System.err.println("ejbRemove: Ignore exception:"+e);
            }
        }
    }

    Connection   lost = null;

    public String ejbCreate(String name, int info, int  num)  throws CreateException {

        super.ejbCreate(name, info, num);

        PreparedStatement createPstmt = null;
        Connection        conn        = null;

        // persistence management
        try {
            conn = getConnection();
            // uncomment this line to lost a connection (test)
            // lost = getConnection();
            createPstmt = conn.prepareStatement("insert into "+tableName+" values (?, ?, ?)");
            // all fields
            createPstmt.setString(1, testname);
            createPstmt.setInt(2, info);
            createPstmt.setInt(3, numtest);
            createPstmt.executeUpdate();
        } catch (SQLException e) {
            logger.log(BasicLevel.ERROR, "ejbCreate failed: " + e);
            throw new javax.ejb.EJBException("Failed to create bean in database "+testname);
        } finally {
            try{
                createPstmt.close();
                conn.close();
            } catch(Exception e) {
                // ignore exception
                logger.log(BasicLevel.ERROR, "ejbFindByPrimaryKey: Ignore exception:"+e);
            }
        }
        return name;
    }

    public void ejbPostCreate(String name, int info, int  num) {
        super.ejbPostCreate(name, info, num);
    }

 

    public String ejbFindByPrimaryKey(String name ) throws ObjectNotFoundException, FinderException {
        logger.log(BasicLevel.DEBUG, "name="+ name);
        PreparedStatement loadPstmt = null;
        Connection        conn      = null;
        try {
            conn      = getConnection();
            loadPstmt = conn.prepareStatement("select c_info,c_numtest  from "+tableName+" where c_testname=?");
            loadPstmt.setString(1,name );
            ResultSet rs = loadPstmt.executeQuery();
            if (rs.next() == false) {
                throw new javax.ejb.ObjectNotFoundException("primary key : "+name);
            }
        } catch (SQLException e) {
            throw new javax.ejb.FinderException("Failed to executeQuery " +e);
        } finally {
            try{
                loadPstmt.close();
                conn.close();
            } catch(Exception e) {
                // ignore exception
                logger.log(BasicLevel.ERROR, "ejbFindByPrimaryKey: Ignore exception:"+e);
            }
        }
        return name;
    }


    public String ejbFindByTestName(String  name) 
        throws ObjectNotFoundException, FinderException {
        logger.log(BasicLevel.DEBUG, "name="+ name);
        PreparedStatement loadPstmt = null;
        Connection conn = null;

        try {
            conn = getConnection();
            loadPstmt = conn.prepareStatement("select c_info,c_numtest  from "+tableName+" where c_testname=?");
            loadPstmt.setString(1, name);
            ResultSet rs = loadPstmt.executeQuery();
            if (rs.next() == false) {
                throw new javax.ejb.ObjectNotFoundException("primary key : "+name);
            }
        } catch (SQLException e) {
            throw new javax.ejb.FinderException("Failed to executeQuery " +e);
        } finally {
            try{
                loadPstmt.close();
                conn.close();
            } catch(Exception e) {
                // ignore exception
                logger.log(BasicLevel.ERROR, "ejbFindByPrimaryKey: Ignore exception:"+e);
            }
        }
 
        return name;
    }

    /** is similar to ejbFindByTestName but try to access to TimerService and PK that should get
        IllegalStateException.
    **/
    public String ejbFindByName(String  name) 
        throws ObjectNotFoundException, FinderException {
        logger.log(BasicLevel.DEBUG, "name="+ name);
        PreparedStatement loadPstmt = null;
        Connection conn = null;

        try {
            conn = getConnection();
            loadPstmt = conn.prepareStatement("select c_info,c_numtest  from "+tableName+" where c_testname=?");
            loadPstmt.setString(1, name);
            ResultSet rs = loadPstmt.executeQuery();
            if (rs.next() == false) {
                throw new javax.ejb.ObjectNotFoundException("primary key : "+name);
            }
        } catch (SQLException e) {
            throw new javax.ejb.FinderException("Failed to executeQuery " +e);
        } finally {
            try{
                loadPstmt.close();
                conn.close();
            } catch(Exception e) {
                // ignore exception
                logger.log(BasicLevel.ERROR, "ejbFindByPrimaryKey: Ignore exception:"+e);
            }
        }
       // Try to access TimerService and PK: Should get IllegalStateException.
        if (entityContext != null) {
            try {
                entityContext.getTimerService();
                throw new FinderException("Should not get TimerService from a finder method");
            } catch (IllegalStateException e) {
                logger.log(BasicLevel.DEBUG, "IllegalStateException has been thrown");
            }
            try {
                entityContext.getPrimaryKey();
                throw new FinderException("Should not get PK from a finder method");
            } catch (IllegalStateException e) {
                logger.log(BasicLevel.DEBUG, "IllegalStateException has been thrown");
            }
        }
        return name;
    }

    public Enumeration ejbFindInfoForNum(int  num) throws FinderException {
        logger.log(BasicLevel.DEBUG, "num="+ num);
        PreparedStatement loadPstmt = null;
        Connection conn = null;
        Vector pkV = new Vector();
        try {
            conn = getConnection();
            loadPstmt = conn.prepareStatement("select c_testname  from "+tableName+" where c_numtest=?");
            loadPstmt.setInt(1, num);
            ResultSet rs = loadPstmt.executeQuery();

            while(rs.next()) {
                String pk = rs.getString(1);
                pkV.addElement(pk);
		
            }

        } catch (SQLException e) {
            throw new javax.ejb.FinderException("Failed to executeQuery " +e);
        } finally {
            try{
                loadPstmt.close();
                conn.close();
            } catch(Exception e) {
                // ignore exception
                logger.log(BasicLevel.ERROR, "ejbFindByPrimaryKey: Ignore exception:"+e);
            }
        }
        return (pkV.elements());
    }

    public String ejbFindOneByNum(int numTest) 
        throws ObjectNotFoundException, FinderException {
        logger.log(BasicLevel.DEBUG, "numTest=" + numTest);
        throw new FinderException();
    }
    
    public Collection  ejbFindInCollection() throws FinderException {
        logger.log(BasicLevel.DEBUG, "");
        PreparedStatement loadPstmt = null;
        Connection conn = null;
        Vector pkV = new Vector();
        try {
            conn = getConnection();
            loadPstmt = conn.prepareStatement("select c_testname  from "+tableName+" where c_numtest =?");
            loadPstmt.setInt(1, 8);
            ResultSet rs = loadPstmt.executeQuery();
            while (rs.next()) {
                String pk = rs.getString(1);
                pkV.addElement(pk);
            }
        } catch (SQLException e) {
            throw new javax.ejb.FinderException("Failed to executeQuery " +e);
        } finally {
            try{
                loadPstmt.close();
                conn.close();
            } catch(Exception e) {
                // ignore exception
                logger.log(BasicLevel.ERROR, "ejbFindByPrimaryKey: Ignore exception:"+e);
            }
        }
        return (pkV);
    }

    public Enumeration ejbFindInfo_beetwen(int  p1, int p2) throws FinderException {
        logger.log(BasicLevel.DEBUG, "");
        Vector pkC = new Vector();
        Connection conn = null;
        PreparedStatement loadPstmt = null;
        try {
            conn = getConnection();
            loadPstmt = conn.prepareStatement("select c_testname  from "+tableName+" where ?<=c_info and c_info<=?  and ?<=c_numtest  and c_numtest<=?");
            loadPstmt.setInt(1, p1);
            loadPstmt.setInt(2, p2);
            loadPstmt.setInt(3, p1);
            loadPstmt.setInt(4, p2);
 
            ResultSet rs = loadPstmt.executeQuery();
            while (rs.next()) {
                String pk = rs.getString(1);
                pkC.addElement(pk);
            }
        } catch (Exception e) {
            throw new javax.ejb.FinderException("Failed to find bean from database (findInfo_beetwen)");
        } finally {
            try{
                loadPstmt.close();
                conn.close();
            } catch(Exception e) {
                // ignore exception
                logger.log(BasicLevel.ERROR, "ejbFindByPrimaryKey: Ignore exception:"+e);
            }
        }
        return(pkC.elements());
    }

    public Enumeration ejbFindEqualOne(int  p1) throws FinderException {
        logger.log(BasicLevel.DEBUG, "");
        Vector pkC = new Vector();
        Connection conn = null;
        PreparedStatement loadPstmt = null;
        try {
            conn = getConnection();
            loadPstmt = conn.prepareStatement("select c_testname  from "+tableName+" where c_info = ?  and c_numtest = ?");
            loadPstmt.setInt(1, p1);
            loadPstmt.setInt(2, p1);
 
            ResultSet rs = loadPstmt.executeQuery();
            while (rs.next()) {
                String pk = rs.getString(1);
                pkC.addElement(pk);
            }
        } catch (Exception e) {
            throw new javax.ejb.FinderException("Failed to find bean from database (findInfo_beetwen)");
        } finally {
            try{
                loadPstmt.close();
                conn.close();
            } catch(Exception e) {
                // ignore exception
                logger.log(BasicLevel.ERROR, "ejbFindByPrimaryKey: Ignore exception:"+e);
            }
        }
        return(pkC.elements());
    }

    public Enumeration ejbFindEqualTwo(int  p1, int p2) throws FinderException {
        logger.log(BasicLevel.DEBUG, "");
        Vector pkC = new Vector();
        Connection conn = null;
        PreparedStatement loadPstmt = null;
        try {
            conn = getConnection();
            loadPstmt = conn.prepareStatement("select c_testname  from "+tableName+" where c_info = ?  and c_numtest = ?");
            loadPstmt.setInt(1, p1);
            loadPstmt.setInt(2, p2);
 
            ResultSet rs = loadPstmt.executeQuery();
            while (rs.next()) {
                String pk = rs.getString(1);
                pkC.addElement(pk);
            }
        } catch (Exception e) {
            throw new javax.ejb.FinderException("Failed to find bean from database (findInfo_beetwen)");
        } finally {
            try{
                loadPstmt.close();
                conn.close();
            } catch(Exception e) {
                // ignore exception
                logger.log(BasicLevel.ERROR, "ejbFindByPrimaryKey: Ignore exception:"+e);
            }
        }
        // Try to access TimerService and PK: Should get IllegalStateException.
        if (entityContext != null) {
            try {
                entityContext.getTimerService();
                throw new FinderException("Should not get TimerService from a finder method");
            } catch (IllegalStateException e) {
                logger.log(BasicLevel.DEBUG, "IllegalStateException has been thrown");
            }
            try {
                entityContext.getPrimaryKey();
                throw new FinderException("Should not get PK from a finder method");
            } catch (IllegalStateException e) {
                logger.log(BasicLevel.DEBUG, "IllegalStateException has been thrown");
            }
        }
        return(pkC.elements());
    }

    private Connection getConnection() throws java.sql.SQLException {
        if (dataSource == null) {
            // Finds DataSource from JNDI
            Context    initialContext = null;
            try {
                initialContext = new InitialContext();
                dataSource = (DataSource)initialContext.lookup("java:comp/env/jdbc/BMP");
            } catch (Exception e) {
                throw new javax.ejb.EJBException("Pb with naming context ");
            }
        }
        Connection ret = dataSource.getConnection();
        if (ret == null) {
            throw new javax.ejb.EJBException("dataSource.getConnection() returned null");
        }
        return ret;
    }

    // Just to test we can define a method named 'ejbSelect' (see bug #522)
    public void ejbSelect() {
    }

}
