KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > avalon > excalibur > datasource > ResourceLimitingJdbcDataSource


1 /*
2  * Copyright (C) The Apache Software Foundation. All rights reserved.
3  *
4  * This software is published under the terms of the Apache Software License
5  * version 1.1, a copy of which has been included with this distribution in
6  * the LICENSE.txt file.
7  */

8 package org.apache.avalon.excalibur.datasource;
9
10 import java.sql.Connection JavaDoc;
11 import java.sql.SQLException JavaDoc;
12
13 import org.apache.avalon.excalibur.datasource.DataSourceComponent;
14 import org.apache.avalon.excalibur.datasource.JdbcConnectionFactory;
15 import org.apache.avalon.excalibur.datasource.NoAvailableConnectionException;
16 import org.apache.avalon.framework.activity.Disposable;
17 import org.apache.avalon.framework.configuration.Configuration;
18 import org.apache.avalon.framework.configuration.ConfigurationException;
19 import org.apache.avalon.framework.logger.AbstractLogEnabled;
20
21 /**
22  * The ResourceLimiting implementation for DataSources in Avalon. This uses the
23  * normal <code>java.sql.Connection</code> object and
24  * <code>java.sql.DriverManager</code>. The Configuration is like this:
25  *
26  * <pre>
27  * &lt;jdbc&gt;
28  * &lt;pool-controller max="<i>10</i>" blocking="<i>true</i>"
29  * timeout="<i>-1</i>" trim-interval="<i>60000</i>"
30  * connection-class="<i>my.overrided.ConnectionClass</i>"&gt;
31  * &lt;keep-alive disable="false"&gt;select 1&lt;/keep-alive&gt;
32  * &lt;/pool-controller&gt;
33  * &lt;driver&gt;<i>com.database.jdbc.JdbcDriver</i>&lt;/driver&gt;
34  * &lt;dburl&gt;<i>jdbc:driver://host/mydb</i>&lt;/dburl&gt;
35  * &lt;user&gt;<i>username</i>&lt;/user&gt;
36  * &lt;password&gt;<i>password</i>&lt;/password&gt;
37  * &lt;/jdbc&gt;
38  * </pre>
39  *
40  * With the following roles declaration:
41  *
42  * <pre>
43  * &lt;role name="org.apache.avalon.excalibur.datasource.DataSourceComponentSelector"
44  * shorthand="datasources"
45  * default-class="org.apache.avalon.excalibur.component.ExcaliburComponentSelector"&gt;
46  * &lt;hint shorthand="jdbc"
47  * class="org.apache.avalon.excalibur.datasource.ResourceLimitingJdbcDataSource"/&gt;
48  * &lt;/role&gt;
49  * </pre>
50  *
51  * @author <a HREF="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
52  * @version CVS $Revision: 1.3 $ $Date: 2002/01/26 16:58:26 $
53  * @since 4.1
54  */

