/*
 * @author  Umesh
 * @version 1.0
 *
 * Development Environment        :  Oracle JDeveloper 10g
 * Name of the Application        :  ConnCacheBean.java
 * Creation/Modification History  :
 *
 *    Umesh      25-Nov-2001      Created
 *    Venky      04-Feb-2003      Certified on OC4J903 on Linux
 *    Shrinvas   21-Jul-2003      Used ConnectionCacheManager API's 
 *
 */

package oracle.otnsamples.jdbc;

  /* Oracle JDBC Classes */
  import oracle.jdbc.pool.OracleConnectionCacheManager;
  import oracle.jdbc.pool.OracleDataSource;

  /* Java IO Classe */
  import java.io.IOException;

  /* Java Sql Classe */
  import java.sql.SQLException;

  /* Java Utility Classes */
  import java.util.Enumeration;
  import java.util.Properties;
  import java.util.ResourceBundle;

/**
 * Overview of Application        : 
 * This Bean Class is used to create and manage the conncetion cache for 
 * this sample application. 
 * 
 * In a typical data centric enterprise application, getting an individual 
 * database connection everytime for each user is an expensive operation. 
 * This is true especially when the number of users involved are 
 * large in number.
 *
 * The OracleConnectionCacheManager APIs are used to create, manage,and  maintain  
 * a connection cache in an efficient way. With the help of Connection Caching, 
 * the overhead of instantiating a new physical database connection can 
 * be easily overcome.
 *
 * This bean is implemented as a Singleton Class meaning that there can be only
 * one instance of this bean per JVM. In the constructor of the bean Connection
 * Cache is initialized.
 * 
 * In this sample application the ProductInfoBean uses this class to get the 
 * connection from the cache. 
 * 
 */
 
  public class ConnCacheBean {
    /* The name used to identify the cache uniquely */
    private static final String CACHE_NAME = "CacheSample";

    /* Maximum number of connection instaces */
    private static int MAX_LIMIT           = 15;

    /* Variable pointing to this instance */
    private static ConnCacheBean thisInstance = null;

    /* Connection cache manager */
    private OracleConnectionCacheManager connMgr = null;

    /* Data Source Variable */
    private OracleDataSource ods = null;

    /**
     * Private Constructor : This approach makes it easy to implement this class
     * as a Singleton Class. This method initializes Cache if not already
     * initialized.
     *
     * @throws Exception
     */
    private ConnCacheBean() throws Exception {
      if (ods == null) {
        initializeConnectionCache( );
      }
    }

    /**
     * This method returns a single instance of this bean.
     *
     * @return - ConnCacheBean Instance
     *
     * @throws Exception - Exception while creating the instance
     */
    public static ConnCacheBean getInstance() throws Exception {
      if (thisInstance == null) {
        thisInstance = new ConnCacheBean();
      }
      return thisInstance;
    }

    /**
     * This method returns active size of the Cache.
     *
     * @return int - Number of active conncetions
     *
     * @throws Exception - Any exception while getting the active size
     */
    public int getActiveSize() throws Exception {
      try {
        return connMgr.getNumberOfActiveConnections(CACHE_NAME);
      } catch (SQLException sqlEx) {
        sqlEx.printStackTrace();
        throw new Exception("SQL Error while getting the no of active " +
                              " connections"
                             );
      }
    }
    
    /**
     * This method returns the number of connections available in the cache.
     * @return int - Available connections in the cache
     * @throws Exception - Exception while getting the available connections
     */
    public int getAvailableConnections() throws Exception {
      return  connMgr.getNumberOfAvailableConnections(CACHE_NAME) ;
    }
    /**
     * This method returns connection cache size.
     *
     * @return int - Cache size
     *
     * @throws Exception - Exception while getting the cache size
     */
    public int getCacheSize() throws Exception {
      return connMgr.getNumberOfActiveConnections(CACHE_NAME) +
               connMgr.getNumberOfAvailableConnections(CACHE_NAME);
    }
    

   /**
    * This method returns the instance of OracleDataSource
    * @return OracleDataSource instance
    */
    public OracleDataSource getDataSource()  {
      return ods;
    }
    
    /**
     * This method returns the MaxLimit of the connection cache
     * @return MAX_LIMIT - Cache max limit
     */
    public int getCacheMaxLimit()  {
      return MAX_LIMIT;
    }
    /**
   * This method reintializes the cache with the new properites
   * 
   * @param properties - Properties object containing connecion cache properties
   * @throws SQLException - SQLException while setting the properties
   */
    public void setCacheProperties(Properties properties) throws SQLException {
      connMgr.reinitializeCache(CACHE_NAME, properties);
      
      /* Get the MaxLimit from the properties object */
      String maxLimit = properties.getProperty("MaxLimit") ;
      /* Set the maximum cache limit, used while closing the connection */
      if ( maxLimit != null && maxLimit.trim().length() > 0 )  {
        MAX_LIMIT =  new Integer(maxLimit).intValue();
      }
            
    }

    /**
   * This method reintializes the cache with the new properites
   * 
   * @return Properties - Connection cache properties
   * @throws SQLException - SQLException
   */
    public Properties getCacheProperties() throws SQLException {
      return ods.getConnectionCacheProperties() ; 
    }    
    
    /**
     * This method closes the connection cache. This is called to close the 
     * connection cache when the application closes.
     *
     * @throws SQLException - SQLException
     */
    public void closeConnCache() throws SQLException {
      if (ods != null) {
        ods.close();
      }
    }
    
    /**
     * This Method initializes Connection Cache by associating a data soruce 
     * with the cache. Also the properties of the cache are set while creating
     * the connection cache.
     * 
     *
     * @throws Exception
     */
    private void initializeConnectionCache() throws Exception {
      if (ods == null) {
        try {
          this.initializeConnectionCacheDataSrc();

          /* Initialize the Connection Cache */
          connMgr =
            OracleConnectionCacheManager.getConnectionCacheManagerInstance();

              
           /* This object holds the properties of the cache and is passed to the 
            * ConnectionCacheManager while creating the cache. Based on these 
            * properties the connection cache manager created the connection 
            * cache.
            */
           Properties properties = new Properties();
    
           /* Set Min Limit for the Cache. 
            * This sets the minimum number of PooledConnections that the cache 
            * maintains. This guarantees that the cache will not shrink below 
            * this minimum limit. 
            */
           properties.setProperty("MinLimit", "1");
    
           /* Set Max Limit for the Cache. 
            * This sets the maximum number of PooledConnections the cache 
            * can hold. There is no default MaxLimit assumed meaning connections
            * in the cache could reach as many as the database allows.
            */
           properties.setProperty("MaxLimit", "15");
    
           /* Set the Initial Limit.
            * This sets the size of the connection cache when the cache is 
            * initially created or reinitialized. When this property is set to 
            * a value greater than 0, that many connections are pre-created and 
            * are ready for use. 
            */
           properties.setProperty("InitialLimit", "10");
              
          /* Create the cache by passing the cache name, data source and the 
           * cache properties 
           */
          connMgr.createCache(CACHE_NAME, ods, properties);
        } catch (java.sql.SQLException ex) { /* Catch SQL Errors */
          throw new Exception("SQL Error while Instantiating Connection Cache : \n" +
                                ex.toString()
                               );
        } catch (java.lang.Exception ex) { /* Catch other generic errors */
          throw new Exception("Exception : \n" + ex.toString());
        }
      }
    }
   
    /**
     * This Method initializes the variable 'ods' with value of valid Connection
     * Cache Data Source.
     *
     * @throws Exception 
     */
    private void initializeConnectionCacheDataSrc()
                                             throws Exception {
      try {

        /* Initialize the Datasource */
        ods = new OracleDataSource();

        /* Configure the Datasource with proper values of
         * Host Name, Sid, Port, Driver type, User Name and Password
         */
        this.configDSConnection();
       
        /* Enable cahcing */
        ods.setConnectionCachingEnabled(true);

        /* Set the cache name */
        ods.setConnectionCacheName(CACHE_NAME);

      } catch (SQLException sqlEx) { /* Catch SQL Errors */
         sqlEx.printStackTrace();
         throw new Exception("SQL Errors = " + sqlEx.toString());
      }catch (Exception ex) { /* Catch Generic Errors */
        ex.printStackTrace(); 
        throw new Exception("Generic Errors = " + ex.toString());
      }
    }

    /**
     * This method configures the Datasource with appropriate values of Host
     * Name, User Name, Password etc. Note that the configuration parameters are
     * stored in Connection.properties file.
     *
     * @param ods - OracleDataSource
     */
    private void configDSConnection() {
      try {
        /* Load the properties file to get the connection information 
         * from the Connection.properties file
         */
        Properties prop = this.loadParams("Connection");

        /* Set Host name */
        ods.setServerName(prop.getProperty("HostName"));

        /* Set Database SID */
        ods.setServiceName( prop.getProperty("SID"));

        /* Set Port number */
        ods.setPortNumber(new Integer( prop.getProperty("Port")).intValue());

        /* Set Driver type  */
        ods.setDriverType("thin");

        /* Set User name */
        ods.setUser( prop.getProperty("UserName") );

        /* Set Password */
        ods.setPassword( prop.getProperty("Password"));

      } catch (IOException ex) {
        ex.printStackTrace();
      } 
    }

    /**
     * This method reads a properties file, which is passed as the parameter  
     * and loads it into a java Properties object and returns the object.
     *
     * @param file - File name
     *
     * @return Properties object
     *
     * @throws IOException
     */
    private Properties loadParams(String file) throws IOException {
      /* Loads a ResourceBundle and creates Properties from it */
      Properties prop = new Properties();
      ResourceBundle bundle = ResourceBundle.getBundle(file);
      Enumeration enum = bundle.getKeys();
      String key = null;

      while (enum.hasMoreElements()) {
        key = (String) enum.nextElement();
        prop.put(key, bundle.getObject(key));
      }

      return prop;
    }
  }
E-mail this page
Printer View Printer View