View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.jetspeed.components.datasource;
18  
19  import java.sql.Connection;
20  import java.sql.DriverManager;
21  
22  import javax.sql.DataSource;
23  
24  import org.apache.commons.dbcp.ConnectionFactory;
25  import org.apache.commons.dbcp.DriverManagerConnectionFactory;
26  import org.apache.commons.dbcp.PoolableConnectionFactory;
27  import org.apache.commons.dbcp.PoolingDataSource;
28  import org.apache.commons.logging.Log;
29  import org.apache.commons.logging.LogFactory;
30  import org.apache.commons.pool.ObjectPool;
31  import org.apache.commons.pool.impl.GenericObjectPool;
32  
33  /***
34   * <p>
35   * DBCPDatasourceComponent
36   * </p>
37   * 
38   * 
39   * @
40   * @author <a href="mailto:weaver@apache.org">Scott T. Weaver</a>
41   * @version $ $
42   *
43   */
44  public class DBCPDatasourceComponent implements DatasourceComponent
45  {
46  
47      private static final Log log = LogFactory.getLog(DBCPDatasourceComponent.class);
48  
49      protected PoolingDataSource dataSource;
50      //protected DataSource dataSource;
51      
52      private String user;
53      
54      private String password;
55      
56      private String driverName;
57      
58      private String connectURI;    
59      
60      private int maxActive;
61      
62      private int maxWait;
63      
64      private byte whenExhausted;
65      
66      private PoolableConnectionFactory dsConnectionFactory;
67      /***
68       * 
69       * Creates a simple commons DBCP connection pool using the following
70       * parameters.
71       * <p>
72       * If you need to bind the datasource of this component to 
73       * JNDI please @see org.apache.jetspeed.components.jndi.JNDIComponent
74       * </p>
75       * 
76       * @param user User name that will be used to connect to the DB
77       * @param password Password that will be used to connect to the DB
78       * @param driverName Fully qualified driver to be used by the connection pool
79       * @param connectURI Fully qualified URI to the DB.
80       * @param maxActive Maximum active connection
81       * @param maxWait if <code>whenExhausted</code> is set to GenericObjectPool.WHEN_EXHAUSTED_BLOCK
82       * the length of time to block while waiting for a connection to become 
83       * available.
84       * @param whenExhausted GenericObjectPool.WHEN_EXHAUSTED_BLOCK, GenericObjectPool.WHEN_EXHAUSTED_GROW or
85       * GenericObjectPool.WHEN_EXHAUSTED_FAIL. @see org.apache.commons.pooling.GenericObjectPool
86       * for more information on these settings
87       * @param autoCommit Whether or not this datasource will autocommit
88       * @throws ClassNotFoundException If the <code>driverName</code> could not be
89       * located within any classloaders.
90       */
91      public DBCPDatasourceComponent(
92          String user,
93          String password,
94          String driverName,
95          String connectURI,
96          int maxActive,
97          int maxWait,
98          byte whenExhausted,
99          boolean autoCommit)
100         
101     {
102 
103         log.info("Setting up data source pooling for " + driverName);
104 
105         log.info("Max active connnections set to: " + maxActive);
106 
107         log.info("Pool is set to \"" + whenExhausted + "\" when all connections are exhausted.");
108 		
109 		this.user = user;
110 		this.password = password;
111 		this.driverName = driverName;
112 		this.connectURI = connectURI;
113 		this.maxActive = maxActive;
114 		this.maxWait = maxWait;
115     }
116 
117     /***
118      * 
119      * <p>
120      * getDatasource
121      * </p>
122      * 
123      * <p>
124      *   returns the datasource created by this component
125      * </p>
126      * @return
127      *
128      */
129     public DataSource getDatasource()
130     {
131         return dataSource;
132     }
133 
134     /*** 
135      * <p>
136      * start
137      * </p>
138      * 
139      * @see org.picocontainer.Startable#start()
140      * 
141      */
142     public void start()
143     {
144 
145         try
146         {
147             log.info("Attempting to start DBCPCDatasourceComponent.");            
148             Class.forName(driverName);
149             
150             // Validate the connection before we go any further
151             try
152             {
153                 Connection conn = DriverManager.getConnection(connectURI, user, password);
154                 conn.close();
155             }
156             catch(Exception e)
157             {
158                 log.error("Unable to obtain a connection database via URI: "+connectURI, e);
159                 throw e;
160             }
161             
162             ObjectPool connectionPool = new GenericObjectPool(null, maxActive, whenExhausted, maxWait);
163             
164             ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(connectURI, user, password);
165             
166             dsConnectionFactory = new PoolableConnectionFactory(connectionFactory, connectionPool, null, null, false, true);
167             
168             dataSource = new PoolingDataSource(connectionPool);            
169             
170             log.info("DBCPCDatasourceComponent successfuly started!");
171         }
172         catch (Throwable e)
173         {
174             
175             String msg = "Unable to start DBCPCDatasourceComponent: "+e.toString();
176             log.error(msg, e);
177             throw new IllegalStateException(msg);
178         }
179     }
180 
181     /*** 
182      * <p>
183      * stop
184      * </p>
185      * 
186      * @see org.picocontainer.Startable#stop()
187      * 
188      */
189     public void stop()
190     {
191         try
192         {
193             dsConnectionFactory.getPool().close();
194         }
195         catch (Exception e)
196         {
197             IllegalStateException ise =
198                 new IllegalStateException("Unable to sfaely shutdown the DBCPConnection pool: " + e.toString());
199             ise.initCause(e);
200         }
201     }
202 
203 }