package net.sourceforge.jdbclogger;
/*
* 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.
*/
import net.sourceforge.jdbclogger.core.AbstractWrapperDriver;
import net.sourceforge.jdbclogger.core.ConnectionWrapper;
import net.sourceforge.jdbclogger.core.config.Environment;
import net.sourceforge.jdbclogger.core.config.JdbcLoggerConstants;
import net.sourceforge.jdbclogger.core.config.ResourceList;
import net.sourceforge.jdbclogger.core.formatters.BlobParameterFormatterImpl;
import net.sourceforge.jdbclogger.core.formatters.BytesParameterFormatterImpl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Properties;
/**
* @author Catalin Kormos (latest modification by $Author: sorin7486 $)
* @version $Revision: 158 $ $Date: 2007-11-03 01:41:18 +0800 (周六, 2007-11-03) $
*/
public class JdbcLoggerDriver extends AbstractWrapperDriver {
private static Log log = LogFactory.getLog(JdbcLoggerDriver.class);
static {
// retrieving the names of the drivers requested by the user (in the jdbclogger.properties file or as system properties)
Properties properties = Environment.getProperties();
boolean targetJdbcDriverClassNameFound = false;
Enumeration propertyNames = properties.propertyNames();
while (propertyNames.hasMoreElements()) {
String aPropertyName = (String) propertyNames.nextElement();
if (aPropertyName.startsWith(JdbcLoggerConstants.USER_DRIVER_PROPERTY_NAME)) {
targetJdbcDriverClassNameFound = true;
String aPropertyValue = properties.getProperty(aPropertyName);
//register the wrapper for each driver
String wrapperDriverClassName = registerWrapperForName(aPropertyValue);
log.info("Wrapper '" + wrapperDriverClassName + "' successfully registed for driver '" + aPropertyValue + "'");
}
}
//there is no jdbc driver class name specified, neither in a jdbclogger.properties file nor
//specified as system property
if (!targetJdbcDriverClassNameFound) {
log.fatal("No target JDBC Driver class name found, register in the DriverManager skipped.");
}
}
/**
*
*/
public JdbcLoggerDriver() {
super();
this.formatters.add(new BlobParameterFormatterImpl());
this.formatters.add(new BytesParameterFormatterImpl());
}
/**
* Replaces the given driver class name with the corresponding wrapper one, in the DriverManager.
*
* @param userDriverClassName the driver class to be replace with the corresponding wrapper driver.
* @return the wrapper driver class name that replace the given user driver class name.
*/
private static String registerWrapperForName(String userDriverClassName) {
String wrapperDriverClassName = null;
try {
//look in the classpath for a custom driver that supports the requested driver
Driver userDriver = findRegisteredUserDriver(userDriverClassName);
if (userDriver == null) {
//there is no registered user driver, try registering it now
try {
Class.forName(userDriverClassName);
//try again, getting the instance from the driver manager
userDriver = findRegisteredUserDriver(userDriverClassName);
}
catch (ClassNotFoundException exc) {
//ignore, we failed to initialize the user driver
}
}
if (userDriver != null) {
AbstractWrapperDriver wrapperDriver = getWrapperDriver(userDriverClassName);
wrapperDriverClassName = wrapperDriver.getClass().getName();
wrapperDriver.setDriver(userDriver);
if (!JdbcLoggerDriver.class.equals(wrapperDriver.getClass())) {
JdbcLoggerDriver drv = new JdbcLoggerDriver();
drv.setDriver(wrapperDriver);
wrapperDriver = drv;
}
DriverManager.deregisterDriver(userDriver);
DriverManager.registerDriver(wrapperDriver);
} else {
log.fatal("Could not find user driver '" + userDriverClassName + "' in the DriverManager.");
}
}
catch (Exception exc) {
log.error("Exception while registering driver.", exc);
}
return wrapperDriverClassName;
}
/**
* @param userDriverClassName
* @return
*/
public static Driver findRegisteredUserDriver(String userDriverClassName) {
Enumeration en = DriverManager.getDrivers();
while (en.hasMoreElements()) {
Driver aDriver = (Driver) en.nextElement();
if (aDriver.getClass().getName().equals(userDriverClassName)) {
return aDriver;
}
}
return null;
}
/**
* @param userDriverClassName
* @return
*/
public static AbstractWrapperDriver getWrapperDriver(String userDriverClassName) {
Enumeration<URL> driverList = null;
Collection<String> files = ResourceList.getResources(".*" + JdbcLoggerConstants.WRAPPER_DRIVER_CONFIG_PACKAGE_NAME + ".*");
Collection<URL> resources = new HashSet<URL>();
for (String file : files) {
file = file.substring(file.indexOf(JdbcLoggerConstants.WRAPPER_DRIVER_CONFIG_PACKAGE_NAME));
driverList = Environment.getResources(file);
while (driverList.hasMoreElements()) {
URL url = driverList.nextElement();
if (!resources.contains(url)) {
resources.add(url);
log.debug("Properties files found: " + url.toString());
}
}
}
for (URL resUrl : resources) {
Properties driverProperties = new Properties();
InputStream res = null;
try {
res = resUrl.openStream();
driverProperties.load(res);
}
catch (IOException e) {
log.error("Error reading " + JdbcLoggerConstants.WRAPPER_DRIVER_CONFIG_FILE_NAME);
}
finally {
if (res != null)
try {
res.close();
}
catch (IOException e) {
log.error("Closing input stream", e);
}
}
if (userDriverClassName.equals(driverProperties.getProperty(JdbcLoggerConstants.TARGET_DRIVER_PROPERTY_NAME))) {
String wrapperDriver = driverProperties.getProperty(JdbcLoggerConstants.WRAPPER_DRIVER_PROPERTY_NAME);
try {
return (AbstractWrapperDriver) Class.forName(wrapperDriver).newInstance();
}
catch (Exception exc) {
log.error("Unable to instantiate wrapper class: " + exc);
}
}
}
return new JdbcLoggerDriver();
}
public Connection connect(String url, Properties properties) throws SQLException {
if (getDriver() == null)
return null;
//has to return null if no connection available for compliance with the JDBC API
Connection con = getDriver().connect(url, properties);
if (con != null) {
if (con instanceof AbstractWrapperDriver)
return con;
return new ConnectionWrapper(con, formatters);
}
return null;
}
}