You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by dw...@apache.org on 2010/09/28 20:56:52 UTC

svn commit: r1002321 - in /openjpa/trunk: openjpa-integration/daytrader/ openjpa-integration/jmx/ openjpa-integration/slf4j/ openjpa-integration/validation/ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/ant/ openjpa-jdbc/src/main/java/org/apache/o...

Author: dwoods
Date: Tue Sep 28 18:56:51 2010
New Revision: 1002321

URL: http://svn.apache.org/viewvc?rev=1002321&view=rev
Log:
OPENJPA-1764 Automatically enable connection pooling in unmanaged environments when Commons DBCP is available

Added:
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/AutoDriverDataSource.java   (with props)
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DBCPDriverDataSource.java   (with props)
Modified:
    openjpa/trunk/openjpa-integration/daytrader/pom.xml
    openjpa/trunk/openjpa-integration/jmx/pom.xml
    openjpa/trunk/openjpa-integration/slf4j/pom.xml
    openjpa/trunk/openjpa-integration/validation/pom.xml
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/ant/ReverseMappingToolTask.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/JDBCConfigurationImpl.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DriverDataSource.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SimpleDriverDataSource.java
    openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/Configurations.java
    openjpa/trunk/openjpa-lib/src/main/resources/org/apache/openjpa/lib/jdbc/localizer.properties
    openjpa/trunk/openjpa-persistence-jdbc/pom.xml
    openjpa/trunk/openjpa-persistence-locking/pom.xml

Modified: openjpa/trunk/openjpa-integration/daytrader/pom.xml
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-integration/daytrader/pom.xml?rev=1002321&r1=1002320&r2=1002321&view=diff
==============================================================================
--- openjpa/trunk/openjpa-integration/daytrader/pom.xml (original)
+++ openjpa/trunk/openjpa-integration/daytrader/pom.xml Tue Sep 28 18:56:51 2010
@@ -203,7 +203,11 @@
                         </property>
                         <property>
                             <name>openjpa.ConnectionDriverName</name>
-                            <value>org.apache.commons.dbcp.BasicDataSource</value>
+                            <value>${connection.driver.name}</value>
+                        </property>
+                        <property>
+                            <name>openjpa.ConnectionURL</name>
+                            <value>${connection.url}</value>
                         </property>
                         <property>
                             <name>derby.stream.error.file</name>
@@ -219,7 +223,7 @@
                         </property>
                         <property>
                             <name>openjpa.ConnectionProperties</name>
-                            <value>DriverClassName=${connection.driver.name},Url=${connection.url},Username=${connection.username},Password=${connection.password},${dbcp.args}</value>
+                            <value>Username=${connection.username},Password=${connection.password},${dbcp.args}</value>
                         </property>
                     </systemProperties>
                 </configuration>

Modified: openjpa/trunk/openjpa-integration/jmx/pom.xml
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-integration/jmx/pom.xml?rev=1002321&r1=1002320&r2=1002321&view=diff
==============================================================================
--- openjpa/trunk/openjpa-integration/jmx/pom.xml (original)
+++ openjpa/trunk/openjpa-integration/jmx/pom.xml Tue Sep 28 18:56:51 2010
@@ -125,16 +125,20 @@
             <argLine>${surefire.jvm.args}</argLine>
             <systemProperties>
                <property>
-                  <name>openjpa.Log</name>
-                  <value>${openjpa.Log}</value>
+                   <name>openjpa.Log</name>
+                   <value>${openjpa.Log}</value>
                </property>
                <property>
-                  <name>openjpa.DynamicEnhancementAgent</name>
-                  <value>false</value>
+                   <name>openjpa.DynamicEnhancementAgent</name>
+                   <value>false</value>
                </property>
                <property>
-                  <name>openjpa.ConnectionDriverName</name>
-                  <value>org.apache.commons.dbcp.BasicDataSource</value>
+                   <name>openjpa.ConnectionDriverName</name>
+                   <value>${connection.driver.name}</value>
+               </property>
+               <property>
+                   <name>openjpa.ConnectionURL</name>
+                   <value>${connection.url}</value>
                </property>
                <property>
                    <name>derby.stream.error.file</name>
