Codice completo

Definisce la logica del BMP Entity Bean

package it.html.ejb.entity.bmp;

import java.rmi.RemoteException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.ejb.CreateException;
import javax.ejb.EntityBean;
import javax.ejb.EntityContext;
import javax.ejb.FinderException;
import javax.ejb.RemoveException;

public class BankAccountBean implements EntityBean {
  
  //Variabili di istanza
  private EntityContext ctx;
  
  private String accountID;
  private String nome;
  private double saldo;
  
  //Costruttore
  public BankAccountBean(){
    System.out.println("New Bank Account creating...");
  }
  
  //Metodi di business  
  public void deposito(double amt){
    System.out.println("Deposito sul conto "+accountID+" di "+amt+" Euro");
    
    saldo+=amt;
  }
  public void prelievo(double amt)throws AccountException{
    System.out.println("Prelievo dal conto "+accountID+" di "+amt+" Euro");
    if ( amt>saldo ) throw new AccountException();
    saldo-=amt;
  }
  
  //Metodi getter / setter  
  public double getSaldo(){
    return saldo;
  }
  public String getNome(){
    return nome;
  }
  public void setNome(String name){
    nome=name;
  }
  public String getAccountID(){
    return accountID;
  }
  public void setAccountID(String id){
    accountID=id;
  }
  
  /**
  * Metodo utilizzato per creare una connessione JDBC verso un database.
  *
  * ATTENZIONE: qui non viene mostrato il modo migliore per utilizzare le connessioni JDBC.
  * In futuro utilizzeremo il servizio JNDI per creare le connessioni sull'application
  * server (attraverso i DataSource) ed utilizzarle direttamente dai componenti.
  * Si è preferito lasciare ai seguenti
  * capitoli la spiegazione per una maggior comprensione del componente in questione.
  */

  
  private Connection getConnection(){
    //Dovete settare le variabili con i valori relativi ai driver utilizzati
    String class_driver="org.gjt.mm.mysql.Driver";
    String url_connect="jdbc:mysql://127.0.0.1:3306/bmpdatabase?user=root&password=squake";
    
    try{
      Class.forName(class_driver);
    }catch(Exception e){
      e.printStackTrace();
      System.exit(-1);
    }
    
    try {
      return DriverManager.getConnection(url_connect);
    } catch (SQLException e) {
      e.printStackTrace();
    }
    
    return null;
  }  
  
  //Metodi Finder
  
  /**
  * Il metodo ricerca l'account in base al suo identificativo univoco: il componente
  * deve sempre avere almento questo metodo finder.
  *
  * La logica sarà recuperare (con una query sql) i valori dal database e restituire la
  * relativa chiave.
  */

  public AccountPK ejbFindByPrimaryKey(AccountPK key) throws FinderException {
    System.out.println("ejbFindByPrimaryKey("+key+")");
    
    PreparedStatement pstmt=null;
    Connection conn=null;
    
    try{
      conn=getConnection();
      pstmt=conn.prepareStatement("SELECT id FROM simplebank WHERE id=?");
      
      //Setto il valore nello statement
      pstmt.setString(1,key.getId());
      
      //Eseguo la query e recupero il risultato
      ResultSet rs=pstmt.executeQuery();
      
      //Se esiste un record, vuol dire che abbiamo trovato l'account
      if (rs.next());
      return key;
    
    }catch(SQLException e){
    
    } finally{
      //Chiudiamo le connessioni aperte in precedenza
      try {
        pstmt.close();
      } catch (SQLException e) {
        // NOOP
      }
      try {
        conn.close();
      } catch (SQLException e) {
        // NOOP
      }
    }
    
    throw new FinderException();
  }
  
  //Metodi di utilità
  
  //Restituisce il numero di conti correnti attualmente presenti nel database
  public int ejbHomeGetNumeroContiAperti(){
    System.out.println("ejbGetNumeroContiAperti()");
    int toRet=0;
    
    PreparedStatement pstmt=null;
    Connection conn=null;
    
    try{
      conn=getConnection();
      pstmt=conn.prepareStatement("SELECT count(id) AS totale FROM simplebank");
      ResultSet rs=pstmt.executeQuery();
      
      //L'operazione non dovrebbe sollevare eccezioni
      toRet=rs.getInt("totale");
      
      rs.close();
    
    }catch (Exception e){
      //NOOP
    }finally{
      try {
        pstmt.close();
      } catch (SQLException e) {
        // NOOP
      }
      try {
        conn.close();
      } catch (SQLException e) {
        // NOOP
      }
    }
    
    //Restituiamo il valore recuperato dalla conta SQL
    return toRet;
  }
  
  //Metodi callback (ejbCreate, ejbPostCreate, ejbLoad, ecc)
  
  /**
  * METODO EJBCREATE
  *
  * In questo metodo bisogna codificare la creazione di un istanza:
  * nel nostro caso l'operazione di insert.
  */

  public AccountPK ejbCreate(String accountID, String name) throws CreateException{
    System.out.println("ejbCreate("+accountID+","+name+")");
    
    Connection conn=null;
    PreparedStatement pstmt=null;
    
    //Settiamo le variabili del componente
    this.accountID=accountID;
    this.nome=name;
    this.saldo=0;
    
    //Salvataggio dell'informazione
    try{
      conn=getConnection();
      pstmt=conn.prepareStatement("" +
      "INSERT INTO simplebank ( id, nome, saldo ) values " +
      "('"+accountID+"','"+nome+"',"+saldo+")");
      pstmt.execute();
      
      return new AccountPK(accountID);
    
    }catch(Exception e){
      e.printStackTrace();
    }finally{
      try {
        pstmt.close();
      } catch (SQLException e) {
        // NOOP
      }
      try {
        conn.close();
      } catch (SQLException e) {
        // NOOP
      }
    }
    
    //Se arriviamo qui, qualcosa è andato storto
    throw new CreateException();
  }
  
