You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2009/05/26 17:16:36 UTC
svn commit: r778741 - in /jackrabbit/sandbox/JCR-1456/jackrabbit-core:
pom.xml
src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/ConnectionFactory.java
Author: jukka
Date: Tue May 26 15:16:35 2009
New Revision: 778741
URL: http://svn.apache.org/viewvc?rev=778741&view=rev
Log:
JCR-1456: Database connection pooling
Applied proposed patch that introduces Commons DBCP and turns all configured
databse connections into (pooled) DataSources.
Obvious TODO: these DataSources will also need to be managed...
Modified:
jackrabbit/sandbox/JCR-1456/jackrabbit-core/pom.xml
jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/ConnectionFactory.java
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/pom.xml?rev=778741&r1=778740&r2=778741&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/pom.xml (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/pom.xml Tue May 26 15:16:35 2009
@@ -154,6 +154,11 @@
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
+ <groupId>commons-dbcp</groupId>
+ <artifactId>commons-dbcp</artifactId>
+ <version>1.2.2</version>
+ </dependency>
+ <dependency>
<groupId>javax.jcr</groupId>
<artifactId>jcr</artifactId>
</dependency>
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/ConnectionFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/ConnectionFactory.java?rev=778741&r1=778740&r2=778741&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/ConnectionFactory.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/ConnectionFactory.java Tue May 26 15:16:35 2009
@@ -17,7 +17,6 @@
package org.apache.jackrabbit.core.persistence.bundle.util;
import java.sql.Connection;
-import java.sql.DriverManager;
import java.sql.SQLException;
import javax.jcr.RepositoryException;
@@ -25,6 +24,8 @@
import javax.naming.NamingException;
import javax.sql.DataSource;
+import org.apache.commons.dbcp.BasicDataSource;
+
/**
* A factory for new database connections.
* Supported are regular JDBC drivers, as well as
@@ -53,43 +54,115 @@
* @throws RepositoryException if the driver could not be loaded
* @throws SQLException if the connection could not be established
*/
- public static Connection getConnection(String driver, String url,
- String user, String password) throws RepositoryException,
- SQLException {
- if (driver != null && driver.length() > 0) {
+ @SuppressWarnings("unchecked")
+ public static Connection getConnection(
+ String driver, String url, String user, String password)
+ throws RepositoryException, SQLException {
+ DataSource database;
+
+ Class<?> driverClass = getDriverClass(driver);
+ if (driverClass != null
+ && Context.class.isAssignableFrom(driverClass)) {
+ database = getJndiDataSource((Class<Context>) driverClass, url);
+ } else {
+ database = getDriverDataSource(driverClass, url);
+ }
+
+ if (user == null && password == null) {
+ return database.getConnection();
+ } else {
+ return database.getConnection(user, password);
+ }
+ }
+
+ /**
+ * Loads and returns the given JDBC driver (or JNDI context) class.
+ * Returns <code>null</code> if a class name is not given.
+ *
+ * @param driver driver class name
+ * @return driver class, or <code>null</code>
+ * @throws RepositoryException if the class can not be loaded
+ */
+ private static Class<?> getDriverClass(String driver)
+ throws RepositoryException {
+ try {
+ if (driver != null && driver.length() > 0) {
+ return Class.forName(driver);
+ } else {
+ return null;
+ }
+ } catch (ClassNotFoundException e) {
+ throw new RepositoryException(
+ "Could not load JDBC driver class " + driver, e);
+ }
+ }
+
+ /**
+ * Returns the JDBC {@link DataSource} bound to the given name in
+ * the JNDI {@link Context} identified by the given class.
+ *
+ * @param contextClass class that is instantiated to get the JNDI context
+ * @param name name of the DataSource within the JNDI context
+ * @return the DataSource bound in JNDI
+ * @throws RepositoryException if the JNDI context can not be accessed,
+ * or if the named DataSource is not found
+ */
+ private static DataSource getJndiDataSource(
+ Class<Context> contextClass, String name)
+ throws RepositoryException {
+ try {
+ Object object = contextClass.newInstance().lookup(name);
+ if (object instanceof DataSource) {
+ return (DataSource) object;
+ } else {
+ throw new RepositoryException(
+ "Object " + object + " with JNDI name "
+ + name + " is not a JDBC DataSource");
+ }
+ } catch (InstantiationException e) {
+ throw new RepositoryException(
+ "Invalid JNDI context: " + contextClass.getName(), e);
+ } catch (IllegalAccessException e) {
+ throw new RepositoryException(
+ "Invalid JNDI context: " + contextClass.getName(), e);
+ } catch (NamingException e) {
+ throw new RepositoryException(
+ "JNDI name not found: " + name, e);
+ }
+ }
+
+ /**
+ * Creates and returns a pooling JDBC {@link DataSource} for accessing
+ * the database identified by the given driver class and JDBC
+ * connection URL. The driver class can be <code>null</code> if
+ * a specific driver has not been configured.
+ *
+ * @param driverClass the JDBC driver class, or <code>null</code>
+ * @param url the JDBC connection URL
+ * @return pooling DataSource for accessing the specified database
+ */
+ private static DataSource getDriverDataSource(
+ Class<?> driverClass, String url) {
+ BasicDataSource database = new BasicDataSource();
+
+ if (driverClass != null) {
try {
- Class< ? > d = Class.forName(driver);
- if (javax.naming.Context.class.isAssignableFrom(d)) {
- // JNDI context
- Context context = (Context) d.newInstance();
- DataSource ds = (DataSource) context.lookup(url);
- if (user == null && password == null) {
- return ds.getConnection();
- } else {
- return ds.getConnection(user, password);
- }
- } else {
- try {
- // Workaround for Apache Derby:
- // The JDBC specification recommends the Class.forName method without the .newInstance() method call,
- // but it is required after a Derby 'shutdown'.
- d.newInstance();
- } catch (Throwable e) {
- // Ignore exceptions
- // There's no requirement that a JDBC driver class has a public default constructor
- }
- }
- } catch (ClassNotFoundException e) {
- throw new RepositoryException("Could not load class " + driver, e);
- } catch (InstantiationException e) {
- throw new RepositoryException("Could not instantiate context " + driver, e);
- } catch (IllegalAccessException e) {
- throw new RepositoryException("Could not instantiate context " + driver, e);
- } catch (NamingException e) {
- throw new RepositoryException("Naming exception using " + driver + " url: " + url, e);
+ // Workaround for Apache Derby:
+ // The JDBC specification recommends the Class.forName
+ // method without the .newInstance() method call,
+ // but it is required after a Derby 'shutdown'
+ driverClass.newInstance();
+ } catch (Throwable e) {
+ // Ignore exceptions as there's no requirement for
+ // a JDBC driver class to have a public default constructor
}
+
+ database.setDriverClassName(driverClass.getName());
}
- return DriverManager.getConnection(url, user, password);
+
+ database.setUrl(url);
+
+ return database;
}
}