
// Copyright (c) 1999, 2000 Oracle Corporation
package oracle.jbo.common.ampool;

import java.util.*;
import oracle.jbo.*;

/**
 * The PoolTester class provides a sample implementation and use
 * of Application Module Pooling in LOCAL mode. This example uses
 * the default implementation of Application Module Pooling.
 * <p>
 * <a HREF="PoolTester.txt">View implementation of PoolTester</a>
 * <P>
 * <h3>Understanding the Sample Implementation</h3>
 * The sample implementation begins by defining the environment
 * settings. This can be done directly
 * (as is demonstrated in this example) or from a property file. In this
 * example, the hashtable contains the properties to set up the
 * environment to connect in LOCAL mode.
 * <p>
 * Create the pool <tt>TestAMPool</tt>. Since <tt>PoolMgr</tt> is a singleton object,
 * use <tt>PoolMgr.getInstance</tt> to get it. Use <tt>createPool</tt>
 * to create the pool. Notice that <tt>createPool</tt> requires the
 * name of the pool,
 * the name of the package that contains the Application Module, the
 * connect string to the database, and env, the hashtable. The
 * <tt>createPool</tt> method is overloaded—an alternative version
 * takes an additional parameter that lets you override the default
 * implementation of Application Module Pooling and specify your own.
 * <p>
 * Create a second pool, <tt>SecondAMPool</tt> that connects with
 * the same environment variables, but to an Application Module
 * in a different package.
 * <p>
 * <tt>PoolMgr.getInstance().getPool("TestAMPool")</tt> gets a
 * handle to the pool to work with it.
 * <p>
 * Checkout three instances. Note that the classes
 * <tt>ApplicationPoolImpl</tt> and <tt>PoolMgr</tt> contain other
 * functions that you can use to traverse the pool content. The
 * <tt>ampool</tt> package also contains a <tt>PoolAdministrator</tt>
 * Web Bean that you can use to dump the contents of the pool.
 * <p>
 * Get a handle to the second pool, check out two instances,
 * then check in one.
 * <p>
 * Use <tt>removePool</tt> to remove the Application Module Pool.
 * This function calls <tt>remove()</tt> on all of the Application
 * Module instances, including ones that are currently checked out
 * and in use, and causes them to disconnect from the database and
 * remove all of their View Objects.
 * <p>
 * The next part of the program defines a class, <tt>CustomPool</tt>,
 * that ensures that no more than three instances are checked out
 * of the pool at any time. In this case, the definition of the
 * checkout method is overridden to check that no more than three
 * instances are checked out. If more than three are checked out,
 * an exception is thrown.
 * <p>
 * This custom pool class is then used in a program which attempts
 * to create more than three instances. The <tt>try-catch</tt> loop is set up to
 * start checking out instances and to catch exceptions. When an
 * attempt is made to create the fourth
 * instance, an exception is thrown.
 *
 *
 * @author Juan Oropeza
 */
public class PoolTester extends Object {

  /**
   * Constructor
   */
  public PoolTester() {
  }

  public void doTest() throws Exception
  {
    Hashtable info = new Hashtable();

    info.put(JboContext.INITIAL_CONTEXT_FACTORY, JboContext.JBO_CONTEXT_FACTORY);
    info.put(JboContext.DEPLOY_PLATFORM, "LOCAL");

    PoolMgr.getInstance().createPool("TestAMPool", "package2.Package2Module" , "jdbc:oracle:thin:scott/tiger@localhost:1521:orcl", info);

    ApplicationPool pool = PoolMgr.getInstance().getPool("TestAMPool");

    ApplicationModule instance = pool.checkout();

    ApplicationModule instance2 = pool.checkout();

    pool.checkin(instance2);
    
    ApplicationModule instance3 = pool.checkout();

    PoolMgr.getInstance().removePool("TestAMPool");

    // create a pool with a custom application pool class
    PoolMgr.getInstance().createPool("CustomTestAMPool", "oracle.jbo.common.ampool.CustomPool" , "package2.Package2Module" , "jdbc:oracle:thin:scott/tiger@localhost:1521:orcl", info);

    pool = PoolMgr.getInstance().getPool("CustomTestAMPool");

    try
    {
      instance = pool.checkout();
      instance = pool.checkout();
      instance = pool.checkout();
      instance = pool.checkout();
      instance = pool.checkout();
    }
    catch(Exception ex)
    {
      ex.printStackTrace();
    }
     
  }

  /**
   * Provides a <tt>main</tt> for the PoolTester
   * sample implementation of Application Module Pooling.
   * @param args arguments to the PoolTester sample implementation.
   */
  public static void main(String[] args) {
    PoolTester poolTester = new PoolTester();

    try
    {
      poolTester.doTest();
    }
    catch(Exception ex)
    {
      ex.printStackTrace();
    }
  }
}

/**
**  This is a simple application pool class that only allows checkout of 3 instances
**/
class CustomPool extends ApplicationPoolImpl
{
  public CustomPool()
  {
  }

  /**
   * checkout
   * @return oracle.jbo.ApplicationModule
   */
  public synchronized ApplicationModule checkout() throws Exception
  {
    // if the instance count > 3 throw an exception
    int nCount = getInstanceCount();

    if(nCount > 3)
    {
      throw new RuntimeException("You have exceeded the number of instances for this pool");
    }
    return super.checkout();
  }
  
}
