jmcnally    02/05/25 21:30:10

  Modified:    src/java/org/apache/torque Torque.java
               src/rttest Torque.properties
               xdocs    jdbc2pool-howto.xml
  Added:       src/java/org/apache/torque/dsfactory
                        AbstractDataSourceFactory.java
                        DataSourceFactory.java JndiDataSourceFactory.java
  Log:
  created a factory abstraction for getting the DataSource to be used with
  torque.  Moved the jndi based code to a factory implementation.  Updated the
  howto doc accordingly.
  
  I plan to implement a couple more factories that avoid the use of jndi and
  avoid some of the complexity.
  
  Revision  Changes    Path
  1.60      +42 -244   jakarta-turbine-torque/src/java/org/apache/torque/Torque.java
  
  Index: Torque.java
  ===================================================================
  RCS file: /home/cvs/jakarta-turbine-torque/src/java/org/apache/torque/Torque.java,v
  retrieving revision 1.59
  retrieving revision 1.60
  diff -u -r1.59 -r1.60
  --- Torque.java       23 May 2002 18:25:53 -0000      1.59
  +++ Torque.java       26 May 2002 04:30:10 -0000      1.60
  @@ -87,6 +87,7 @@
   import org.apache.torque.oid.IDBroker;
   import org.apache.torque.util.BasePeer;
   import org.apache.torque.manager.AbstractBaseManager;
  +import org.apache.torque.dsfactory.DataSourceFactory;
   import org.apache.commons.configuration.Configuration;
   import org.apache.commons.configuration.PropertiesConfiguration;
   import org.apache.stratum.lifecycle.Configurable;
  @@ -103,7 +104,7 @@
    * @author <a href="mailto:[EMAIL PROTECTED]";>Jason van Zyl</a>
    * @author <a href="mailto:[EMAIL PROTECTED]";>Rafal Krzewski</a>
    * @author <a href="mailto:[EMAIL PROTECTED]";>Martin Poeschl</a>
  - * @version $Id: Torque.java,v 1.59 2002/05/23 18:25:53 jmcnally Exp $
  + * @version $Id: Torque.java,v 1.60 2002/05/26 04:30:10 jmcnally Exp $
    */
   public class Torque implements Initializable, Configurable
   {
  @@ -142,14 +143,9 @@
       private static Map dbMaps;
   
       /** 
  -     * The cache of initial contexts that contain jdbc datasources 
  +     * The cache of DataSourceFactory's 
        */
  -    private static Map jndiContexts;
  -
  -    /** 
  -     * The cache of jndi paths to jdbc datasources 
  -     */
  -    private static Map dsJndiPaths;
  +    private static Map dsFactoryMap;
   
       /** 
        * The cache of datasources 
  @@ -162,12 +158,6 @@
       private static Map adapterMap;
   
       /**
  -     * The various connection pools this broker contains.  Keyed by
  -     * database URL.
  -     */
  -    private static Map pools;
  -
  -    /**
        * A repository of Manager instances.
        */
       protected static Map managers = new HashMap();
  @@ -248,11 +238,9 @@
           }
   
           dbMaps = new HashMap();
  -        pools = new HashMap();
           DBFactory.init(configuration);
           initAdapters(configuration);
  -        initJNDI(configuration);
  -        initDataSources(configuration);
  +        initDataSourceFactories(configuration);
   
           isInit = true;
           for (Iterator i = mapBuilders.iterator(); i.hasNext(); )
  @@ -267,71 +255,6 @@
           initManagerMappings(configuration);
       }
   
  -    private static final void initJNDI(Configuration configuration)
  -        throws TorqueException
  -    {
  -        category.debug("Starting initJNDI"); 
  -        jndiContexts = new HashMap();
  -        dsJndiPaths = new HashMap();
  -        Configuration c = configuration.subset("jndi");
  -        //Map dsMap = new HashMap();
  -        if (c != null) 
  -        {
  -            try
  -            {
  -                Iterator i = c.getKeys();
  -                while (i.hasNext())
  -                {
  -                    String key = (String)i.next();                
  -                    if (key.endsWith("path"))
  -                    {
  -                        String path = c.getString(key);
  -                        String handle = key.substring(0, key.indexOf('.'));
  -                        //dsMap.put(name, cpdsClassName);
  -                        category.debug("JNDI handle: " + handle + 
  -                                       " path: " + path);
  -                        
  -                        Configuration jndiProps = c.subset(handle);
  -                        
  -                        Hashtable env = new Hashtable();
  -                        Iterator j = jndiProps.getKeys();
  -                        while (j.hasNext())
  -                        {
  -                            String prop = (String)j.next();
  -                            if ( !"path".equals(prop) ) 
  -                            {
  -                                category.debug("Setting jndi " + handle +
  -                                               " property: " + prop);
  -                                env.put(prop, jndiProps.getString(prop)); 
  -                            }
  -                        }
  -                        if ( env.size() == 0 ) 
  -                        {
  -                            jndiContexts.put(handle, new InitialContext());
  -                        }
  -                        else 
  -                        {
  -                            jndiContexts.put(handle, new InitialContext(env));
  -                        }
  -                        
  -                        dsJndiPaths.put(handle, path);
  -                }
  -            }
  -        }
  -        catch (Exception e)
  -        {
  -            category.error("", e);
  -            throw new TorqueException(e);
  -        }        
  -        }
  -        else 
  -        {
  -            category.error(
  -                "There were no datasource paths in the configuration");
  -        }
  -        
  -    }
  -
       private static final void initAdapters(Configuration configuration)
           throws TorqueException
       {
  @@ -369,174 +292,41 @@
           }        
       }
   
  -
  -    private static final void initDataSources(Configuration configuration)
  +    private static void initDataSourceFactories(Configuration configuration)
           throws TorqueException
       {
  -        category.debug("Starting initDataSources"); 
  -        Configuration c = configuration.subset("datasource");
  -        try
  +        category.debug("Starting initDSF"); 
  +        dsFactoryMap = new HashMap();
  +        Configuration c = configuration.subset("dsfactory");
  +        if (c != null) 
           {
  -            Class mapClass = Class.forName("java.util.Map");
  -            if (c != null) 
  -            {            
  -            Iterator i = c.getKeys();
  -            while (i.hasNext())
  +            try
               {
  -                String key = (String)i.next();                
  -                if (key.endsWith("factory"))
  +                Iterator i = c.getKeys();
  +                while (i.hasNext())
                   {
  -                    String classname = c.getString(key);
  -                    String handle = key.substring(0, key.indexOf('.'));
  -                    category.debug("Datasource handle: " + handle + 
  -                                   " factory: " + classname);
  -
  -                    Class dsClass = Class.forName(classname);
  -                    Object ds = dsClass.newInstance();
  -                    Configuration dsProps = c.subset(handle);
  -                    // use reflection to set properties
  -                    Iterator j = dsProps.getKeys();
  -                    while (j.hasNext())
  -                    {
  -                        String property = (String)j.next();
  -                        if ( !"factory".equals(property) ) 
  -                        {
  -                            category.debug("Setting datasource " + handle +
  -                                           " property: " + property);
  -                            setProperty(property, dsProps, ds);
  -                        }
  -                    }
  -
  -                    Context ctx = (Context)jndiContexts.get(handle);
  -                    if ( ctx == null ) 
  +                    String key = (String)i.next();                
  +                    if (key.endsWith("factory"))
                       {
  -                        if ( dsMap == null) 
  -                        {
  -                            dsMap = new HashMap();
  -                        }
  -                        dsMap.put(handle, ds);
  +                        String classname = c.getString(key);
  +                        String handle = key.substring(0, key.indexOf('.'));
  +                        category.debug("handle: " + handle + 
  +                                       " DataSourceFactory: " + classname);
  +                        
  +                        Class dsfClass = Class.forName(classname);
  +                        DataSourceFactory dsf = 
  +                            (DataSourceFactory)dsfClass.newInstance();
  +                        dsf.initialize(c.subset(handle));
  +                        dsFactoryMap.put(handle, dsf);
                       }
  -                    else 
  -                    {
  -                        // bind the datasource
  -                        String path = (String)dsJndiPaths.get(handle);
  -                        bindDStoJndi(ctx, path, ds);
  -                    }                    
                   }
  -            }   
  -            }            
  -        }
  -        catch (Exception e)
  -        {
  -            category.error("", e);
  -            throw new TorqueException(e);
  -        }    
  -    }
  -
  -    private static void bindDStoJndi(Context ctx, String path, Object ds) 
  -        throws Exception
  -    {
  -                    // Start debugging
  -                    category.debug("instantiated InitialContext");
  -                    Map env = ctx.getEnvironment();
  -                    Iterator qw = env.keySet().iterator();
  -                    category.debug("Environment properties:" + env.size() );
  -                    while ( qw.hasNext() ) 
  -                    {
  -                        Object prop = qw.next();
  -                        category.debug("    " + prop + ": " + env.get(prop) );
  -                    }
  -                    // End debugging
  -
  -                    // add subcontexts, if not added already
  -                    int start = path.indexOf(':') + 1;
  -                    if ( start > 0 ) 
  -                    {
  -                        path = path.substring(start);
  -                    }
  -                    StringTokenizer st = new StringTokenizer(path, "/");
  -                    while ( st.hasMoreTokens() ) 
  -                    {
  -                        String subctx = st.nextToken();
  -                        if ( st.hasMoreTokens() ) 
  -                        {
  -                            try
  -                            {
  -                                ctx.createSubcontext(subctx);
  -                                category.debug("Added sub context: "+subctx); 
  -                            }
  -                            catch(NameAlreadyBoundException nabe)
  -                            {
  -                                // ignore
  -                            }
  -                            catch(NamingException ne)
  -                            {
  -                                // even though there is a specific exception
  -                                // for this condition, some implementations
  -                                // throw the more general one.
  -                                /*
  -                                if (ne.getMessage().indexOf("already bound") == -1 
) 
  -                                {
  -                                    throw ne;
  -                                }
  -                                */
  -                                // ignore
  -                            }
  -                            ctx = (Context)ctx.lookup(subctx);
  -                        }
  -                        else 
  -                        {
  -                            // not really a subctx, it is the ds name
  -                            ctx.bind(subctx, ds);
  -                        }                        
  -                    }
  -    }
  -
  -    private static void setProperty(String property, Configuration c, 
  -                                    Object ds)
  -        throws Exception
  -    {
  -        String key = property;
  -        Class dsClass = ds.getClass();
  -        int dot = property.indexOf('.');
  -        try
  -        {
  -            if ( dot > 0 )
  +            }
  +            catch (Exception e)
               {
  -                property = property.substring(0, dot);                
  -
  -                MappedPropertyDescriptor mappedPD = 
  -                    new MappedPropertyDescriptor(property, dsClass);
  -                Class propertyType = mappedPD.getMappedPropertyType();
  -                Configuration subProps = c.subset(property);
  -                // use reflection to set properties
  -                Iterator j = subProps.getKeys();
  -                while (j.hasNext())
  -                {
  -                    String subProp = (String)j.next();
  -                    String propVal = subProps.getString(subProp);
  -                    Object value = ConvertUtils.convert(propVal, propertyType);
  -                    PropertyUtils
  -                        .setMappedProperty(ds, property, subProp, value);
  -                }
  -            }
  -            else 
  -            {
  -                Class propertyType = 
  -                    PropertyUtils.getPropertyType(ds, property);
  -                Object value = 
  -                    ConvertUtils.convert(c.getString(property), propertyType);
  -                PropertyUtils.setSimpleProperty(ds, property, value);
  +                category.error("", e);
  +                throw new TorqueException(e);
               }
           }
  -        catch (Exception e)
  -        {
  -            category.error("Property: " + property + " value: "
  -                           + c.getString(key) +
  -                           " is not supported by DataSource: " + 
  -                           ds.getClass().getName());
  -            throw e;
  -        }
       }
   
       /**
  @@ -1027,10 +817,8 @@
           Connection con = null;
           try
           {
  -            Context ctx = (Context)jndiContexts.get(name);
  -            String jndiPath = (String)dsJndiPaths.get(name);
  -            con = ((DataSource)ctx.lookup(jndiPath))
  -                .getConnection(username, password);
  +            DataSourceFactory dsf = (DataSourceFactory)dsFactoryMap.get(name);
  +            con = dsf.getDataSource().getConnection(username, password);
           }
           catch (Exception e)
           {
  @@ -1042,7 +830,17 @@
       public static Connection getConnection(String name)
           throws TorqueException
       {
  -        return getConnection(name, null, null);
  +        Connection con = null;
  +        try
  +        {
  +            DataSourceFactory dsf = (DataSourceFactory)dsFactoryMap.get(name);
  +            con = dsf.getDataSource().getConnection();
  +        }
  +        catch (Exception e)
  +        {
  +            throw new TorqueException(e);
  +        }
  +        return con;
       }
   
       /**
  
  
  
  1.1                  
jakarta-turbine-torque/src/java/org/apache/torque/dsfactory/AbstractDataSourceFactory.java
  
  Index: AbstractDataSourceFactory.java
  ===================================================================
  package org.apache.torque.dsfactory;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Turbine" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.IOException;
  import java.sql.Connection;
  import javax.sql.DataSource;
  import java.beans.PropertyDescriptor;
  import java.beans.PropertyEditorManager;
  import java.beans.PropertyEditor;
  import java.lang.reflect.Method;
  import java.io.File;
  import java.util.HashMap;
  import java.util.Enumeration;
  import java.util.Iterator;
  import java.util.Map;
  import java.util.List;
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.Properties;
  import java.util.Hashtable;
  import java.util.StringTokenizer;
  import javax.naming.Context;
  import javax.naming.InitialContext;
  import javax.naming.NameAlreadyBoundException;
  import javax.naming.NamingException;
  import org.apache.log4j.Category;
  import org.apache.log4j.PropertyConfigurator;
  import org.apache.log4j.helpers.NullEnumeration;
  import org.apache.torque.adapter.DB;
  import org.apache.torque.adapter.DBFactory;
  import org.apache.torque.map.DatabaseMap;
  import org.apache.torque.map.TableMap;
  import org.apache.torque.oid.IDGeneratorFactory;
  import org.apache.torque.oid.IDBroker;
  import org.apache.torque.util.BasePeer;
  import org.apache.torque.manager.AbstractBaseManager;
  import org.apache.commons.configuration.Configuration;
  import org.apache.commons.configuration.PropertiesConfiguration;
  import org.apache.stratum.lifecycle.Configurable;
  import org.apache.stratum.lifecycle.Initializable;
  import org.apache.commons.beanutils.ConvertUtils;
  import org.apache.commons.beanutils.PropertyUtils;
  import org.apache.commons.beanutils.MappedPropertyDescriptor;
  
  /**
   * A class that contains common functionality of the factories in this
   * package.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>John McNally</a>
   * @version $Id: AbstractDataSourceFactory.java,v 1.1 2002/05/26 04:30:10 jmcnally 
Exp $
   */
  abstract class AbstractDataSourceFactory
  {
      /**
       * The logging category.
       */
      protected static Category category =
          Category.getInstance("org.apache.torque");
  
      protected void setProperty(String property, Configuration c, 
                                      Object ds)
          throws Exception
      {
          String key = property;
          Class dsClass = ds.getClass();
          int dot = property.indexOf('.');
          try
          {
              if ( dot > 0 )
              {
                  property = property.substring(0, dot);                
  
                  MappedPropertyDescriptor mappedPD = 
                      new MappedPropertyDescriptor(property, dsClass);
                  Class propertyType = mappedPD.getMappedPropertyType();
                  Configuration subProps = c.subset(property);
                  // use reflection to set properties
                  Iterator j = subProps.getKeys();
                  while (j.hasNext())
                  {
                      String subProp = (String)j.next();
                      String propVal = subProps.getString(subProp);
                      Object value = ConvertUtils.convert(propVal, propertyType);
                      PropertyUtils
                          .setMappedProperty(ds, property, subProp, value);
                  }
              }
              else 
              {
                  Class propertyType = 
                      PropertyUtils.getPropertyType(ds, property);
                  Object value = 
                      ConvertUtils.convert(c.getString(property), propertyType);
                  PropertyUtils.setSimpleProperty(ds, property, value);
              }
          }
          catch (Exception e)
          {
              category.error("Property: " + property + " value: "
                             + c.getString(key) +
                             " is not supported by DataSource: " + 
                             ds.getClass().getName());
              throw e;
          }
      }
  
  }
  
  
  
  1.1                  