55 public class ResourceLimitingJdbcDataSource
56     extends AbstractLogEnabled
57     implements DataSourceComponent, Disposable
58 {
59     private boolean m_configured;
60     private boolean m_disposed;
61     protected ResourceLimitingJdbcConnectionPool m_pool;
62     
63     /*---------------------------------------------------------------
64      * Constructors
65      *-------------------------------------------------------------*/

66     public ResourceLimitingJdbcDataSource() {}
67
68     /*---------------------------------------------------------------
69      * DataSourceComponent Methods
70      *-------------------------------------------------------------*/

71     /**
72      * Gets the Connection to the database
73      *
74      * @throws NoValidConnectionException when there is no valid Connection wrapper
75      * available in the classloader.
76      *
77      * @throws NoAvailableConnectionException when there are no more available
78      * Connections in the pool.
79      */

80     public Connection JavaDoc getConnection()
81         throws SQLException JavaDoc
82     {
83         if ( !m_configured ) throw new IllegalStateException JavaDoc( "Not Configured" );
84         if ( m_disposed ) throw new IllegalStateException JavaDoc( "Already Disposed" );
85         
86         Connection JavaDoc connection;
87         try
88         {
89             connection = (Connection JavaDoc)m_pool.get();
90         }
91         catch ( SQLException JavaDoc e )
92         {
93             if (getLogger().isWarnEnabled())
94             {
95                 getLogger().warn("Could not return Connection", e);
96             }
97             
98             throw e;
99         }
100         catch ( Exception JavaDoc e )
101         {
102             if ( getLogger().isWarnEnabled() )
103             {
104                 getLogger().warn( "Could not return Connection", e );
105             }
106             
107             throw new NoAvailableConnectionException( e.getMessage() );
108         }
109         
110         return connection;
111     }
112     
113     /*---------------------------------------------------------------
114      * DataSourceComponent (Configurable) Methods
115      *-------------------------------------------------------------*/

116     /**
117      * Pass the <code>Configuration</code> to the <code>Configurable</code>
118      * class. This method must always be called after the constructor
119      * and before any other method.
120      *
121      * @param configuration the class configurations.
122      */

123     public void configure(Configuration configuration) throws ConfigurationException {
124         if (m_configured) throw new IllegalStateException JavaDoc("Already Configured");
125         
126         final String JavaDoc driver = configuration.getChild( "driver" ).getValue( "" );
127         final String JavaDoc dburl = configuration.getChild( "dburl" ).getValue( null );
128         final String JavaDoc user = configuration.getChild( "user" ).getValue( null );
129         final String JavaDoc passwd = configuration.getChild( "password" ).getValue( null );
130         
131         final Configuration controller = configuration.getChild( "pool-controller" );
132         String JavaDoc keepAlive = controller.getChild( "keep-alive" ).getValue( "SELECT 1" );
133         final boolean disableKeepAlive = controller.getChild( "keep-alive" ).getAttributeAsBoolean( "disable", false );
134         
135         final int max = controller.getAttributeAsInteger( "max", 3 );
136         final boolean blocking = controller.getAttributeAsBoolean( "blocking", true );
137         final long timeout = controller.getAttributeAsLong ( "timeout", -1 );
138         final long trimInterval = controller.getAttributeAsLong ( "trim-interval", 60000 );
139         final boolean oradb = controller.getAttributeAsBoolean( "oradb", false );
140         
141         final boolean autoCommit = configuration.getChild("auto-commit").getValueAsBoolean(true);
142         // Get the JdbcConnection class. The factory will resolve one if null.
143
final String JavaDoc connectionClass = controller.getAttribute( "connection-class", null );
144
145         final int l_max;
146
147         // If driver is specified....
148
if ( ! "".equals(driver) )
149         {
150             if (getLogger().isDebugEnabled())
151             {
152                 getLogger().debug("Loading new driver: " + driver);
153             }
154
155             try
156             {
157                 Class.forName( driver, true, Thread.currentThread().getContextClassLoader() );
158             }
159             catch (ClassNotFoundException JavaDoc cnfe)
160             {
161                 if (getLogger().isWarnEnabled())
162                 {
163                     getLogger().warn( "Could not load driver: " + driver, cnfe );
164                 }
165             }
166         }
167
168         // Validate the max pool size values.
169
if( max < 1 )
170         {
171             if (getLogger().isWarnEnabled())
172             {
173                 getLogger().warn( "Maximum number of connections specified must be at least 1." );
174             }
175
176             l_max = 1;
177         }
178         else
179         {
180             l_max = max;
181         }
182
183         // If the keepAlive disable attribute was set, then set the keepAlive query to null, disabling it.
184
if (disableKeepAlive)
185         {
186             keepAlive = null;
187         }
188         
189         // If the oradb attribute was set, then override the keepAlive query.
190
// This will override any specified keepalive value even if disabled.
191
// (Deprecated, but keep this for backwards-compatability)
192
if (oradb)
193         {
194             keepAlive = "SELECT 1 FROM DUAL";
195
196             if (getLogger().isWarnEnabled())
197             {
198                 getLogger().warn("The oradb attribute is deprecated, please use the" +
199                                  "keep-alive element instead.");
200             }
201         }
202
203         
204         final JdbcConnectionFactory factory = new JdbcConnectionFactory
205             ( dburl, user, passwd, autoCommit, keepAlive, connectionClass );
206
207         factory.enableLogging( getLogger() );
208
209         try
210         {
211             m_pool = new ResourceLimitingJdbcConnectionPool
212                 (factory, l_max, true, blocking, timeout, trimInterval, autoCommit );
213             m_pool.enableLogging( getLogger() );
214         }
215         catch (Exception JavaDoc e)
216         {
217             if (getLogger().isDebugEnabled())
218             {
219                 getLogger().debug("Error configuring ResourceLimitingJdbcDataSource", e);
220             }
221
222             throw new ConfigurationException("Error configuring ResourceLimitingJdbcDataSource", e);
223         }
224         
225         m_configured = true;
226     }
227     
228     /*---------------------------------------------------------------
229      * Disposable Methods
230      *-------------------------------------------------------------*/

231     /**
232      * The dispose operation is called at the end of a components lifecycle.
233      * This method will be called after Startable.stop() method (if implemented
234      * by component). Components use this method to release and destroy any
235      * resources that the Component owns.
236      */

237     public void dispose() {
238         m_disposed = true;
239         m_pool.dispose();
240         m_pool = null;
241     }
242 }
243
244
Popular Tags