src/share/classes/java/sql/DriverManager.java

Print this page

        

@@ -107,10 +107,18 @@
      * @since 1.3
      */
     final static SQLPermission SET_LOG_PERMISSION =
         new SQLPermission("setLog");
 
+    /**
+     * The {@code SQLPermission} constant that allows the
+     * un-register a registered JDBC driver.
+     * @since 1.8
+     */
+    final static SQLPermission DEREGISTER_DRIVER_PERMISSION =
+        new SQLPermission("deregisterDriver");
+
     //--------------------------JDBC 2.0-----------------------------
 
     /**
      * Retrieves the log writer.
      *

@@ -329,48 +337,93 @@
      * @exception SQLException if a database access error occurs
      */
     public static synchronized void registerDriver(java.sql.Driver driver)
         throws SQLException {
 
+        registerDriver(driver, null);
+    }
+    
+    /**
+     * Registers the given driver with the <code>DriverManager</code>.
+     * A newly-loaded driver class should call
+     * the method {@code registerDriver} to make itself
+     * known to the {@code DriverManager}.  
+     *
+     * @param driver the new JDBC Driver that is to be registered with the
+     *               {@code DriverManager}
+     * @param da the {@code DriverAction} implementation to be called
+     * when the JDBC Driver has been de-registered; or null if the JDBC
+     * driver is not to be notified when de-registered.
+     * @exception SQLException if a database access error occurs
+     * @see DriverAction
+     * @since 1.8
+     */
+    public static synchronized void registerDriver(java.sql.Driver driver,
+            DriverAction da)
+        throws SQLException {
+
         /* Register the driver if it has not already been added to our list */
         if(driver != null) {
-            registeredDrivers.addIfAbsent(new DriverInfo(driver));
+            DriverInfo di = new DriverInfo(driver);
+            di.da= da;
+            registeredDrivers.addIfAbsent(di);
         } else {
             // This is for compatibility with the original DriverManager
             throw new NullPointerException();
         }
 
         println("registerDriver: " + driver);
 
     }
 
     /**
-     * Drops a driver from the <code>DriverManager</code>'s list.
-     *  Applets can only deregister drivers from their own classloaders.
+     * Removes the specified driver from the {@code DriverManager}'s list of
+     * registered drivers.
+     * <p>
+     * If a security manager exists and its {@code checkPermission} denies
+     * permission, then a {@code SecurityException} will be thrown.
+     * <p>
+     * No action will be taken if the specified driver
+     * was not found in the list of registered drivers or  was {@code null}.
+     * <p>
+     * If a {@code DriverAction} implementation was specified when the driver was
+     * registered, its {@code deregister} method will be called.
      *
-     * @param driver the JDBC Driver to drop
+     * @param driver the JDBC Driver to remove
      * @exception SQLException if a database access error occurs
+     * @throws SecurityException if a security manager exists and its
+     * {@code checkPermission} method denies permission to deregister a driver.
+     *
+     * @see SecurityManager#checkPermission
+     * @see DriverAction
      */
     public static synchronized void deregisterDriver(Driver driver)
         throws SQLException {
         if (driver == null) {
             return;
         }
 
+        SecurityManager sec = System.getSecurityManager();
+        if (sec != null) {
+            sec.checkPermission(DEREGISTER_DRIVER_PERMISSION);
+        }
+        
         // Gets the classloader of the code that called this method,
         // may be null.
         ClassLoader callerCL = DriverManager.getCallerClassLoader();
         println("DriverManager.deregisterDriver: " + driver);
 
         DriverInfo aDriver = new DriverInfo(driver);
         if(registeredDrivers.contains(aDriver)) {
             if (isDriverAllowed(driver, callerCL)) {
+                DriverInfo di = registeredDrivers.get(registeredDrivers.indexOf(aDriver));
+                 // If a DriverAction was specified, Call it to notify the
+                 // driver that it has been deregistered
+                 if(di.da != null) {
+                     di.da.deregister();
+                 }
                  registeredDrivers.remove(aDriver);
-            } else {
-                // If the caller does not have permission to load the driver then
-                // throw a SecurityException.
-                throw new SecurityException();
             }
         } else {
             println("    couldn't find driver to unload");
         }
     }

@@ -653,12 +706,14 @@
  * normally have access.
  */
 class DriverInfo {
 
     final Driver driver;
+    DriverAction da;
     DriverInfo(Driver driver) {
         this.driver = driver;
+        da = null;
     }
 
     @Override
     public boolean equals(Object other) {
         return (other instanceof DriverInfo)