jakarta-turbine-torque/src/java/org/apache/torque/dsfactory/DataSourceFactory.java
  
  Index: DataSourceFactory.java
  ===================================================================
  package org.apache.torque.dsfactory;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Turbine" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import javax.sql.DataSource;
  import org.apache.commons.configuration.Configuration;
  import org.apache.torque.TorqueException;
  
  /**
   * A factory that returns a DataSource.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>John McNally</a>
   * @version $Id: DataSourceFactory.java,v 1.1 2002/05/26 04:30:10 jmcnally Exp $
   */
  public interface DataSourceFactory
  {
      /**
       *
       */
      public DataSource getDataSource()
          throws TorqueException;
  
      /**
       * initialize
       *
       * @throws TorqueException Any exceptions caught during processing will be
       *         rethrown wrapped into a TorqueException.
       */
      public void initialize(Configuration configuration) 
          throws TorqueException;
  }
  
  
  
  1.1                  
jakarta-turbine-torque/src/java/org/apache/torque/dsfactory/JndiDataSourceFactory.java
  
  Index: JndiDataSourceFactory.java
  ===================================================================
  package org.apache.torque.dsfactory;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Turbine" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.IOException;
  import java.sql.Connection;
  import javax.sql.DataSource;
  import java.beans.PropertyDescriptor;
  import java.beans.PropertyEditorManager;
  import java.beans.PropertyEditor;
  import java.lang.reflect.Method;
  import java.io.File;
  import java.util.HashMap;
  import java.util.Enumeration;
  import java.util.Iterator;
  import java.util.Map;
  import java.util.List;
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.Properties;
  import java.util.Hashtable;
  import java.util.StringTokenizer;
  import javax.naming.Context;
  import javax.naming.InitialContext;
  import javax.naming.NameAlreadyBoundException;
  import javax.naming.NamingException;
  import org.apache.log4j.Category;
  import org.apache.log4j.PropertyConfigurator;
  import org.apache.log4j.helpers.NullEnumeration;
  import org.apache.commons.configuration.Configuration;
  import org.apache.commons.configuration.PropertiesConfiguration;
  import org.apache.stratum.lifecycle.Configurable;
  import org.apache.stratum.lifecycle.Initializable;
  import org.apache.commons.beanutils.ConvertUtils;
  import org.apache.commons.beanutils.PropertyUtils;
  import org.apache.commons.beanutils.MappedPropertyDescriptor;
  import org.apache.torque.TorqueException;
  
  /**
   * A factory that looks up the DataSource from JNDI.  It is also able
   * to deploy the DataSource based on properties found in the 
   * configuration.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>John McNally</a>
   * @version $Id: JndiDataSourceFactory.java,v 1.1 2002/05/26 04:30:10 jmcnally Exp $
   */
  public class JndiDataSourceFactory 
      extends AbstractDataSourceFactory
      implements DataSourceFactory
  {
      private String path;
      private Context ctx;
  
      /**
       *
       */
      public DataSource getDataSource()
          throws TorqueException
      {
          DataSource ds = null;
          try
          {
              ds = ((DataSource)ctx.lookup(path));
          }
          catch (Exception e)
          {
              throw new TorqueException(e);
          }
          return ds;
      }
  
      /**
       * initialize
       *
       * @throws TorqueException Any exceptions caught during processing will be
       *         rethrown wrapped into a TorqueException.
       */
      public void initialize(Configuration configuration) 
          throws TorqueException
      {
          if (configuration == null)
          {
              throw new TorqueException("Torque cannot be initialized without " +
                  "a valid configuration. Please check the log files " +
                      "for further details.");
          }        
          initJNDI(configuration);
          initDataSource(configuration);
      }
  
  
      private void initJNDI(Configuration configuration)
          throws TorqueException
      {
          category.debug("Starting initJNDI"); 
          Hashtable env = null;
          Configuration c = configuration.subset("jndi");
          if (c == null) 
          {
              throw new TorqueException("JndiDataSourceFactory requires a jndi "
                  + "path property to lookup the DataSource in JNDI.");
          }
          try
          {
              Iterator i = c.getKeys();
              while (i.hasNext())
              {
                  String key = (String)i.next();                
                  if (key.equals("path"))
                  {
                      path = c.getString(key);
                      category.debug("JNDI path: " + path);
                  }
                  else                 {
                      if (env == null) 
                      {
                          env = new Hashtable();
                      }
                      String value = c.getString(key);
                      env.put(key, value); 
                      category.debug("Set jndi property: " + key + "=" + value);
                  }
              }
              if (env == null) 
              {
                  ctx = new InitialContext();
              }
              else 
              {
                  ctx = new InitialContext(env);
              }
              category.debug("Created new InitialContext");
              debugCtx(ctx);
          }
          catch (Exception e)
          {
              category.error("", e);
              throw new TorqueException(e);
          }        
      }
  
      private void initDataSource(Configuration configuration)
          throws TorqueException
      {
          category.debug("Starting initDataSources"); 
          Configuration c = configuration.subset("datasource");
          try
          {
              if (c != null) 
              {            
                  Object ds = null;
                  Iterator i = c.getKeys();
                  while (i.hasNext())
                  {
                      String key = (String)i.next();
                      if (key.equals("classname"))
                      {
                          String classname = c.getString(key);
                          category.debug("Datasource class: "+classname);
  
                          Class dsClass = Class.forName(classname);
                          ds = dsClass.newInstance();
                      }
                      else 
                      {
                          category.debug("Setting datasource property: " 
                                         + key);
                          setProperty(key, c, ds);
                      }
                  }
  
                  bindDStoJndi(ctx, path, ds);
              }            
          }
          catch (Exception e)
          {
              category.error("", e);
              throw new TorqueException(e);
          }    
      }
  
      private void debugCtx(Context ctx)
          throws NamingException
      {
          category.debug("InitialContext -------------------------------");
          Map env = ctx.getEnvironment();
          Iterator qw = env.keySet().iterator();
          category.debug("Environment properties:" + env.size() );
          while ( qw.hasNext() ) 
          {
              Object prop = qw.next();
              category.debug("    " + prop + ": " + env.get(prop) );
          }
          category.debug("----------------------------------------------");
      }
  
      private void bindDStoJndi(Context ctx, String path, Object ds) 
          throws Exception
      {
          debugCtx(ctx);
  
          // add subcontexts, if not added already
          int start = path.indexOf(':') + 1;
          if ( start > 0 ) 
          {
              path = path.substring(start);
          }
          StringTokenizer st = new StringTokenizer(path, "/");
          while ( st.hasMoreTokens() ) 
          {
              String subctx = st.nextToken();
              if ( st.hasMoreTokens() ) 
              {
                  try
                  {
                      ctx.createSubcontext(subctx);
                      category.debug("Added sub context: "+subctx); 
                  }
                  catch(NameAlreadyBoundException nabe)
                  {
                      // ignore
                  }
                  catch(NamingException ne)
                  {
                      // even though there is a specific exception
                      // for this condition, some implementations
                      // throw the more general one.
                      /*
                        if (ne.getMessage().indexOf("already bound") == -1 ) 
                        {
                        throw ne;
                        }
                      */
                      // ignore
                  }
                  ctx = (Context)ctx.lookup(subctx);
              }
              else 
              {
                  // not really a subctx, it is the ds name
                  ctx.bind(subctx, ds);
              }                        
          }
      }
  }
  
  
  
  1.10      +22 -21    jakarta-turbine-torque/src/rttest/Torque.properties
  
  Index: Torque.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-turbine-torque/src/rttest/Torque.properties,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- Torque.properties 23 May 2002 18:26:35 -0000      1.9
  +++ Torque.properties 26 May 2002 04:30:10 -0000      1.10
  @@ -1,5 +1,5 @@
   # -------------------------------------------------------------------
  -# $Id: Torque.properties,v 1.9 2002/05/23 18:26:35 jmcnally Exp $
  +# $Id: Torque.properties,v 1.10 2002/05/26 04:30:10 jmcnally Exp $
   #
   # This is the configuration file for Torque.
   #
  @@ -47,26 +47,27 @@
   torque.database.default=bookstore
   torque.database.bookstore.adapter=mysql
   
  -torque.jndi.bookstore.path=jdbc/bookstore
  -torque.jndi.bookstore.java.naming.factory.initial = 
