diff options
author | jfrijters <jfrijters> | 2013-08-08 18:09:23 +0400 |
---|---|---|
committer | jfrijters <jfrijters> | 2013-08-08 18:09:23 +0400 |
commit | 546f3216e16771166236121ca70441e01360840a (patch) | |
tree | e7dfcee68abd4b0824c2399b3016a679ee6ae1dd /openjdk | |
parent | 938206e2a3e8d5c7e5d49067b366829fd1c4f682 (diff) |
Updated DriverManager to OpenJDK 7 (somehow this file was previously missed).
Diffstat (limited to 'openjdk')
-rw-r--r-- | openjdk/java/sql/DriverManager.java | 302 |
1 files changed, 127 insertions, 175 deletions
diff --git a/openjdk/java/sql/DriverManager.java b/openjdk/java/sql/DriverManager.java index 9e357f46..6c35058d 100644 --- a/openjdk/java/sql/DriverManager.java +++ b/openjdk/java/sql/DriverManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,10 +27,10 @@ package java.sql; import ikvm.internal.CallerID; import java.util.Iterator; -import java.sql.Driver; import java.util.ServiceLoader; import java.security.AccessController; import java.security.PrivilegedAction; +import java.util.concurrent.CopyOnWriteArrayList; /** @@ -80,6 +80,27 @@ import java.security.PrivilegedAction; public class DriverManager { + // List of registered JDBC drivers + private final static CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<DriverInfo>(); + private static volatile int loginTimeout = 0; + private static volatile java.io.PrintWriter logWriter = null; + private static volatile java.io.PrintStream logStream = null; + // Used in println() to synchronize logWriter + private final static Object logSync = new Object(); + + /* Prevent the DriverManager class from being instantiated. */ + private DriverManager(){} + + + /** + * Load the initial JDBC drivers by checking the System property + * jdbc.properties and then use the {@code ServiceLoader} mechanism + */ + static { + loadInitialDrivers(); + println("JDBC DriverManager initialized"); + } + /** * The <code>SQLPermission</code> constant that allows the * setting of the logging stream. @@ -240,43 +261,31 @@ public class DriverManager { @ikvm.internal.HasCallerID public static Driver getDriver(String url) throws SQLException { - java.util.Vector drivers = null; println("DriverManager.getDriver(\"" + url + "\")"); - if (!initialized) { - initialize(); - } - - synchronized (DriverManager.class){ - // use the read copy of the drivers vector - drivers = readDrivers; - } - // Gets the classloader of the code that called this method, may // be null. ClassLoader callerCL = CallerID.getCallerID().getCallerClassLoader(); - // Walk through the loaded drivers attempting to locate someone + // Walk through the loaded registeredDrivers attempting to locate someone // who understands the given URL. - for (int i = 0; i < drivers.size(); i++) { - DriverInfo di = (DriverInfo)drivers.elementAt(i); + for (DriverInfo aDriver : registeredDrivers) { // If the caller does not have permission to load the driver then // skip it. - if ( getCallerClass(callerCL, di.driverClassName ) != - di.driverClass ) { - println(" skipping: " + di); - continue; - } - try { - println(" trying " + di); - if (di.driver.acceptsURL(url)) { - // Success! - println("getDriver returning " + di); - return (di.driver); + if(isDriverAllowed(aDriver.driver, callerCL)) { + try { + if(aDriver.driver.acceptsURL(url)) { + // Success! + println("getDriver returning " + aDriver.driver.getClass().getName()); + return (aDriver.driver); + } + + } catch(SQLException sqe) { + // Drop through and try the next driver. } - } catch (SQLException ex) { - // Drop through and try the next driver. + } else { + println(" skipping: " + aDriver.driver.getClass().getName()); } } @@ -297,23 +306,16 @@ public class DriverManager { */ public static synchronized void registerDriver(java.sql.Driver driver) throws SQLException { - if (!initialized) { - initialize(); - } - - DriverInfo di = new DriverInfo(); - - di.driver = driver; - di.driverClass = driver.getClass(); - di.driverClassName = di.driverClass.getName(); - // Not Required -- drivers.addElement(di); - - writeDrivers.addElement(di); - println("registerDriver: " + di); + /* Register the driver if it has not already been added to our list */ + if(driver != null) { + registeredDrivers.addIfAbsent(new DriverInfo(driver)); + } else { + // This is for compatibility with the original DriverManager + throw new NullPointerException(); + } - /* update the read copy of drivers vector */ - readDrivers = (java.util.Vector) writeDrivers.clone(); + println("registerDriver: " + driver); } @@ -327,37 +329,27 @@ public class DriverManager { @ikvm.internal.HasCallerID public static synchronized void deregisterDriver(Driver driver) throws SQLException { + if (driver == null) { + return; + } + // Gets the classloader of the code that called this method, // may be null. ClassLoader callerCL = CallerID.getCallerID().getCallerClassLoader(); println("DriverManager.deregisterDriver: " + driver); - // Walk through the loaded drivers. - int i; - DriverInfo di = null; - for (i = 0; i < writeDrivers.size(); i++) { - di = (DriverInfo)writeDrivers.elementAt(i); - if (di.driver == driver) { - break; + DriverInfo aDriver = new DriverInfo(driver); + if(registeredDrivers.contains(aDriver)) { + if (isDriverAllowed(driver, callerCL)) { + registeredDrivers.remove(aDriver); + } else { + // If the caller does not have permission to load the driver then + // throw a SecurityException. + throw new SecurityException(); } - } - // If we can't find the driver just return. - if (i >= writeDrivers.size()) { + } else { println(" couldn't find driver to unload"); - return; - } - - // If the caller does not have permission to load the driver then - // throw a security exception. - if (getCallerClass(callerCL, di.driverClassName ) != di.driverClass ) { - throw new SecurityException(); } - - // Remove the driver. Other entries in drivers get shuffled down. - writeDrivers.removeElementAt(i); - - /* update the read copy of drivers vector */ - readDrivers = (java.util.Vector) writeDrivers.clone(); } /** @@ -372,31 +364,20 @@ public class DriverManager { @ikvm.internal.HasCallerID public static java.util.Enumeration<Driver> getDrivers() { java.util.Vector<Driver> result = new java.util.Vector<Driver>(); - java.util.Vector drivers = null; - - if (!initialized) { - initialize(); - } - - synchronized (DriverManager.class){ - // use the readcopy of drivers - drivers = readDrivers; - } // Gets the classloader of the code that called this method, may // be null. ClassLoader callerCL = CallerID.getCallerID().getCallerClassLoader(); - // Walk through the loaded drivers. - for (int i = 0; i < drivers.size(); i++) { - DriverInfo di = (DriverInfo)drivers.elementAt(i); + // Walk through the loaded registeredDrivers. + for(DriverInfo aDriver : registeredDrivers) { // If the caller does not have permission to load the driver then // skip it. - if ( getCallerClass(callerCL, di.driverClassName ) != di.driverClass ) { - println(" skipping: " + di); - continue; + if(isDriverAllowed(aDriver.driver, callerCL)) { + result.addElement(aDriver.driver); + } else { + println(" skipping: " + aDriver.getClass().getName()); } - result.addElement(di.driver); } return (result.elements()); @@ -488,28 +469,29 @@ public class DriverManager { //------------------------------------------------------------------------ - // Returns the class object that would be created if the code calling the - // driver manager had loaded the driver class, or null if the class - // is inaccessible. - private static Class getCallerClass(ClassLoader callerClassLoader, - String driverClassName) { - Class callerC = null; + // Indicates whether the class object that would be created if the code calling + // DriverManager is accessible. + private static boolean isDriverAllowed(Driver driver, ClassLoader classLoader) { + boolean result = false; + if(driver != null) { + Class<?> aClass = null; + try { + aClass = Class.forName(driver.getClass().getName(), true, classLoader); + } catch (Exception ex) { + result = false; + } - try { - callerC = Class.forName(driverClassName, true, callerClassLoader); - } - catch (Exception ex) { - callerC = null; // being very careful + result = ( aClass == driver.getClass() ) ? true : false; } - return callerC; + return result; } private static void loadInitialDrivers() { String drivers; try { - drivers = (String) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + drivers = AccessController.doPrivileged(new PrivilegedAction<String>() { + public String run() { return System.getProperty("jdbc.drivers"); } }); @@ -521,8 +503,8 @@ public class DriverManager { // exposed as a java.sql.Driver.class service. // ServiceLoader.load() replaces the sun.misc.Providers() - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction<Void>() { + public Void run() { ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class); Iterator driversIterator = loadedDrivers.iterator(); @@ -551,26 +533,17 @@ public class DriverManager { }); println("DriverManager.initialize: jdbc.drivers = " + drivers); - if (drivers == null) { + + if (drivers == null || drivers.equals("")) { return; } - while (drivers.length() != 0) { - int x = drivers.indexOf(':'); - String driver; - if (x < 0) { - driver = drivers; - drivers = ""; - } else { - driver = drivers.substring(0, x); - drivers = drivers.substring(x+1); - } - if (driver.length() == 0) { - continue; - } + String[] driversList = drivers.split(":"); + println("number of Drivers:" + driversList.length); + for (String aDriver : driversList) { try { - println("DriverManager.Initialize: loading " + driver); - Class.forName(driver, true, - ClassLoader.getSystemClassLoader()); + println("DriverManager.Initialize: loading " + aDriver); + Class.forName(aDriver, true, + ClassLoader.getSystemClassLoader()); } catch (Exception ex) { println("DriverManager.Initialize: load failed: " + ex); } @@ -581,7 +554,6 @@ public class DriverManager { // Worker method called by the public getConnection() methods. private static Connection getConnection( String url, java.util.Properties info, ClassLoader callerCL) throws SQLException { - java.util.Vector drivers = null; /* * When callerCl is null, we should check the application's * (which is invoking this class indirectly) @@ -601,40 +573,32 @@ public class DriverManager { println("DriverManager.getConnection(\"" + url + "\")"); - if (!initialized) { - initialize(); - } - - synchronized (DriverManager.class){ - // use the readcopy of drivers - drivers = readDrivers; - } - - // Walk through the loaded drivers attempting to make a connection. + // Walk through the loaded registeredDrivers attempting to make a connection. // Remember the first exception that gets raised so we can reraise it. SQLException reason = null; - for (int i = 0; i < drivers.size(); i++) { - DriverInfo di = (DriverInfo)drivers.elementAt(i); + for(DriverInfo aDriver : registeredDrivers) { // If the caller does not have permission to load the driver then // skip it. - if ( getCallerClass(callerCL, di.driverClassName ) != di.driverClass ) { - println(" skipping: " + di); - continue; - } - try { - println(" trying " + di); - Connection result = di.driver.connect(url, info); - if (result != null) { - // Success! - println("getConnection returning " + di); - return (result); - } - } catch (SQLException ex) { - if (reason == null) { - reason = ex; + if(isDriverAllowed(aDriver.driver, callerCL)) { + try { + println(" trying " + aDriver.driver.getClass().getName()); + Connection con = aDriver.driver.connect(url, info); + if (con != null) { + // Success! + println("getConnection returning " + aDriver.driver.getClass().getName()); + return (con); + } + } catch (SQLException ex) { + if (reason == null) { + reason = ex; + } } + + } else { + println(" skipping: " + aDriver.getClass().getName()); } + } // if we got here nobody could connect. @@ -647,42 +611,30 @@ public class DriverManager { throw new SQLException("No suitable driver found for "+ url, "08001"); } +} - // Class initialization. - static void initialize() { - if (initialized) { - return; - } - initialized = true; - loadInitialDrivers(); - println("JDBC DriverManager initialized"); - } - - /* Prevent the DriverManager class from being instantiated. */ - private DriverManager(){} - - /* write copy of the drivers vector */ - private static java.util.Vector writeDrivers = new java.util.Vector(); - - /* write copy of the drivers vector */ - private static java.util.Vector readDrivers = new java.util.Vector(); - - private static int loginTimeout = 0; - private static java.io.PrintWriter logWriter = null; - private static java.io.PrintStream logStream = null; - private static boolean initialized = false; +/* + * Wrapper class for registered Drivers in order to not expose Driver.equals() + * to avoid the capture of the Driver it being compared to as it might not + * normally have access. + */ +class DriverInfo { - private static Object logSync = new Object(); + final Driver driver; + DriverInfo(Driver driver) { + this.driver = driver; + } -} + public boolean equals(Object other) { + return (other instanceof DriverInfo) + && this.driver == ((DriverInfo) other).driver; + } -// DriverInfo is a package-private support class. -class DriverInfo { - Driver driver; - Class driverClass; - String driverClassName; + public int hashCode() { + return driver.hashCode(); + } public String toString() { - return ("driver[className=" + driverClassName + "," + driver + "]"); + return ("driver[className=" + driver + "]"); } } |