package oracle.forms.fd;

import java.sql.*;
import oracle.forms.handler.IHandler;
import oracle.forms.ui.CustomEvent;
import oracle.forms.properties.ID;
import oracle.forms.ui.VBean;

  /**
   * A javabean to start asynchronous stored procedures/functions
   *
   * @author Francois Degrelle
   * @version 1.1
   */

public class AsyncJob extends VBean implements Runnable 
{
    static Thread runner ;
    static int seconds = 0 ;
    static IHandler mHandler;
    static String sValue = "" ;
    static String sQuery = "" ;
    static String sResult = "" ;
    static String sError  = "" ;    
    static String sConn = "" ;
    static String sUser = "" ;
    static String sPwd  = "" ;
    static boolean bFunction = true ;
    static boolean bLog = false ;    
    static Connection conn ;
    
    protected static final ID pInitProc      = ID.registerProperty("INITPROC");
    protected static final ID pInitFunc      = ID.registerProperty("INITFUNC");
    protected static final ID pInitConn      = ID.registerProperty("INITCONN");
    protected static final ID pInitUser      = ID.registerProperty("INITUSER");    
    protected static final ID pInitPwd       = ID.registerProperty("INITPWD");    
    protected static final ID pEvent         = ID.registerProperty("EVENT");
    protected static final ID pGetResult     = ID.registerProperty("GETRESULT");
    protected static final ID pGetError      = ID.registerProperty("GETERROR");    
    protected static final ID pSetLog        = ID.registerProperty("SETLOG");        


    public AsyncJob()
    {
      super();
    }

    public void init(IHandler handler)
    {
      super.init(handler);
      mHandler = handler;
      log("**Init**") ;       
    }      

  public void connect()
  {
    sResult = "" ;
    log("**connect**") ;       
    if( sConn.equals("") || sUser.equals("") || sPwd.equals(""))
    {
      sError = "Connection string and username and password must be set" ;
      return ;
    }
    try {
      DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver()); 
      log("**registerDriver OK**") ;       
      conn = DriverManager.getConnection (sConn, sUser, sPwd);           
      log("**connect OK**") ;       
      // execute the stored procedure/function
      sResult = SQLExec(conn) ;
      log("sResult="+sResult) ;       
      try {
        conn.close();
        log("**close OK**") ;       
      }
      catch(SQLException ex)
      {
        System.out.println("conn.close() exception: " + ex.getMessage());
        ex.printStackTrace ();
      }      
    }
    catch(SQLException ex)
      {
        System.out.println("exception: " + ex.getMessage());
      }      
    finally
    {
      log("**connect End**") ;               
    }
  }      

    // we start the thread here
    private void startThread()
    {
      if (runner == null )
      {
        runner = new Thread(this);
        runner.start();
      }
    }
    
    // we stop the thread here
    private static void stopThread()
    {
      if (runner != null )
      {
        runner = null;
      }
      try {
        conn.close();
      }
      catch(SQLException ex)
      {
        System.out.println("stopTimer exception: " + ex.getMessage());
        ex.printStackTrace ();
      }
    }    

    // execute the SQL function in its own thread
    public void run()
    {
      Thread theThread = Thread.currentThread();
      while (runner == theThread)
      {
          // execute the stored function
          connect() ; 
          // stop the threadd
          stopThread() ;
          // tell Forms that the process is finished
          CustomEvent ce = new CustomEvent(mHandler, pEvent);
          dispatchCustomEvent(ce);
      }
    }    
    
    // set the properties of the bean
    public boolean setProperty(ID _ID, Object _args)
    {
  
     // a procedure will be called
     if (_ID == pInitProc)
     {
        log("InitProc") ;       
        sQuery = (String)_args ;
        bFunction = false ;
        startThread() ;
        return true;
     }
    
     // a function will be called
     else if (_ID == pInitFunc)
      {
         sQuery = (String)_args ;
         log("InitFunc="+sQuery) ;                
         bFunction = true ;
         startThread() ;
         return true;
      }     

      // init the connect string
      else if (_ID == pInitConn)
       {
          sConn = (String)_args ;
          log("InitConn="+sConn) ;                 
          return true;
       }     

      // init the username
      else if (_ID == pInitUser)
       {
          sUser = (String)_args ;
          log("InitUser="+sUser) ;       
          return true;
       }     

      // init the password
      else if (_ID == pInitPwd)
       {
          sPwd  = (String)_args ;
          log("InitPwd="+sPwd) ;       
          return true;
       }     

      // init the log boolean
      else if (_ID == pSetLog)
       {
          String sLog = (String)_args ;
          if (sLog.equalsIgnoreCase("true"))
             bLog = true ;
          else
             bLog = false ;
          return true;
       }     
       
     else
        {
          return true;
        }      
    }

  // get the properties
  public Object getProperty(ID property)
    {
      if (property == pGetResult)
      {
        // return the SQL result
        return "" + sResult ;
      }

      else if (property == pGetError)
      {
        // return the error message
        return "" + sError ;
      }
      else // default behaviour
      {
        return super.getProperty(property);
      }
    }

    // execute the procedure/function
    private String SQLExec( Connection conn ) throws SQLException
    {
      String sValue = "" ;
      sError = "" ;
      log("SQLExec query=" + sQuery);
      try
      {
        if( ! bFunction )
        {
         // call a procedure
         CallableStatement procedure = conn.prepareCall (sQuery);
         procedure.execute ();
         procedure.close();
         sValue = "pl/sql bloc ended" ;
        }
        else
        {
         // call a function
         CallableStatement function = conn.prepareCall (sQuery);
         function.registerOutParameter (1, Types.CHAR);
         function.execute ();
         sValue = function.getString (1) ;
         function.close();
        }
      }
      
      catch(SQLException ex)
      {
        System.out.println("SQLExec exception: " + ex.getMessage());
        sError = ex.getMessage() ;
      }

      return( sValue ) ;
    }  

  void log( String sMessage )
  {
    if( bLog ) System.out.println( sMessage ) ;
  }
  
}