org.apache.naming.java.javaURLContextFactory
  -torque.jndi.bookstore.java.naming.factory.url.pkgs = org.apache.naming
  -
  -torque.jndi.DBbookstore.path=jdbc/DBbookstore
  -torque.jndi.DBbookstore.java.naming.factory.initial = 
org.apache.naming.java.javaURLContextFactory
  -torque.jndi.DBbookstore.java.naming.factory.url.pkgs = org.apache.naming
  -
  
-torque.datasource.bookstore.factory=org.apache.commons.jdbc2pool.TorqueClassicDataSource
  -torque.datasource.bookstore.dataSourceName=jdbc/DBbookstore
  -torque.datasource.bookstore.jndiEnvironment.java.naming.factory.initial = 
org.apache.naming.java.javaURLContextFactory
  -torque.datasource.bookstore.jndiEnvironment.java.naming.factory.url.pkgs = 
org.apache.naming
  -torque.datasource.bookstore.defaultMaxConnections=10
  -
  -
  
-torque.datasource.DBbookstore.factory=org.apache.commons.jdbc2pool.adapter.DriverAdapterCPDS
  -torque.datasource.DBbookstore.driver = @DATABASE_DRIVER@
  -torque.datasource.DBbookstore.url = @DATABASE_URL@
  -torque.datasource.DBbookstore.user = @DATABASE_USER@
  -torque.datasource.DBbookstore.password = @DATABASE_PASSWORD@
  +torque.dsfactory.bookstore.factory=org.apache.torque.dsfactory.JndiDataSourceFactory
  +torque.dsfactory.bookstore.jndi.path=jdbc/bookstore
  +torque.dsfactory.bookstore.jndi.java.naming.factory.initial = 
