20.4. How To code your own connection provider class

To create your own connection provider class, follow these steps:

  1. create a new class that extends " org.dbforms.conprovider.ConnectionProvider" class:

      public class MyOwnConnectionProvider extends ConnectionProvider 
      {
        ...
      }
                 

  2. create a default constructor like this one:

      /**
       *  Default constructor.
       *
       * @throws Exception because of the <code>throws Exception</code> clause
       *                   of the  <code>init</code> method.
       */
      public MyConnectionProvider() throws Exception 
      {   
         super();    // up to now, do nothing...
      }
                

  3. implement the following ConnectionProvider abstract methods:

    • protected abstract void init() throws Exception;

    • protected abstract Connection getConnection() throws SQLException;

20.4.1. Using pool-property elements to configure the JDBC connection pool attributes

A connectionProvider class can configure its connection pool attributes sing the values specificed by the pool-property xml elements, children of the dbconnection element of the dbforms-config.xml file.

Here's an example of the configuration of the dbconnection element that uses the ProtomatterConnectionProvider class to obtain JDBC connections from the database:

  <dbconnection
    id                      = "protomatter"
    isJndi                  = "false"
    isPow2                  = "true"
    defaultConnection       = "true"
    connectionProviderClass = "org.dbforms.conprovider.ProtomatterConnectionProvider"
    connectionPoolURL       = "jdbc:protomatter:pool:postgresPool"
    conClass                = "org.postgresql.Driver"
    name                    = "jdbc:postgresql://myHost/myDb"
    username                = "secret"
    password                = "moreSecret">
        
    <!-- jdbc properties -->
    <property name="charSet" value="ISO-8859-1" />
        
    <!-- Connection pool dataSource properties -->
    <pool-property name="pool.initialSize"             value="4"   />
    <pool-property name="pool.maxSize"                 value="10"  />
    <pool-property name="pool.growBlock"               value="2"   />
    <pool-property name="pool.createWaitTime"          value="100" />
    <pool-property name="pool.maxConnectionIdleTime"   value=""    />
    <pool-property name="pool.maidThreadCheckInterval" value=""    />
    <pool-property name="jdbc.validityCheckStatement"  value=""    />
  </dbconnection>
        

When a ConnectionProvider class is instantiated, it can access to the connection pool properties using the following statement:

  Properties props = prefs.getPoolProperties();
        

The "name" attribute of the pool-property xml element becomes the property key that must be used to retrieve the property value from the above Properties class.

Every connection pool package uses its own configuration system; here's the example code used to configure the ProtomatterConnectionProvider class:

  Properties props = null;
  ...

  // now set the connection pool custom properties;    
  // if the connectionPool properties object is null,
  // instance a new properties object anyway, to use default values;
  if ((props = prefs.getPoolProperties()) == null)
    props = new Properties();

  // use defaults values as specified into the documentation;
  setIntegerArg(args, props, CP_PROPS_INITIALSIZE,             "0");
  setIntegerArg(args, props, CP_PROPS_MAXSIZE,                 "-1");
  setIntegerArg(args, props, CP_PROPS_GROWBLOCK,               "1");
  setIntegerArg(args, props, CP_PROPS_CREATEWAITTIME,          "0");
  setArg       (args, props, CP_PROPS_VALIDITYCHECKSTATEMENT,  null);
  setIntegerArg(args, props, CP_PROPS_MAXCONNECTIONIDLETIME,   null);
  setIntegerArg(args, props, CP_PROPS_MAIDTHREADCHECKINTERVAL, null);
  
  // finally create the pool and we're ready to go!
  Class.forName(CP_DRIVER).newInstance();
  connectionPool = new JdbcConnectionPool(getLastToken(prefs.getConnectionPoolURL(), ":"), args);
        

and here's the (simpler) code for J akartaConnectionProvider class:

  Properties props = null;
  ...

  // now set the connection pool custom properties;
  // if the connectionPool properties object is null,
  // instance a new properties object anyway, to use default values;
  if ((props = prefs.getPoolProperties()) == null)
    props = new Properties();

  String validationQuery = props.getProperty(CP_PROPS_VALIDATION_QUERY, null);

  if (!Util.isNull(validationQuery))
    dataSource.setValidationQuery(validationQuery.trim());

  dataSource.setMaxActive (Integer.parseInt(props.getProperty(CP_PROPS_MAX_ACTIVE,"20")));
  dataSource.setMaxIdle   (Integer.parseInt(props.getProperty(CP_PROPS_MAX_IDLE,"5")));
  dataSource.setMaxWait   (Long.parseLong  (props.getProperty(CP_PROPS_MAX_WAIT,"-1")));

  // if PROPS_LOG == true, use log4j category to log the datasource info;
  String useLog = props.getProperty(CP_PROPS_USE_LOG, "false");

  if (!Util.isNull(useLog)  "true".equals(useLog.trim()))
  {
    cat.info("::init - dataSource log activated");
    dataSource.setLogWriter(new Log4jPrintWriter(cat, cat.getPriority()));
  }