blob: 6bab0cd3c1c632d5f72ab207898827fe07e7684e [file] [log] [blame]
/*
* 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.openejb.resource.jdbc;
import org.apache.commons.dbcp.SQLNestedException;
import org.apache.xbean.finder.ResourceFinder;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.sql.SQLException;
import java.util.Map;
public final class BasicDataSourceUtil {
private BasicDataSourceUtil() {
}
public static DataSourcePlugin getDataSourcePlugin(String jdbcUrl) throws SQLException {
// determine the vendor based on the jdbcUrl stirng "jdbc:${Vendor}:properties"
String vendor = getJdbcName(jdbcUrl);
// no vendor so no plugin
if (vendor == null) return null;
// find the plugin class
String pluginClassName = null;
try {
ResourceFinder finder = new ResourceFinder("META-INF");
Map<String,String> plugins = finder.mapAvailableStrings(DataSourcePlugin.class.getName());
pluginClassName = plugins.get(vendor);
} catch (IOException ignored) {
// couldn't determine the plugins, which isn't fatal
}
// no plugin found
if (pluginClassName == null || pluginClassName.length() <= 0) {
return null;
}
// create the plugin
try {
Class pluginClass = Class.forName(pluginClassName);
DataSourcePlugin plugin = (DataSourcePlugin) pluginClass.newInstance();
return plugin;
} catch (ClassNotFoundException e) {
throw new SQLException("Unable to load data source helper class '" + pluginClassName + "' for database '" + vendor + "'");
} catch (Exception e) {
throw (SQLException) new SQLException("Unable to create data source helper class '" + pluginClassName + "' for database '" + vendor + "'").initCause(e);
}
}
public static String getJdbcName(String jdbcUrl) {
// nothing gets you nothing
if (jdbcUrl == null) return null;
// strip off "jdbc:"
if (!jdbcUrl.startsWith("jdbc:")) {
return null;
}
jdbcUrl = jdbcUrl.substring("jdbc:".length());
// return text up to first ":" if present
int index = jdbcUrl.indexOf(':');
// It is ok to have no trailing ':'. This may be a url like jdbc:specialDB.
if (index >= 0) {
jdbcUrl = jdbcUrl.substring(0, index);
}
return jdbcUrl;
}
/**
* Create a {@link PasswordCipher} instance from the
* passwordCipher class name.
*
* @param passwordCipherClass the password cipher to look for
* @return the password cipher from the passwordCipher class name
* optionally set.
* @throws SQLException
* if the driver can not be found.
*/
public static PasswordCipher getPasswordCipher(String passwordCipherClass) throws SQLException {
// Load the password cipher class
Class<? extends PasswordCipher> pwdCipher = null;
// try looking for implementation in /META-INF/org.apache.openejb.resource.jdbc.PasswordCipher
ResourceFinder finder = new ResourceFinder("META-INF/");
Map<String, Class<? extends PasswordCipher>> impls;
try {
impls = finder.mapAllImplementations(PasswordCipher.class);
} catch (Throwable t) {
String message =
"Password cipher '" + passwordCipherClass +
"' not found in META-INF/org.apache.openejb.resource.jdbc.PasswordCipher.";
throw new SQLNestedException(message, t);
}
pwdCipher = impls.get(passwordCipherClass);
//
final ClassLoader tccl = Thread.currentThread().getContextClassLoader();
final URL url = tccl.getResource("META-INF/org.apache.openejb.resource.jdbc.PasswordCipher/" + passwordCipherClass);
if (url != null) {
try {
final String clazz = new BufferedReader(new InputStreamReader(url.openStream())).readLine().trim();
pwdCipher = tccl.loadClass(clazz).asSubclass(PasswordCipher.class);
} catch (Exception e) {
// ignored
}
}
// if not found in META-INF/org.apache.openejb.resource.jdbc.PasswordCipher
// we can try to load the class.
if (null == pwdCipher) {
try {
try {
pwdCipher = Class.forName(passwordCipherClass).asSubclass(PasswordCipher.class);
} catch (ClassNotFoundException cnfe) {
pwdCipher = tccl.loadClass(passwordCipherClass).asSubclass(PasswordCipher.class);
}
} catch (Throwable t) {
String message = "Cannot load password cipher class '" + passwordCipherClass + "'";
throw new SQLNestedException(message, t);
}
}
// Create an instance
PasswordCipher cipher = null;
try {
cipher = pwdCipher.newInstance();
} catch (Throwable t) {
String message = "Cannot create password cipher instance";
throw new SQLNestedException(message, t);
}
return cipher;
}
}