@@ -150,7 +154,7 @@
                </property>
                <property>
                    <name>openjpa.ConnectionProperties</name>
-                   <value>DriverClassName=${connection.driver.name},Url=${connection.url},Username=${connection.username},Password=${connection.password},${dbcp.args}</value>
+                   <value>Username=${connection.username},Password=${connection.password},${dbcp.args}</value>
                </property>
                <property>
                    <name>tests.openjpa.allowfailure</name>

Modified: openjpa/trunk/openjpa-integration/slf4j/pom.xml
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-integration/slf4j/pom.xml?rev=1002321&r1=1002320&r2=1002321&view=diff
==============================================================================
--- openjpa/trunk/openjpa-integration/slf4j/pom.xml (original)
+++ openjpa/trunk/openjpa-integration/slf4j/pom.xml Tue Sep 28 18:56:51 2010
@@ -159,7 +159,11 @@
                         </property>
                         <property>
                             <name>openjpa.ConnectionDriverName</name>
-                            <value>org.apache.commons.dbcp.BasicDataSource</value>
+                            <value>${connection.driver.name}</value>
+                        </property>
+                        <property>
+                            <name>openjpa.ConnectionURL</name>
+                            <value>${connection.url}</value>
                         </property>
                         <property>
                             <name>derby.stream.error.file</name>
@@ -175,7 +179,7 @@
                         </property>
                         <property>
                             <name>openjpa.ConnectionProperties</name>
-                            <value>DriverClassName=${connection.driver.name},Url=${connection.url},Username=${connection.username},Password=${connection.password},${dbcp.args}</value>
+                            <value>Username=${connection.username},Password=${connection.password},${dbcp.args}</value>
                         </property>
                         <property>
                             <name>tests.openjpa.allowfailure</name>

Modified: openjpa/trunk/openjpa-integration/validation/pom.xml
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-integration/validation/pom.xml?rev=1002321&r1=1002320&r2=1002321&view=diff
==============================================================================
--- openjpa/trunk/openjpa-integration/validation/pom.xml (original)
+++ openjpa/trunk/openjpa-integration/validation/pom.xml Tue Sep 28 18:56:51 2010
@@ -245,7 +245,11 @@
                         </property>
                         <property>
                             <name>openjpa.ConnectionDriverName</name>
-                            <value>org.apache.commons.dbcp.BasicDataSource</value>
+                            <value>${connection.driver.name}</value>
+                        </property>
+                        <property>
+                            <name>openjpa.ConnectionURL</name>
+                            <value>${connection.url}</value>
                         </property>
                         <property>
                             <name>derby.stream.error.file</name>
@@ -261,7 +265,7 @@
                         </property>
                         <property>
                             <name>openjpa.ConnectionProperties</name>
-                            <value>DriverClassName=${connection.driver.name},Url=${connection.url},Username=${connection.username},Password=${connection.password},${dbcp.args}</value>
+                            <value>Username=${connection.username},Password=${connection.password},${dbcp.args}</value>
                         </property>
                         <property>
                             <name>tests.openjpa.allowfailure</name>

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/ant/ReverseMappingToolTask.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/ant/ReverseMappingToolTask.java?rev=1002321&r1=1002320&r2=1002321&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/ant/ReverseMappingToolTask.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/ant/ReverseMappingToolTask.java Tue Sep 28 18:56:51 2010
@@ -277,7 +277,7 @@ public class ReverseMappingToolTask
         // create and configure customizer
         JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
         flags.customizer = (ReverseCustomizer) Configurations.