org.apache.naming.java.javaURLContextFactory
  +torque.dsfactory.bookstore.jndi.java.naming.factory.url.pkgs = org.apache.naming
  +
  
+torque.dsfactory.bookstore.datasource.classname=org.apache.commons.jdbc2pool.TorqueClassicDataSource
  +torque.dsfactory.bookstore.datasource.dataSourceName=jdbc/DBbookstore
  +torque.dsfactory.bookstore.datasource.jndiEnvironment.java.naming.factory.initial = 
org.apache.naming.java.javaURLContextFactory
  +torque.dsfactory.bookstore.datasource.jndiEnvironment.java.naming.factory.url.pkgs 
= org.apache.naming
  +torque.dsfactory.bookstore.datasource.defaultMaxConnections=10
  +
  +## ConnectionPoolDataSource
  
+torque.dsfactory.DBbookstore.factory=org.apache.torque.dsfactory.JndiDataSourceFactory
  +torque.dsfactory.DBbookstore.jndi.path=jdbc/DBbookstore
  +torque.dsfactory.DBbookstore.jndi.java.naming.factory.initial = 
org.apache.naming.java.javaURLContextFactory
  +torque.dsfactory.DBbookstore.jndi.java.naming.factory.url.pkgs = org.apache.naming
  
+torque.dsfactory.DBbookstore.datasource.classname=org.apache.commons.jdbc2pool.adapter.DriverAdapterCPDS
  +torque.dsfactory.DBbookstore.datasource.driver = @DATABASE_DRIVER@
  +torque.dsfactory.DBbookstore.datasource.url = @DATABASE_URL@
  +torque.dsfactory.DBbookstore.datasource.user = @DATABASE_USER@
  +torque.dsfactory.DBbookstore.datasource.password = @DATABASE_PASSWORD@
   
   # Determines if the quantity column of the IDBroker's id_table should
   # be increased automatically if requests for ids reaches a high
  
  
  
  1.5       +102 -54   jakarta-turbine-torque/xdocs/jdbc2pool-howto.xml
  
  Index: jdbc2pool-howto.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-turbine-torque/xdocs/jdbc2pool-howto.xml,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- jdbc2pool-howto.xml       24 May 2002 18:09:26 -0000      1.4
  +++ jdbc2pool-howto.xml       26 May 2002 04:30:10 -0000      1.5
  @@ -22,33 +22,47 @@
   Starting with Torque-3.0b3, torque no longer includes a built-in pool.  
   Torque's old pool has been updated to be a <code>javax.sql.DataSource</code>
   implementation and has been moved into the commons-sandbox/jdbc2pool package.
  -Torque now expects to be able to lookup a connection pool using jndi.  Torque 
  -also provides a simple property file based way to configure most
  +Torque now expects a factory that can return a <code>DataSource</code> and can
  +be configured using torque's configuration file.
  +</p>
  +
  +<p>
  +Currently Torque provides a 
  +factory that uses jndi to retrieve the <code>DataSource</code>.  This factory 
  +also provides a simple property file based way to configure and deploy most
   <code>DataSource</code>'s, though in many cases a pool may already be 
  -bound to jndi and torque only needs to use it. 
  +bound to jndi and torque only needs to use it. It is expected that very soon
  +a couple more factories will be available to allow a simpler arrangement than
  +using jndi.
   </p>
   
  -</section>
  +<p>
  +Before going over how to configure the factories which will take up most the
  +content of this document, there is one other configuration that needs covered: 
  +adapters.
  +</p>
   
  +</section>
   
  -<section name="Using pre-configured pool">
  +<section name="Database Adapters">
   
   <p>
  -If a pool is known to already be available via jndi, the configuration for
  -torque to use it can be very simple.  In all examples that follow we will
  -use the handle, bookstore.  This is the name attribute that is used in the
  -&lt;database&gt; tag in the schema.xml.  If the name attribute is not used, then the
  -handle would be 'default'.
  +Previously, Torque provided an internal map between many Drivers and a set
  +of adapter classes which are used to account for differences among databases.
  +This arrangement is no longer possible using <code>DataSource</code>, so
  +the adapter must be given in the configuration.  In all examples that follow we
  +will use the handle, bookstore.  This is the name attribute that is used in the
  +&lt;database&gt; tag in the schema.xml.  If the name attribute is not used, then 
