diff options
Diffstat (limited to 'external/ikvm/openjdk/java/sql/DriverManager.java')
-rw-r--r-- | external/ikvm/openjdk/java/sql/DriverManager.java | 370 |
1 files changed, 153 insertions, 217 deletions
diff --git a/external/ikvm/openjdk/java/sql/DriverManager.java b/external/ikvm/openjdk/java/sql/DriverManager.java index 9e357f4669..8698345c17 100644 --- a/external/ikvm/openjdk/java/sql/DriverManager.java +++ b/external/ikvm/openjdk/java/sql/DriverManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -25,13 +25,13 @@ 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; +import sun.reflect.CallerSensitive; +import sun.reflect.Reflection; /** * <P>The basic service for managing a set of JDBC drivers.<br> @@ -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. @@ -160,15 +181,10 @@ public class DriverManager { * @return a Connection to the URL * @exception SQLException if a database access error occurs */ - @ikvm.internal.HasCallerID + @CallerSensitive public static Connection getConnection(String url, java.util.Properties info) throws SQLException { - - // Gets the classloader of the code that called this method, may - // be null. - ClassLoader callerCL = CallerID.getCallerID().getCallerClassLoader(); - - return (getConnection(url, info, callerCL)); + return (getConnection(url, info, Reflection.getCallerClass())); } /** @@ -184,15 +200,11 @@ public class DriverManager { * @return a connection to the URL * @exception SQLException if a database access error occurs */ - @ikvm.internal.HasCallerID + @CallerSensitive public static Connection getConnection(String url, String user, String password) throws SQLException { java.util.Properties info = new java.util.Properties(); - // Gets the classloader of the code that called this method, may - // be null. - ClassLoader callerCL = CallerID.getCallerID().getCallerClassLoader(); - if (user != null) { info.put("user", user); } @@ -200,7 +212,7 @@ public class DriverManager { info.put("password", password); } - return (getConnection(url, info, callerCL)); + return (getConnection(url, info, Reflection.getCallerClass())); } /** @@ -213,17 +225,12 @@ public class DriverManager { * @return a connection to the URL * @exception SQLException if a database access error occurs */ - @ikvm.internal.HasCallerID + @CallerSensitive public static Connection getConnection(String url) throws SQLException { java.util.Properties info = new java.util.Properties(); - - // Gets the classloader of the code that called this method, may - // be null. - ClassLoader callerCL = CallerID.getCallerID().getCallerClassLoader(); - - return (getConnection(url, info, callerCL)); + return (getConnection(url, info, Reflection.getCallerClass())); } /** @@ -237,47 +244,34 @@ public class DriverManager { * that can connect to the given URL * @exception SQLException if a database access error occurs */ - @ikvm.internal.HasCallerID + @CallerSensitive public static Driver getDriver(String url) throws SQLException { - java.util.Vector drivers = null; println("DriverManager.getDriver(\"" + url + "\")"); - if (!initialized) { - initialize(); - } + Class<?> callerClass = Reflection.getCallerClass(); - 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, callerClass)) { + 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()); } + } println("getDriver: no suitable driver"); @@ -297,23 +291,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); } @@ -324,40 +311,27 @@ public class DriverManager { * @param driver the JDBC Driver to drop * @exception SQLException if a database access error occurs */ - @ikvm.internal.HasCallerID + @CallerSensitive public static synchronized void deregisterDriver(Driver driver) throws SQLException { - // Gets the classloader of the code that called this method, - // may be null. - ClassLoader callerCL = CallerID.getCallerID().getCallerClassLoader(); + if (driver == null) { + return; + } + 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, Reflection.getCallerClass())) { + 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(); } /** @@ -369,36 +343,22 @@ public class DriverManager { * * @return the list of JDBC Drivers loaded by the caller's class loader */ - @ikvm.internal.HasCallerID + @CallerSensitive 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(); + Class<?> callerClass = Reflection.getCallerClass(); - // 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, callerClass)) { + result.addElement(aDriver.driver); + } else { + println(" skipping: " + aDriver.getClass().getName()); } - result.addElement(di.driver); } - return (result.elements()); } @@ -488,28 +448,34 @@ 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, Class<?> caller) { + ClassLoader callerCL = caller != null ? caller.getClassLoader() : null; + return isDriverAllowed(driver, callerCL); + } - try { - callerC = Class.forName(driverClassName, true, callerClassLoader); - } - catch (Exception ex) { - callerC = null; // being very careful + 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; + } + + 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 +487,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(); @@ -541,7 +507,7 @@ public class DriverManager { */ try{ while(driversIterator.hasNext()) { - println(" Loading done by the java.util.ServiceLoader : "+driversIterator.next()); + driversIterator.next(); } } catch(Throwable t) { // Do nothing @@ -551,26 +517,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); } @@ -580,19 +537,19 @@ 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; + String url, java.util.Properties info, Class<?> caller) throws SQLException { /* * When callerCl is null, we should check the application's * (which is invoking this class indirectly) * classloader, so that the JDBC driver class outside rt.jar * can be loaded from here. */ - synchronized(DriverManager.class) { - // synchronize loading of the correct classloader. - if(callerCL == null) { - callerCL = Thread.currentThread().getContextClassLoader(); - } + ClassLoader callerCL = caller != null ? caller.getClassLoader() : null; + synchronized (DriverManager.class) { + // synchronize loading of the correct classloader. + if (callerCL == null) { + callerCL = Thread.currentThread().getContextClassLoader(); + } } if(url == null) { @@ -601,40 +558,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. @@ -646,43 +595,30 @@ public class DriverManager { println("getConnection: no suitable driver found for "+ url); throw new SQLException("No suitable driver found for "+ url, "08001"); } +} +/* + * 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 { - // Class initialization. - static void initialize() { - if (initialized) { - return; - } - initialized = true; - loadInitialDrivers(); - println("JDBC DriverManager initialized"); + final Driver driver; + DriverInfo(Driver driver) { + this.driver = driver; } - /* 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; - - private static Object logSync = new Object(); - -} + 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 + "]"); } } |