-            newInstance(customizerClass, conf, null,
+            newInstance(customizerClass, conf, (String)null,
                 AccessController.doPrivileged(
                     J2DoPrivHelper.getClassLoaderAction(
                         ReverseCustomizer.class)));

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/JDBCConfigurationImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/JDBCConfigurationImpl.java?rev=1002321&r1=1002320&r2=1002321&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/JDBCConfigurationImpl.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/JDBCConfigurationImpl.java Tue Sep 28 18:56:51 2010
@@ -242,7 +242,9 @@ public class JDBCConfigurationImpl
 
         driverDataSourcePlugin = addPlugin("jdbc.DriverDataSource", false);
         aliases = new String[]{
+            "auto", "org.apache.openjpa.jdbc.schema.AutoDriverDataSource",
             "simple", "org.apache.openjpa.jdbc.schema.SimpleDriverDataSource",
+            "dbcp", "org.apache.openjpa.jdbc.schema.DBCPDriverDataSource",
         };
         driverDataSourcePlugin.setAliases(aliases);
         driverDataSourcePlugin.setDefault(aliases[0]);

Added: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/AutoDriverDataSource.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/AutoDriverDataSource.java?rev=1002321&view=auto
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/AutoDriverDataSource.java (added)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/AutoDriverDataSource.java Tue Sep 28 18:56:51 2010
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.jdbc.schema;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import org.apache.openjpa.lib.util.ConcreteClassGenerator;
+
+/**
+ * Automatic Commons DBCP pooling or Simple non-pooling driver data source.
+ * If the commons-dbcp packages are on the class path, then they will be used,
+ * else it will fall back to non-DBCP mode.
+ */
+public abstract class AutoDriverDataSource
+    extends DBCPDriverDataSource {
+    
+    private static final Class<? extends AutoDriverDataSource> implClass;
+
+    static {
+        try {
+            implClass = ConcreteClassGenerator.makeConcrete(AutoDriverDataSource.class);
+        } catch (Exception e) {
+            throw new ExceptionInInitializerError(e);
+        }
+    }
+
+    public static AutoDriverDataSource newInstance() {
+        return ConcreteClassGenerator.newInstance(implClass);
+    }
+
+    @Override
+    public Connection getConnection(Properties props) throws SQLException {
+        // if we're using managed transactions, or user specified a DBCP driver
+        // or DBCP is not on the classpath, then use SimpleDriver
+        if (conf == null || conf.isTransactionModeManaged() || conf.isConnectionFactoryModeManaged() ||
+                !isDBCPLoaded()) {
+            return getSimpleConnection(props);
+        } else {
+            // use DBCPDriverDataSource
+            return getDBCPConnection(props);
+        }
+    }
+}

Propchange: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/AutoDriverDataSource.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DBCPDriverDataSource.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DBCPDriverDataSource.java?rev=1002321&view=auto
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DBCPDriverDataSource.java (added)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DBCPDriverDataSource.java Tue Sep 28 18:56:51 2010
@@ -0,0 +1,296 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.jdbc.schema;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Iterator;
+import java.util.Properties;
+
+import javax.sql.DataSource;
+
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.lib.conf.Configurable;
+import org.apache.openjpa.lib.conf.Configuration;
+import org.apache.openjpa.lib.conf.Configurations;
+import org.apache.openjpa.lib.util.ConcreteClassGenerator;
+
+/**
+ * Commons DBCP basic pooling driver data source.
+ * The commons-dbcp packages must be on the class path for this plugin to work,
+ * as it WILL NOT fall back to non-DBCP mode if they are missing. For automatic
+ * usage of Commons DBCP when available, use AutoDriverDataSource instead.
+ */
+public abstract class DBCPDriverDataSource
+extends SimpleDriverDataSource implements Configurable {
+
+    private static String DBCPPACKAGENAME = "org.apache.commons.dbcp";
+    private static String DBCPBASICDATASOURCENAME = "org.apache.commons.dbcp.BasicDataSource";
+    protected JDBCConfiguration conf;
+    private Class<?> _dbcpClass;
+    private Boolean _dbcpAvail;
+    private RuntimeException _dbcpEx;
+    private DataSource _ds;
+    
+    private static final Class<? extends DBCPDriverDataSource> implClass;
+
+    static {
+        try {
+            implClass = ConcreteClassGenerator.makeConcrete(DBCPDriverDataSource.class);
+        } catch (Exception e) {
+            throw new ExceptionInInitializerError(e);
+        }
+    }
+
+    public static DBCPDriverDataSource newInstance() {
+        return ConcreteClassGenerator.newInstance(implClass);
+    }
+
+    @Override
+    public Connection getConnection(Properties props) throws SQLException {
+        return getDBCPConnection(props);
+    }
+
+    protected Connection getDBCPConnection(Properties props) throws SQLException {
+        Connection con = getDBCPDataSource(props).getConnection();
+        if (con == null) {
+            throw new SQLException(_eloc.get("dbcp-ds-null",
+                DBCPBASICDATASOURCENAME, getConnectionDriverName(), getConnectionURL()).getMessage());
+        }
+        return con;
+    }
+
+    protected DataSource getDBCPDataSource(Properties props) {
+        if (isDBCPLoaded()) {
+            if (_ds == null) {
+                Properties dbcpProps = updateDBCPProperties(props);
+                _ds = (DataSource) Configurations.newInstance(DBCPBASICDATASOURCENAME, conf,
+                    dbcpProps, getClassLoader());
+                return _ds;
+            } else {
+                return _ds;
+            }
+        } else {
+            // user chose DBCP, so fail if it isn't on the classpath
+            throw _dbcpEx;
+        }
+    }
+    
+    /**
+     * This method should not throw an exception, as it is called by
+     * AutoDriverDataSource to determine if user already specified
+     * to use Commons DBCP.
+     * @return true if ConnectionDriverName contains org.apache.commons.dbcp,
+     *         otherwise false
+     */
+    protected boolean isDBCPDataSource() {
+        return (getConnectionDriverName() != null &&
+            getConnectionDriverName().toLowerCase().indexOf(DBCPPACKAGENAME) >= 0);
+    }
+    
+    /**
+     * This method should not throw an exception, as it is called by
+     * AutoDriverDataSource to determine if it should use DBCP or not
+     * based on if org.apache.commons.dbcp.BasicDataSource can be loaded.
+     * @return true if Commons DBCP was found on the classpath, otherwise false
+     */
+    protected boolean isDBCPLoaded() {
+        if (Boolean.TRUE.equals(_dbcpAvail) && (_dbcpClass != null)) {
+            return true;
+        } else if (Boolean.FALSE.equals(_dbcpAvail)) {
+            return false;
+        } else {
+            // first time checking, so try to load it
+            try {
+                _dbcpClass = Class.forName(DBCPBASICDATASOURCENAME, true, getClassLoader());
+                _dbcpAvail = Boolean.TRUE;
+                return true;
+            } catch (Exception e) {
+                _dbcpAvail = Boolean.FALSE;
+                // save exception details for later instead of throwing here
+                _dbcpEx = new RuntimeException(_eloc.get("driver-null", DBCPBASICDATASOURCENAME).getMessage(), e);
+            }
+            return _dbcpAvail.booleanValue();
+        }
+    }        
+
+    /**
+     * Normalize properties for Commons DBCP.  This should be done for every call from DataSourceFactory,
+     * as we do not have a pre-configured Driver to reuse.
+     * @param props
+     * @return updated properties
+     */
+    private Properties updateDBCPProperties(Properties props) {
+        Properties dbcpProps = mergeConnectionProperties(props);
+        
+        // only perform the following check for the first connection attempt (_driverClassName == null),
+        // as multiple connections could be requested (like from SchemaTool) and isDBCPDriver() will be true
+        if (isDBCPDataSource()) {
+            String propDriver = hasProperty(dbcpProps, "DriverClassName");
+            if (propDriver == null || propDriver.trim().isEmpty()) {
+                // if user specified DBCP for the connectionDriverName, then make sure they supplied a DriverClassName
+                throw new RuntimeException(_eloc.get("connection-property-invalid", "DriverClassName",
+                    propDriver).getMessage());
+            }
+            propDriver = hasProperty(dbcpProps, "Url");
+            if (propDriver == null || propDriver.trim().isEmpty()) {
+                // if user specified DBCP for the connectionDriverName, then make sure they supplied a Url
+                throw new RuntimeException(_eloc.get("connection-property-invalid", "Url",
+                    propDriver).getMessage());
+            }
+        } else {
+            // set Commons DBCP expected DriverClassName to the original connection driver name
+            dbcpProps.setProperty(hasKey(dbcpProps, "DriverClassName", "DriverClassName"), getConnectionDriverName());
+            // set Commons DBCP expected URL property
+            dbcpProps.setProperty(hasKey(dbcpProps, "Url", "Url"), getConnectionURL());
+        }
+        
+        // Commons DBCP requires non-Null username/password values in the connection properties
+        if (hasKey(dbcpProps, "Username") == null) {
+            if (getConnectionUserName() != null)
+                dbcpProps.setProperty("Username", getConnectionUserName());
+            else
+                dbcpProps.setProperty("Username", "");
+        }
+        // Commons DBCP requires non-Null username/password values in the connection properties
+        if (hasKey(dbcpProps, "Password") == null) {
+            if (getConnectionPassword() != null)
+                dbcpProps.setProperty("Password", getConnectionPassword());
+            else
+                dbcpProps.setProperty("Password", "");
+        }
+
+        // set some default properties for DBCP
+        if (hasKey(dbcpProps, "MaxIdle") == null) {
+            dbcpProps.setProperty("MaxIdle", "1");
+        }
+        if (hasKey(dbcpProps, "MinIdle") == null) {
+            dbcpProps.setProperty("MinIdle", "0");
+        }
+        if (hasKey(dbcpProps, "MaxActive") == null) {
+            dbcpProps.setProperty("MaxActive", "10");
+        }
+        
+        return dbcpProps;
+    }
+    
+    /**
+     * Merge the passed in properties with a copy of the existing _connectionProperties
+     * @param props
+     * @return Merged properties
+     */
+    private Properties mergeConnectionProperties(final Properties props) {
+        Properties mergedProps = new Properties();
+        mergedProps.putAll(getConnectionProperties());
+
+        // need to map "user" to "username" for Commons DBCP
+        String uid = removeProperty(mergedProps, "user");
+        if (uid != null) {
+            mergedProps.setProperty("Username", uid);
+        }
+        
+        // now, merge in any passed in properties
+        if (props != null && !props.isEmpty()) {
+            for (Iterator<Object> itr = props.keySet().iterator(); itr.hasNext();) {
+                String key = (String)itr.next();
+                String value = mergedProps.getProperty(key);
+                if (value != null) {
+                    // need to map "user" to "username" for Commons DBCP
+                    if ("user".equalsIgnoreCase(key)) {
+                        key = "Username";
+                    }
+                    // case-insensitive search for existing key
+                    String existingKey = hasKey(mergedProps, key);
+                    if (existingKey != null) {
+                        // update existing entry
+                        mergedProps.setProperty(existingKey, value);                        
+                    } else {
+                        // add property to the merged set
+                        mergedProps.setProperty(key, value);
+                    }
+                }
+            }
+        }
+        return mergedProps;
+    }
+    
+    /**
+     * Case-insensitive search of the given properties for the given key.
+     * @param props
+     * @param key
+     * @return Key name as found in properties or null if it was not found.
+     */
+    private String hasKey(Properties props, String key) {
+        return hasKey(props, key, null);
+    }
+    
+    /**
+     * Case-insensitive search of the given properties for the given key.
+     * @param props
+     * @param key
+     * @param defaultKey
+     * @return Key name as found in properties or the given defaultKey if it was not found.
+     */
+    private String hasKey(Properties props, String key, String defaultKey)
+    {
+        if (props != null && key != null) {
+            for (Iterator<Object> itr = props.keySet().iterator(); itr.hasNext();) {
+                String entry = (String)itr.next();
+                if (key.equalsIgnoreCase(entry))
+                    return entry;
+            }
+        }
+        return defaultKey;
+    }
+    
+    private String hasProperty(Properties props, String key) {
+        if (props != null && key != null) {
+            String entry = hasKey(props, key);
+            if (entry != null)
+                return props.getProperty(entry);
+        }
+        return null;
+
+    }
+    
+    private String removeProperty(Properties props, String key) {
+        if (props != null && key != null) {
+            String entry = hasKey(props, key);
+            if (entry != null)
+                return (String)props.remove(entry);
+        }
+        return null;
+    }
+    
+    // Configurable interface methods
+    public void setConfiguration(Configuration conf) {
+        if (conf instanceof JDBCConfiguration)
+            this.conf = (JDBCConfiguration)conf;
+    }
+
+    public void startConfiguration() {
+        // no-op
+    }
+
+    public void endConfiguration() {
+        // no-op
+    }
+
+}
+

Propchange: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DBCPDriverDataSource.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DriverDataSource.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DriverDataSource.java?rev=1002321&r1=1002320&r2=1002321&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DriverDataSource.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DriverDataSource.java Tue Sep 28 18:56:51 2010
@@ -101,6 +101,7 @@ public interface DriverDataSource
     /**
      * Provide any built-in decorators; may be null.
      */
+    @SuppressWarnings("unchecked")
     public List createConnectionDecorators();
 
     /**

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SimpleDriverDataSource.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SimpleDriverDataSource.java?rev=1002321&r1=1002320&r2=1002321&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SimpleDriverDataSource.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SimpleDriverDataSource.java Tue Sep 28 18:56:51 2010
@@ -19,7 +19,6 @@
 package org.apache.openjpa.jdbc.schema;
 
 import java.io.PrintWriter;
-import java.lang.reflect.Constructor;
 import java.security.AccessController;
 import java.security.PrivilegedActionException;
 import java.sql.Connection;
@@ -29,8 +28,6 @@ import java.sql.SQLException;
 import java.util.List;
 import java.util.Properties;
 
-import javax.sql.DataSource;
-
 import org.apache.openjpa.jdbc.sql.DBDictionary;
 import org.apache.openjpa.lib.jdbc.DelegatingDataSource;
 import org.apache.openjpa.lib.util.ConcreteClassGenerator;
@@ -91,10 +88,12 @@ public abstract class SimpleDriverDataSo
         return getConnection(props);
     }
 
-    public Connection getConnection(Properties props)
-        throws SQLException {
-    	Connection con = getDriver().connect(_connectionURL, props == null? new Properties() : props);
-    	
+    public Connection getConnection(Properties props) throws SQLException {
+        return getSimpleConnection(props);
+    }
+    
+    protected Connection getSimpleConnection(Properties props) throws SQLException {
+    	Connection con = getSimpleDriver().connect(_connectionURL, props == null? new Properties() : props);
     	if (con == null) {
             throw new SQLException(_eloc.get("poolds-null",
                     _connectionDriverName, _connectionURL).getMessage());
@@ -139,6 +138,11 @@ public abstract class SimpleDriverDataSo
         _connectionPassword = connectionPassword;
     }
 
+    // Only allow sub-classes to retrieve the password
+    protected String getConnectionPassword() {
+        return _connectionPassword;
+    }
+
     public void setConnectionProperties(Properties props) {
         _connectionProperties = props;
     }
@@ -155,6 +159,7 @@ public abstract class SimpleDriverDataSo
         return _connectionFactoryProperties;
     }
 
+    @SuppressWarnings("unchecked")
     public List createConnectionDecorators() {
         return null;
     }
@@ -175,7 +180,7 @@ public abstract class SimpleDriverDataSo
         return _connectionDriverName;
     }
 
-    private Driver getDriver() {
+    protected Driver getSimpleDriver() {
         if (_driver != null)
             return _driver;
 
@@ -198,7 +203,7 @@ public abstract class SimpleDriverDataSo
         }
 
         try {
-            Class c = Class.forName(_connectionDriverName,
+            Class<?> c = Class.forName(_connectionDriverName,
                 true, _classLoader);
             _driver = (Driver) AccessController.doPrivileged(
                 J2DoPrivHelper.newInstanceAction(c));
@@ -214,10 +219,12 @@ public abstract class SimpleDriverDataSo
     
 
     // java.sql.Wrapper implementation (JDBC 4)
+    @SuppressWarnings("unchecked")
     public boolean isWrapperFor(Class iface) {
         return iface.isAssignableFrom(SimpleDriverDataSource.class);
     }
 
+    @SuppressWarnings("unchecked")
     public Object unwrap(Class iface) {
         if (isWrapperFor(iface))
             return this;

Modified: openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/Configurations.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/Configurations.java?rev=1002321&r1=1002320&r2=1002321&view=diff
==============================================================================
--- openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/Configurations.java (original)
+++ openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/Configurations.java Tue Sep 28 18:56:51 2010
@@ -163,7 +163,7 @@ public class Configurations {
 
     /**
      * Create and configure an instance with the given class name and
-     * properties.
+     * properties as a String.
      */
     public static Object newInstance(String clsName, Configuration conf,
         String props, ClassLoader loader) {
@@ -173,6 +173,17 @@ public class Configurations {
     }
 
     /**
+     * Create and configure an instance with the given class name and
+     * properties.
+     */
+    public static Object newInstance(String clsName, Configuration conf,
+        Properties props, ClassLoader loader) {
+        Object obj = newInstance(clsName, null, conf, loader, true);
+        configureInstance(obj, conf, props);
+        return obj;
+    }
+
+    /**
      * Helper method used by members of this package to instantiate plugin
      * values.
      */

Modified: openjpa/trunk/openjpa-lib/src/main/resources/org/apache/openjpa/lib/jdbc/localizer.properties
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-lib/src/main/resources/org/apache/openjpa/lib/jdbc/localizer.properties?rev=1002321&r1=1002320&r2=1002321&view=diff
==============================================================================
--- openjpa/trunk/openjpa-lib/src/main/resources/org/apache/openjpa/lib/jdbc/localizer.properties (original)
+++ openjpa/trunk/openjpa-lib/src/main/resources/org/apache/openjpa/lib/jdbc/localizer.properties Tue Sep 28 18:56:51 2010
@@ -39,6 +39,9 @@ not-active: Attempt to operate on connec
 	returned to the connection pool.
 poolds-null: A connection could not be obtained for driver class "{0}" \
 	and URL "{1}".  You may have specified an invalid URL.
+dbcp-ds-null: A connection could not be obtained from pool "{0}" with \
+        driver class "{1}" and URL "{2}". You may have specified an invalid URL.
+driver-null: The connection driver class "{0}" could not be loaded.
 get-conn-exception:	An unexpected exception of type "{0}" occurred while \
 	getting a connection. This exception will be re-thrown as a SQLException.
 conn-pool-exhausted: The maximum number of connections ({0}) for the \
@@ -93,6 +96,8 @@ connection-url-desc:  The JDBC URL for t
 connection-properties-desc:  Properties applied to the JDBC driver or \
 	datasource.
 connection-driver-name-desc:  The JDBC driver.
+connection-property-invalid:  The supplied connection property "{0}" contains \
+        an invalid value of "{1}".
 login-timeout-desc:  The maximum number of milliseconds to block for database \
 	login.
 close-pool: Shutting down connection pool.

Modified: openjpa/trunk/openjpa-persistence-jdbc/pom.xml
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/pom.xml?rev=1002321&r1=1002320&r2=1002321&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/pom.xml (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/pom.xml Tue Sep 28 18:56:51 2010
@@ -65,7 +65,11 @@
                         </property>
                         <property>
                             <name>openjpa.ConnectionDriverName</name>
-                            <value>org.apache.commons.dbcp.BasicDataSource</value>
+                            <value>${connection.driver.name}</value>
+                        </property>
+                        <property>
+                            <name>openjpa.ConnectionURL</name>
+                            <value>${connection.url}</value>
                         </property>
                         <property>
                             <name>derby.stream.error.file</name>
@@ -73,7 +77,7 @@
                         </property>
                         <property>
                             <name>openjpa.ConnectionProperties</name>
-                            <value>DriverClassName=${connection.driver.name},Url=${connection.url},Username=${connection.username},Password=${connection.password},${dbcp.args}</value>
+                            <value>Username=${connection.username},Password=${connection.password},${dbcp.args}</value>
                         </property>
                         <property>
                             <name>tests.openjpa.allowfailure</name>
@@ -1019,7 +1023,11 @@
                         </property>
                         <property>
                             <name>openjpa.ConnectionDriverName</name>
-                            <value>org.apache.commons.dbcp.BasicDataSource</value>
+                            <value>${connection.driver.name}</value>
+                        </property>
+                        <property>
+                            <name>openjpa.ConnectionURL</name>
+                            <value>${connection.url}</value>
                         </property>
                         <property>
                             <name>derby.stream.error.file</name>
@@ -1043,7 +1051,7 @@
                         </property>
                         <property>
                             <name>openjpa.ConnectionProperties</name>
-                            <value>DriverClassName=${connection.driver.name},Url=${connection.url},Username=${connection.username},Password=${connection.password},${dbcp.args}</value>
+                            <value>Username=${connection.username},Password=${connection.password},${dbcp.args}</value>
                         </property>
                         <property>
                             <name>tests.openjpa.allowfailure</name>

Modified: openjpa/trunk/openjpa-persistence-locking/pom.xml
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-locking/pom.xml?rev=1002321&r1=1002320&r2=1002321&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-locking/pom.xml (original)
+++ openjpa/trunk/openjpa-persistence-locking/pom.xml Tue Sep 28 18:56:51 2010
@@ -75,7 +75,11 @@
                                 </property>
                                 <property>
                                     <name>openjpa.ConnectionDriverName</name>
-                                    <value>org.apache.commons.dbcp.BasicDataSource</value>
+                                    <value>${connection.driver.name}</value>
+                                </property>
+                                <property>
+                                    <name>openjpa.ConnectionURL</name>
+                                    <value>${connection.url}</value>
                                 </property>
                                 <property>
                                     <name>derby.stream.error.file</name>
@@ -83,7 +87,7 @@
                                 </property>
                                 <property>
                                     <name>openjpa.ConnectionProperties</name>
-                                    <value>DriverClassName=${connection.driver.name},Url=${connection.url},Username=${connection.username},Password=${connection.password},${dbcp.args}</value>
+                                    <value>Username=${connection.username},Password=${connection.password},${dbcp.args}</value>
                                 </property>
                                 <property>
                                     <name>tests.openjpa.allowfailure</name>
@@ -799,7 +803,11 @@
                         </property>
                         <property>
                             <name>openjpa.ConnectionDriverName</name>
-                            <value>org.apache.commons.dbcp.BasicDataSource</value>
+                            <value>${connection.driver.name}</value>
+                        </property>
+                        <property>
+                            <name>openjpa.ConnectionURL</name>
+                            <value>${connection.url}</value>
                         </property>
                         <property>
                             <name>derby.stream.error.file</name>
@@ -815,7 +823,7 @@
                         </property>
                         <property>
                             <name>openjpa.ConnectionProperties</name>
-                            <value>DriverClassName=${connection.driver.name},Url=${connection.url},Username=${connection.username},Password=${connection.password},${dbcp.args}</value>
+                            <value>Username=${connection.username},Password=${connection.password},${dbcp.args}</value>
                         </property>
                         <property>
                             <name>tests.openjpa.allowfailure</name>