  /**
  * Metodo callback chiamato subito dopo la ejbCreate: a noi in questo caso
  * non serve, percui lasciamo il corpo vuoto.
  */

  public void ejbPostCreate(String s,String s2) throws CreateException {
    //NOOP
  }
  
  /**
  * METODO EJBREMOVE
  *
  * In questo metodo bisogna codificare la distruzione di una riga del database (operazione
  * di delete). Attenzione: questo metodo non elimina il componente dal sistema, in quanto
  * può essere riutilizzato da altri utenti (con i nuovi valori settati).
  */

  public void ejbRemove() throws RemoveException {
  /*
  * Per prima cosa recuperiamo l'account da eliminare, e lo recuperiamo
  * dall'oggetto ctx (il Context) che virtualizza l'ambiente di esecuzione
  * e conosce la primary key legata all'istanza attuale del BMP.
  * */

  AccountPK key=(AccountPK) ctx.getPrimaryKey();
  
  System.out.println("ejbRemove() account "+key);
  
  Connection conn=null;
  PreparedStatement pstmt=null;
  
  //Eliminazione dell'informazione dal database
  try{
    conn=getConnection();
    pstmt=conn.prepareStatement("DELETE FROM simplebank WHERE id=?");
    
    //Settiamo il valore di ?
    pstmt.setString(1, key.getId());
    
    //Eseguiamo
    pstmt.execute();
  
  }catch(Exception e){
    e.printStackTrace();
  }finally{
    try {
      pstmt.close();
    } catch (SQLException e) {
      // NOOP
    }
    try {
      conn.close();
    } catch (SQLException e) {
      // NOOP
    }
  }
  
  }
  
  /**
  * METODO EJBLOAD
  *
  * Rappresenta il modo con cui i valori del bean vengono recuperati dal database (operazione
  * di SELECT).
  *
  * La logica pertanto prevede il recupero dei valori legati alla chiave associata al componente
  * ed il setting degli stessi, in maniera da poterli usare e manipolare (secondo i metodi di
  * logica previsti).
  */

  public void ejbLoad() {
    //Recuperiamo dal context la Primary Key associata al componente
    AccountPK key=(AccountPK) ctx.getPrimaryKey();
    
    System.out.println("ejbLoad() account "+key);
    
    Connection conn=null;
    PreparedStatement pstmt=null;
    
    //Recupero le informazioni associate all'account dal database
    try{
      conn=getConnection();
      pstmt=conn.prepareStatement("Select * FROM simplebank WHERE id=?");
      
      //Settiamo il valore di ?
      pstmt.setString(1, key.getId());
      
      //Eseguiamo
      ResultSet rs=pstmt.executeQuery();
      if (rs.next()){
        //settiamo il risultato nelle variabili di istanza
        accountID=key.getId();
        nome=rs.getString("nome");
        saldo=rs.getDouble("saldo");
      }
      
      rs.close();
    
    }catch(Exception e){
      e.printStackTrace();
    }finally{
      try {
        pstmt.close();
      } catch (SQLException e) {
        // NOOP
      }
      try {
        conn.close();
      } catch (SQLException e) {
        // NOOP
      }
    }  
  }
  
  /**
  * METODO EJBSTORE
  *
  * Rappresenta il modo con cui i valori del bean vengono salvati sul database (operazione
  * di UPDATE).
  *
  * La logica pertanto prevede il recupero dei valori legati alla chiave associata al componente
  * ed il salvataggio (update) sul database in modo da mantenerli persistenti.
  */

  
  public void ejbStore() {
    System.out.println("ejbStore() account "+accountID);
    
    Connection conn=null;
    PreparedStatement pstmt=null;
    
    //Aggioriamo l'account sul database
    try{
      conn=getConnection();
      pstmt=conn.prepareStatement("UPDATE simplebank set nome=?, saldo=? WHERE id=?");
      
      //Settiamo il valore di ? con i relativi valori puntati dal componente
      pstmt.setString(1, this.nome);
      pstmt.setDouble(2, this.saldo);
      pstmt.setString(3, this.accountID);
      
      //Eseguiamo
      pstmt.execute();
    
    }catch(Exception e){
      e.printStackTrace();
    }finally{
      try {
        pstmt.close();
      } catch (SQLException e) {
        // NOOP
      }
      try {
        conn.close();
      } catch (SQLException e) {
        // NOOP
      }
    }    
  }
  
  //Metodi callback utilizzati per l'attivazione e la passivazione del componente.
  public void ejbActivate() {
    //NOOP
  }
  public void ejbPassivate() {
    //NOOP
  }
  
  /**
  * Metodi callback utilizzati dal container per settare l'ambiente di esecuzione (Context)
  *
  * Attraverso il context, il componente può comunicare con il container e recuperarne
  * servizi in maniera immediata utilizzato il naming JNDI.
  * */
  
  public void setEntityContext(EntityContext entityContext) {
    this.ctx = entityContext;
  }
  
  public void unsetEntityContext() {
    ctx = null;
  }

}