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

Print this page

        

@@ -108,10 +108,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.
      *

@@ -307,53 +315,105 @@
         throw new SQLException("No suitable driver", "08001");
     }
 
 
     /**
-     * Registers the given driver with the <code>DriverManager</code>.
+     * Registers the given driver with the {@code DriverManager}.
      * A newly-loaded driver class should call
-     * the method <code>registerDriver</code> to make itself
-     * known to the <code>DriverManager</code>.
+     * the method {@code registerDriver} to make itself
+     * known to the {@code DriverManager}. If the driver had previously been
+     * registered, no action is taken.
      *
      * @param driver the new JDBC Driver that is to be registered with the
-     *               <code>DriverManager</code>
+     *               {@code DriverManager}
      * @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}.
+     * A newly-loaded driver class should call
+     * the method {@code registerDriver} to make itself
+     * known to the {@code DriverManager}. If the driver had previously been
+     * registered, no action is taken.
+     *
+     * @param driver the new JDBC Driver that is to be registered with the
+     *               {@code DriverManager}
+     * @param da     the {@code DriverAction} implementation to be used when
+     *               {@code DriverManager#deregisterDriver} is called            
+     * @exception SQLException if a database access error occurs
+     */
+    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));
+            registeredDrivers.addIfAbsent(new DriverInfo(driver, da));
         } 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 {@code null} value is specified for the driver to be removed, then no
+     * action is taken.
+     * <p>
+     * If a security manager exists and its {@code checkPermission} denies
+     * permission, then a {@code SecurityException} will be thrown.
+     * <p>
+     * If the specified driver is not found in the list of registered drivers,
+     * then no action is taken.  If the specified driver was found, then the
+     * driver's {@linkplain Driver#deregisterDriver  deregisterDriver} method will
+     * be called to release any resources it may hold.
+     * <p>
+     * If a {@code DriverAction} instance was specified when the JDBC driver was
+     * registered, its deregister method will be called
+     * prior to the driver being removed from the list of registered drivers.
      *
-     * @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 Driver#deregisterDriver
      */
     @CallerSensitive
     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);
+        }
+        
         println("DriverManager.deregisterDriver: " + driver);
 
-        DriverInfo aDriver = new DriverInfo(driver);
+        DriverInfo aDriver = new DriverInfo(driver, null);
         if(registeredDrivers.contains(aDriver)) {
             if (isDriverAllowed(driver, Reflection.getCallerClass())) {
+                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.action() != null) {
+                     di.action().deregister();
+                 }
                  registeredDrivers.remove(aDriver);
             } else {
                 // If the caller does not have permission to load the driver then
                 // throw a SecurityException.
                 throw new SecurityException();

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

@@ -656,6 +718,10 @@
 
     @Override
     public String toString() {
         return ("driver[className="  + driver + "]");
     }
+    
+    DriverAction action() {
+        return da;
+    }
 }