the handle would be 'default'.
  +The adapter property is given as:
   </p>
   
   <source><![CDATA[
   torque.database.bookstore.adapter=mysql
  -torque.jndi.bookstore.path=jdbc/bookstore
   ]]></source>
   
   <p>
  -The first line defines the adapter that will be used to compensate for
  -the differences between databases.  The valid values are:
  +The valid values are:
  +</p>
   
   <table align="center">
   <tr>
  @@ -81,12 +95,38 @@
   </tr>
   </table>
   
  -The second line defines the string that will be used to lookup the 
  -<code>DataSource</code> within the default jndi <code>InitialContext</code>.
  +</section>
  +
  +<section name="JndiDataSourceFactory">
  +
  +<p>
  +This factory is used if the <code>DataSource</code> is to be available via
  +jndi.  It is possible to use this factory to deploy a <code>DataSource</code>
  +into jndi, but in many cases for using this factory the <code>DataSource</code>
  +is already deployed.  This factory is specified with the following property:
  +</p>
  +
  +<source><![CDATA[
  +torque.dsfactory.bookstore.factory=org.apache.torque.dsfactory.JndiDataSourceFactory
  +]]></source>
  +
  +
  +<subsection name="Using pre-configured pool">
  +
  +<p>
  +If a pool is known to already be available via jndi, only one more property
  +is required.
   </p>
  +
  +<source><![CDATA[
  +torque.dsfactory.bookstore.jndi.path=jdbc/bookstore
  +]]></source>
  +
   <p>
  +This line defines the string that will be used to lookup the 
  +<code>DataSource</code> within the default jndi <code>InitialContext</code>.
   If everything is configured and the default <code>InitialContext</code> 
  -contains the <code>DataSource</code>, the two lines above are all that is
  +contains the <code>DataSource</code>, this is all that is
   needed.  The default <code>InitialContext</code> is chosen according to the
   rules given in the class's javadoc.  If the default has not been configured,
   you can specify any other environment properties that are needed to instantiate
  @@ -95,13 +135,19 @@
   </p>
   
   <source><![CDATA[
  -torque.jndi.bookstore.java.naming.factory.initial = 
org.apache.naming.java.javaURLContextFactory
  -torque.jndi.bookstore.java.naming.factory.url.pkgs = org.apache.naming
  +torque.dsfactory.bookstore.jndi.java.naming.factory.initial = 
org.apache.naming.java.javaURLContextFactory
  +torque.dsfactory.bookstore.jndi.java.naming.factory.url.pkgs = org.apache.naming
   ]]></source>
   
  -</section>
  +<p>
  +Such environment settings will likely not be necessary when running within
  +a J2EE container, but they are useful in other cases.  One such case is when
  +running torque's unit/run-time tests
  +</p>
  +
  +</subsection>
   
  -<section name="Using torque to bind pool">
  +<subsection name="Using torque to bind pool">
   
   <p>
   Generally a J2EE environment such as a servlet engine or application server is
  @@ -110,23 +156,23 @@
   only use of a connection pool, torque provides a simple properties file
   method of configuring a <code>DataSource</code> and deploying it via jndi.
   The one property that is necessary for all <code>DataSource</code>'s is the
  -<code>ObjectFactory</code> classname that is used to instantiate the 
