View Javadoc

1   package org.apache.torque.dsfactory;
2   
3   /* ====================================================================
4    * The Apache Software License, Version 1.1
5    *
6    * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
7    * reserved.
8    *
9    * Redistribution and use in source and binary forms, with or without
10   * modification, are permitted provided that the following conditions
11   * are met:
12   *
13   * 1. Redistributions of source code must retain the above copyright
14   *    notice, this list of conditions and the following disclaimer.
15   *
16   * 2. Redistributions in binary form must reproduce the above copyright
17   *    notice, this list of conditions and the following disclaimer in
18   *    the documentation and/or other materials provided with the
19   *    distribution.
20   *
21   * 3. The end-user documentation included with the redistribution,
22   *    if any, must include the following acknowledgment:
23   *       "This product includes software developed by the
24   *        Apache Software Foundation (http://www.apache.org/)."
25   *    Alternately, this acknowledgment may appear in the software itself,
26   *    if and wherever such third-party acknowledgments normally appear.
27   *
28   * 4. The names "Apache" and "Apache Software Foundation" and
29   *    "Apache Turbine" must not be used to endorse or promote products
30   *    derived from this software without prior written permission. For
31   *    written permission, please contact apache@apache.org.
32   *
33   * 5. Products derived from this software may not be called "Apache",
34   *    "Apache Turbine", nor may "Apache" appear in their name, without
35   *    prior written permission of the Apache Software Foundation.
36   *
37   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48   * SUCH DAMAGE.
49   * ====================================================================
50   *
51   * This software consists of voluntary contributions made by many
52   * individuals on behalf of the Apache Software Foundation.  For more
53   * information on the Apache Software Foundation, please see
54   * <http://www.apache.org/>.
55   */
56  
57  import java.util.Iterator;
58  
59  import javax.sql.ConnectionPoolDataSource;
60  
61  import org.apache.commons.beanutils.ConvertUtils;
62  import org.apache.commons.beanutils.MappedPropertyDescriptor;
63  import org.apache.commons.beanutils.PropertyUtils;
64  
65  import org.apache.commons.configuration.Configuration;
66  import org.apache.commons.dbcp.cpdsadapter.DriverAdapterCPDS;
67  
68  import org.apache.commons.logging.Log;
69  import org.apache.commons.logging.LogFactory;
70  
71  import org.apache.torque.Torque;
72  import org.apache.torque.TorqueException;
73  
74  /***
75   * A class that contains common functionality of the factories in this
76   * package.
77   *
78   * @author <a href="mailto:jmcnally@apache.org">John McNally</a>
79   * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
80   * @version $Id: AbstractDataSourceFactory.java,v 1.12 2003/08/19 18:30:34 mpoeschl Exp $
81   */
82  public abstract class AbstractDataSourceFactory
83  {
84      /*** "pool" Key for the configuration */
85      public static final String POOL_KEY = "pool";
86  
87      /*** "connection" Key for the configuration */
88      public static final String CONNECTION_KEY = "connection";
89  
90      /*** "default.pool" Key for the configuration */
91      public static final String DEFAULT_POOL_KEY = "defaults.pool";
92  
93      /*** "default.connection" Key for the configuration */
94      public static final String DEFAULT_CONNECTION_KEY = "defaults.connection";
95  
96      /*** The log */
97      private static Log log = LogFactory.getLog(AbstractDataSourceFactory.class);
98  
99      /***
100      * Encapsulates setting configuration properties on
101      * <code>DataSource</code> objects.
102      *
103      * @param property the property to read from the configuration
104      * @param c the configuration to read the property from
105      * @param ds the <code>DataSource</code> instance to write the property to
106      * @throws Exception if anything goes wrong
107      */
108     protected void setProperty(String property, Configuration c, Object ds)
109         throws Exception
110     {
111         String key = property;
112         Class dsClass = ds.getClass();
113         int dot = property.indexOf('.');
114         try
115         {
116             if (dot > 0)
117             {
118                 property = property.substring(0, dot);
119 
120                 MappedPropertyDescriptor mappedPD =
121                     new MappedPropertyDescriptor(property, dsClass);
122                 Class propertyType = mappedPD.getMappedPropertyType();
123                 Configuration subProps = c.subset(property);
124                 // use reflection to set properties
125                 Iterator j = subProps.getKeys();
126                 while (j.hasNext())
127                 {
128                     String subProp = (String) j.next();
129                     String propVal = subProps.getString(subProp);
130                     Object value = ConvertUtils.convert(propVal, propertyType);
131                     PropertyUtils
132                         .setMappedProperty(ds, property, subProp, value);
133 
134                     if (log.isDebugEnabled())
135                     {
136                         log.debug("setMappedProperty("
137                                        + ds + ", "
138                                        + property + ", "
139                                        + subProp + ", "
140                                        + value
141                                        + ")");
142                     }
143                 }
144             }
145             else
146             {
147                 Class propertyType =
148                     PropertyUtils.getPropertyType(ds, property);
149                 Object value =
150                     ConvertUtils.convert(c.getString(property), propertyType);
151                 PropertyUtils.setSimpleProperty(ds, property, value);
152 
153                 if (log.isDebugEnabled())
154                 {
155                     log.debug("setSimpleProperty("
156                                    + ds + ", "
157                                    + property + ", "
158                                    + value
159                                    + ")");
160                 }
161             }
162         }
163         catch (Exception e)
164         {
165             log.error(
166                 "Property: "
167                 + property
168                 + " value: "
169                 + c.getString(key)
170                 + " is not supported by DataSource: "
171                 + ds.getClass().getName());
172         }
173     }
174 
175     /***
176      * Iterate over a Configuration subset and apply all
177      * properties to a passed object which must contain Bean
178      * setter and getter
179      *
180      * @param c The configuration subset
181      * @param o The object to apply the properties to
182      * @throws TorqueException if a property set fails
183      */
184     protected void applyConfiguration(Configuration c, Object o)
185         throws TorqueException
186     {
187         log.debug("applyConfiguration(" + c + ", " + o + ")");
188 
189         if (c != null)
190         {
191             try
192             {
193                 for (Iterator i = c.getKeys(); i.hasNext();)
194                 {
195                     String key = (String) i.next();
196                     setProperty(key, c, o);
197                 }
198             }
199             catch (Exception e)
200             {
201                 log.error(e);
202                 throw new TorqueException(e);
203             }
204         }
205     }
206     
207     /***
208      * Initializes the ConnectionPoolDataSource.
209      *
210      * @param configuration where to read the settings from
211      * @throws TorqueException if a property set fails
212      * @return a configured <code>ConnectionPoolDataSource</code>
213      */
214     protected ConnectionPoolDataSource initCPDS(Configuration configuration)
215         throws TorqueException
216     {
217         log.debug("Starting initCPDS");
218         ConnectionPoolDataSource cpds = new DriverAdapterCPDS();
219         Configuration c = Torque.getConfiguration();
220 
221         if (c == null)
222         {
223             log.warn("Global Configuration not set,"
224                     + " no Default connection pool data source configured!");
225         }
226         else
227         {
228             Configuration conf = c.subset(DEFAULT_CONNECTION_KEY);
229             applyConfiguration(conf, cpds);
230         }
231             
232         Configuration conf = configuration.subset(CONNECTION_KEY);
233         applyConfiguration(conf, cpds);
234         
235         return cpds;
236     }
237 }