mirror of https://github.com/apache/openjpa.git
OPENJPA-1764 Automatically enable connection pooling in unmanaged environments when Commons DBCP is available
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@1002321 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
9f392edc9d
commit
ed85f020fd
|
@ -203,7 +203,11 @@
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>openjpa.ConnectionDriverName</name>
|
<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>
|
||||||
<property>
|
<property>
|
||||||
<name>derby.stream.error.file</name>
|
<name>derby.stream.error.file</name>
|
||||||
|
@ -219,7 +223,7 @@
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>openjpa.ConnectionProperties</name>
|
<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>
|
||||||
</systemProperties>
|
</systemProperties>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
|
@ -125,16 +125,20 @@
|
||||||
<argLine>${surefire.jvm.args}</argLine>
|
<argLine>${surefire.jvm.args}</argLine>
|
||||||
<systemProperties>
|
<systemProperties>
|
||||||
<property>
|
<property>
|
||||||
<name>openjpa.Log</name>
|
<name>openjpa.Log</name>
|
||||||
<value>${openjpa.Log}</value>
|
<value>${openjpa.Log}</value>
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>openjpa.DynamicEnhancementAgent</name>
|
<name>openjpa.DynamicEnhancementAgent</name>
|
||||||
<value>false</value>
|
<value>false</value>
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>openjpa.ConnectionDriverName</name>
|
<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>
|
||||||
<property>
|
<property>
|
||||||
<name>derby.stream.error.file</name>
|
<name>derby.stream.error.file</name>
|
||||||
|
@ -150,7 +154,7 @@
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>openjpa.ConnectionProperties</name>
|
<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>
|
||||||
<property>
|
<property>
|
||||||
<name>tests.openjpa.allowfailure</name>
|
<name>tests.openjpa.allowfailure</name>
|
||||||
|
|
|
@ -159,7 +159,11 @@
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>openjpa.ConnectionDriverName</name>
|
<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>
|
||||||
<property>
|
<property>
|
||||||
<name>derby.stream.error.file</name>
|
<name>derby.stream.error.file</name>
|
||||||
|
@ -175,7 +179,7 @@
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>openjpa.ConnectionProperties</name>
|
<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>
|
||||||
<property>
|
<property>
|
||||||
<name>tests.openjpa.allowfailure</name>
|
<name>tests.openjpa.allowfailure</name>
|
||||||
|
|
|
@ -245,7 +245,11 @@
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>openjpa.ConnectionDriverName</name>
|
<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>
|
||||||
<property>
|
<property>
|
||||||
<name>derby.stream.error.file</name>
|
<name>derby.stream.error.file</name>
|
||||||
|
@ -261,7 +265,7 @@
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>openjpa.ConnectionProperties</name>
|
<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>
|
||||||
<property>
|
<property>
|
||||||
<name>tests.openjpa.allowfailure</name>
|
<name>tests.openjpa.allowfailure</name>
|
||||||
|
|
|
@ -277,7 +277,7 @@ public class ReverseMappingToolTask
|
||||||
// create and configure customizer
|
// create and configure customizer
|
||||||
JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
|
JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
|
||||||
flags.customizer = (ReverseCustomizer) Configurations.
|
flags.customizer = (ReverseCustomizer) Configurations.
|
||||||
newInstance(customizerClass, conf, null,
|
newInstance(customizerClass, conf, (String)null,
|
||||||
AccessController.doPrivileged(
|
AccessController.doPrivileged(
|
||||||
J2DoPrivHelper.getClassLoaderAction(
|
J2DoPrivHelper.getClassLoaderAction(
|
||||||
ReverseCustomizer.class)));
|
ReverseCustomizer.class)));
|
||||||
|
|
|
@ -242,7 +242,9 @@ public class JDBCConfigurationImpl
|
||||||
|
|
||||||
driverDataSourcePlugin = addPlugin("jdbc.DriverDataSource", false);
|
driverDataSourcePlugin = addPlugin("jdbc.DriverDataSource", false);
|
||||||
aliases = new String[]{
|
aliases = new String[]{
|
||||||
|
"auto", "org.apache.openjpa.jdbc.schema.AutoDriverDataSource",
|
||||||
"simple", "org.apache.openjpa.jdbc.schema.SimpleDriverDataSource",
|
"simple", "org.apache.openjpa.jdbc.schema.SimpleDriverDataSource",
|
||||||
|
"dbcp", "org.apache.openjpa.jdbc.schema.DBCPDriverDataSource",
|
||||||
};
|
};
|
||||||
driverDataSourcePlugin.setAliases(aliases);
|
driverDataSourcePlugin.setAliases(aliases);
|
||||||
driverDataSourcePlugin.setDefault(aliases[0]);
|
driverDataSourcePlugin.setDefault(aliases[0]);
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -101,6 +101,7 @@ public interface DriverDataSource
|
||||||
/**
|
/**
|
||||||
* Provide any built-in decorators; may be null.
|
* Provide any built-in decorators; may be null.
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public List createConnectionDecorators();
|
public List createConnectionDecorators();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
package org.apache.openjpa.jdbc.schema;
|
package org.apache.openjpa.jdbc.schema;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
import java.security.PrivilegedActionException;
|
import java.security.PrivilegedActionException;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
|
@ -29,8 +28,6 @@ import java.sql.SQLException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
|
||||||
|
|
||||||
import org.apache.openjpa.jdbc.sql.DBDictionary;
|
import org.apache.openjpa.jdbc.sql.DBDictionary;
|
||||||
import org.apache.openjpa.lib.jdbc.DelegatingDataSource;
|
import org.apache.openjpa.lib.jdbc.DelegatingDataSource;
|
||||||
import org.apache.openjpa.lib.util.ConcreteClassGenerator;
|
import org.apache.openjpa.lib.util.ConcreteClassGenerator;
|
||||||
|
@ -91,10 +88,12 @@ public abstract class SimpleDriverDataSource
|
||||||
return getConnection(props);
|
return getConnection(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Connection getConnection(Properties props)
|
public Connection getConnection(Properties props) throws SQLException {
|
||||||
throws SQLException {
|
return getSimpleConnection(props);
|
||||||
Connection con = getDriver().connect(_connectionURL, props == null? new Properties() : props);
|
}
|
||||||
|
|
||||||
|
protected Connection getSimpleConnection(Properties props) throws SQLException {
|
||||||
|
Connection con = getSimpleDriver().connect(_connectionURL, props == null? new Properties() : props);
|
||||||
if (con == null) {
|
if (con == null) {
|
||||||
throw new SQLException(_eloc.get("poolds-null",
|
throw new SQLException(_eloc.get("poolds-null",
|
||||||
_connectionDriverName, _connectionURL).getMessage());
|
_connectionDriverName, _connectionURL).getMessage());
|
||||||
|
@ -139,6 +138,11 @@ public abstract class SimpleDriverDataSource
|
||||||
_connectionPassword = connectionPassword;
|
_connectionPassword = connectionPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only allow sub-classes to retrieve the password
|
||||||
|
protected String getConnectionPassword() {
|
||||||
|
return _connectionPassword;
|
||||||
|
}
|
||||||
|
|
||||||
public void setConnectionProperties(Properties props) {
|
public void setConnectionProperties(Properties props) {
|
||||||
_connectionProperties = props;
|
_connectionProperties = props;
|
||||||
}
|
}
|
||||||
|
@ -155,6 +159,7 @@ public abstract class SimpleDriverDataSource
|
||||||
return _connectionFactoryProperties;
|
return _connectionFactoryProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public List createConnectionDecorators() {
|
public List createConnectionDecorators() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -175,7 +180,7 @@ public abstract class SimpleDriverDataSource
|
||||||
return _connectionDriverName;
|
return _connectionDriverName;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Driver getDriver() {
|
protected Driver getSimpleDriver() {
|
||||||
if (_driver != null)
|
if (_driver != null)
|
||||||
return _driver;
|
return _driver;
|
||||||
|
|
||||||
|
@ -198,7 +203,7 @@ public abstract class SimpleDriverDataSource
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Class c = Class.forName(_connectionDriverName,
|
Class<?> c = Class.forName(_connectionDriverName,
|
||||||
true, _classLoader);
|
true, _classLoader);
|
||||||
_driver = (Driver) AccessController.doPrivileged(
|
_driver = (Driver) AccessController.doPrivileged(
|
||||||
J2DoPrivHelper.newInstanceAction(c));
|
J2DoPrivHelper.newInstanceAction(c));
|
||||||
|
@ -214,10 +219,12 @@ public abstract class SimpleDriverDataSource
|
||||||
|
|
||||||
|
|
||||||
// java.sql.Wrapper implementation (JDBC 4)
|
// java.sql.Wrapper implementation (JDBC 4)
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public boolean isWrapperFor(Class iface) {
|
public boolean isWrapperFor(Class iface) {
|
||||||
return iface.isAssignableFrom(SimpleDriverDataSource.class);
|
return iface.isAssignableFrom(SimpleDriverDataSource.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public Object unwrap(Class iface) {
|
public Object unwrap(Class iface) {
|
||||||
if (isWrapperFor(iface))
|
if (isWrapperFor(iface))
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -163,7 +163,7 @@ public class Configurations {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create and configure an instance with the given class name and
|
* Create and configure an instance with the given class name and
|
||||||
* properties.
|
* properties as a String.
|
||||||
*/
|
*/
|
||||||
public static Object newInstance(String clsName, Configuration conf,
|
public static Object newInstance(String clsName, Configuration conf,
|
||||||
String props, ClassLoader loader) {
|
String props, ClassLoader loader) {
|
||||||
|
@ -172,6 +172,17 @@ public class Configurations {
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
* Helper method used by members of this package to instantiate plugin
|
||||||
* values.
|
* values.
|
||||||
|
|
|
@ -39,6 +39,9 @@ not-active: Attempt to operate on connection "{0}" that has already been \
|
||||||
returned to the connection pool.
|
returned to the connection pool.
|
||||||
poolds-null: A connection could not be obtained for driver class "{0}" \
|
poolds-null: A connection could not be obtained for driver class "{0}" \
|
||||||
and URL "{1}". You may have specified an invalid URL.
|
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 \
|
get-conn-exception: An unexpected exception of type "{0}" occurred while \
|
||||||
getting a connection. This exception will be re-thrown as a SQLException.
|
getting a connection. This exception will be re-thrown as a SQLException.
|
||||||
conn-pool-exhausted: The maximum number of connections ({0}) for the \
|
conn-pool-exhausted: The maximum number of connections ({0}) for the \
|
||||||
|
@ -93,6 +96,8 @@ connection-url-desc: The JDBC URL for the database.
|
||||||
connection-properties-desc: Properties applied to the JDBC driver or \
|
connection-properties-desc: Properties applied to the JDBC driver or \
|
||||||
datasource.
|
datasource.
|
||||||
connection-driver-name-desc: The JDBC driver.
|
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-timeout-desc: The maximum number of milliseconds to block for database \
|
||||||
login.
|
login.
|
||||||
close-pool: Shutting down connection pool.
|
close-pool: Shutting down connection pool.
|
||||||
|
|
|
@ -65,7 +65,11 @@
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>openjpa.ConnectionDriverName</name>
|
<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>
|
||||||
<property>
|
<property>
|
||||||
<name>derby.stream.error.file</name>
|
<name>derby.stream.error.file</name>
|
||||||
|
@ -73,7 +77,7 @@
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>openjpa.ConnectionProperties</name>
|
<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>
|
||||||
<property>
|
<property>
|
||||||
<name>tests.openjpa.allowfailure</name>
|
<name>tests.openjpa.allowfailure</name>
|
||||||
|
@ -1019,7 +1023,11 @@
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>openjpa.ConnectionDriverName</name>
|
<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>
|
||||||
<property>
|
<property>
|
||||||
<name>derby.stream.error.file</name>
|
<name>derby.stream.error.file</name>
|
||||||
|
@ -1043,7 +1051,7 @@
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>openjpa.ConnectionProperties</name>
|
<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>
|
||||||
<property>
|
<property>
|
||||||
<name>tests.openjpa.allowfailure</name>
|
<name>tests.openjpa.allowfailure</name>
|
||||||
|
|
|
@ -75,7 +75,11 @@
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>openjpa.ConnectionDriverName</name>
|
<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>
|
||||||
<property>
|
<property>
|
||||||
<name>derby.stream.error.file</name>
|
<name>derby.stream.error.file</name>
|
||||||
|
@ -83,7 +87,7 @@
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>openjpa.ConnectionProperties</name>
|
<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>
|
||||||
<property>
|
<property>
|
||||||
<name>tests.openjpa.allowfailure</name>
|
<name>tests.openjpa.allowfailure</name>
|
||||||
|
@ -799,7 +803,11 @@
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>openjpa.ConnectionDriverName</name>
|
<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>
|
||||||
<property>
|
<property>
|
||||||
<name>derby.stream.error.file</name>
|
<name>derby.stream.error.file</name>
|
||||||
|
@ -815,7 +823,7 @@
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>openjpa.ConnectionProperties</name>
|
<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>
|
||||||
<property>
|
<property>
|
||||||
<name>tests.openjpa.allowfailure</name>
|
<name>tests.openjpa.allowfailure</name>
|
||||||
|
|
Loading…
Reference in New Issue