<code>DataSource</code>.  Beyond that the properties are implementation specific.
  +classname the <code>DataSource</code> implementation.  Beyond that the properties 
are implementation specific.
   <code>DataSource</code>'s contain getters/setters for configuration.  You
   can specify the values for these properties as shown below:
   </p>
   
   <source><![CDATA[
  
-torque.datasource.bookstore.factory=org.apache.commons.jdbc2pool.TorqueClassicDataSource
  -torque.datasource.bookstore.dataSourceName=jdbc/DBbookstore
  -torque.datasource.bookstore.defaultMaxConnections=10
  
+torque.dsfactory.bookstore.datasource.classname=org.apache.commons.jdbc2pool.TorqueClassicDataSource
  +torque.dsfactory.bookstore.datasource.dataSourceName=jdbc/DBbookstore
  +torque.dsfactory.bookstore.datasource.defaultMaxConnections=10
   ]]></source>
   
   <source><![CDATA[
  
-torque.datasource.DBbookstore.factory=org.apache.commons.jdbc2pool.adapter.DriverAdapterCPDS
  -torque.datasource.DBbookstore.driver = org.gjt.mm.mysql.Driver
  -torque.datasource.DBbookstore.url = jdbc:mysql://localhost:3306/bookstore
  -torque.datasource.DBbookstore.user = root
  -torque.datasource.DBbookstore.password = 1234
  
+torque.dsfactory.DBbookstore.datasource.factory=org.apache.commons.jdbc2pool.adapter.DriverAdapterCPDS
  +torque.dsfactory.DBbookstore.datasource.driver = org.gjt.mm.mysql.Driver
  +torque.dsfactory.DBbookstore.datasource.url = jdbc:mysql://localhost:3306/bookstore
  +torque.dsfactory.DBbookstore.datasource.user = root
  +torque.dsfactory.DBbookstore.datasource.password = 1234
   ]]></source>
   
   <p>
  @@ -149,19 +195,19 @@
   </p>
   
   <source><![CDATA[
  -torque.jndi.bookstore.path=jdbc/bookstore
  -torque.jndi.DBbookstore.path=jdbc/DBbookstore
  +torque.dsfactory.bookstore.jndi.path=jdbc/bookstore
  +torque.dsfactory.DBbookstore.jndi.path=jdbc/DBbookstore
   ]]></source>
   
   <p>
  -where the second handle, DBbookstore, has no relevance to torque, other than 
  +The second handle, DBbookstore, has no relevance to torque, other than 
   to uniquely identify this group of properties as belonging together.  Any 
   unique handle may be used.
   </p>
   
  -</section>
  +</subsection>
   
  -<section name="Tomcat example of external configuration/binding">
  +<subsection name="Tomcat example of external configuration/binding">
   
   <p>
   If you have other parts of your application that need to use the same 
  @@ -233,7 +279,7 @@
   </p>
   
   <source><![CDATA[
  -torque.jndi.bookstore.path=java:comp/env/jdbc/bookstore
  +torque.dsfactory.bookstore.jndi.path=java:comp/env/jdbc/bookstore
   ]]></source>
   
   <p>
  @@ -252,40 +298,41 @@
   implementation classname is used in our configuration example.
   </p>
   
  -</section>
  +</subsection>
   
   
  -<section name="An example configuration from scarab">
  +<subsection name="An example configuration from scarab">
   
   <p>
  -The following example shows a complete working torque configuration from the 
  -scarab, issue tracking application.  It is here to put together some of the 
  -details shown above.
  +The following example shows a complete torque configuration from 
  +scarab, an issue tracking application, running under catalina, but using torque
  +to deploy the <code>DataSource</code>.  It is here to 
  +put together some of the details shown above.
   </p>
   
   <source><![CDATA[
   torque.database.scarab.adapter=mysql
   
   # Jndi location
  -torque.jndi.scarab.path=jdbc/scarab
  -torque.jndi.DBscarabDB.path=jdbc/DBscarabDB
  +torque.dsfactory.scarab.jndi.path=jdbc/scarab
  +torque.dsfactory.DBscarabDB.jndi.path=jdbc/DBscarabDB
   
   # Connection properties for the pooling DataSource
   # These properties will vary from one datasource to another, see the class
   # javadoc for a description of which properties can be set.
  
-torque.datasource.scarab.factory=org.apache.commons.jdbc2pool.TorqueClassicDataSource
  -torque.datasource.scarab.dataSourceName=jdbc/DBscarabDB
  -torque.datasource.scarab.defaultMaxConnections=30
  -torque.datasource.scarab.maxExpiryTime=3600
  -torque.datasource.scarab.connectionWaitTimeout=10
  -torque.datasource.scarab.logInterval=0
  
+torque.dsfactory.scarab.datasource.classname=org.apache.commons.jdbc2pool.TorqueClassicDataSource
  +torque.dsfactory.scarab.datasource.dataSourceName=jdbc/DBscarabDB
  +torque.dsfactory.scarab.datasource.defaultMaxConnections=30
  +torque.dsfactory.scarab.datasource.maxExpiryTime=3600
  +torque.dsfactory.scarab.datasource.connectionWaitTimeout=10
  +torque.dsfactory.scarab.datasource.logInterval=0
   
   # Connection properties for the ConnectionPoolDataSource
  
-torque.datasource.DBscarabDB.factory=org.apache.commons.jdbc2pool.adapter.DriverAdapterCPDS
  -torque.datasource.DBscarabDB.driver=org.gjt.mm.mysql.Driver
  -torque.datasource.DBscarabDB.url=jdbc:mysql://localhost:3306/scarab
  -torque.datasource.DBscarabDB.user=xxx
  -torque.datasource.DBscarabDB.password=yyy
  
+torque.dsfactory.DBscarabDB.datasource.classname=org.apache.commons.jdbc2pool.adapter.DriverAdapterCPDS
  +torque.dsfactory.DBscarabDB.datasource.driver=org.gjt.mm.mysql.Driver
  +torque.dsfactory.DBscarabDB.datasource.url=jdbc:mysql://localhost:3306/scarab
  +torque.dsfactory.DBscarabDB.datasource.user=xxx
  +torque.dsfactory.DBscarabDB.datasource.password=yyy
   
   
   # Determines if the quantity column of the IDBroker's id_table should
  @@ -304,8 +351,9 @@
   
   ]]></source>
   
  -</section>
  +</subsection>
   
  +</section>
   
   </body>
   </document>
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to