93 private DriverManager(){}
94
95
96 /**
97 * Load the initial JDBC drivers by checking the System property
98 * jdbc.properties and then use the {@code ServiceLoader} mechanism
99 */
100 static {
101 loadInitialDrivers();
102 println("JDBC DriverManager initialized");
103 }
104
105 /**
106 * The <code>SQLPermission</code> constant that allows the
107 * setting of the logging stream.
108 * @since 1.3
109 */
110 final static SQLPermission SET_LOG_PERMISSION =
111 new SQLPermission("setLog");
112
113 //--------------------------JDBC 2.0-----------------------------
114
115 /**
116 * Retrieves the log writer.
117 *
118 * The <code>getLogWriter</code> and <code>setLogWriter</code>
119 * methods should be used instead
120 * of the <code>get/setlogStream</code> methods, which are deprecated.
121 * @return a <code>java.io.PrintWriter</code> object
122 * @see #setLogWriter
123 * @since 1.2
124 */
125 public static java.io.PrintWriter getLogWriter() {
126 return logWriter;
127 }
128
129 /**
130 * Sets the logging/tracing <code>PrintWriter</code> object
131 * that is used by the <code>DriverManager</code> and all drivers.
132 * <P>
292 // Success!
293 println("getDriver returning " + aDriver.driver.getClass().getName());
294 return (aDriver.driver);
295 }
296
297 } catch(SQLException sqe) {
298 // Drop through and try the next driver.
299 }
300 } else {
301 println(" skipping: " + aDriver.driver.getClass().getName());
302 }
303
304 }
305
306 println("getDriver: no suitable driver");
307 throw new SQLException("No suitable driver", "08001");
308 }
309
310
311 /**
312 * Registers the given driver with the <code>DriverManager</code>.
313 * A newly-loaded driver class should call
314 * the method <code>registerDriver</code> to make itself
315 * known to the <code>DriverManager</code>.
316 *
317 * @param driver the new JDBC Driver that is to be registered with the
318 * <code>DriverManager</code>
319 * @exception SQLException if a database access error occurs
320 */
321 public static synchronized void registerDriver(java.sql.Driver driver)
322 throws SQLException {
323
324 /* Register the driver if it has not already been added to our list */
325 if(driver != null) {
326 registeredDrivers.addIfAbsent(new DriverInfo(driver));
327 } else {
328 // This is for compatibility with the original DriverManager
329 throw new NullPointerException();
330 }
331
332 println("registerDriver: " + driver);
333
334 }
335
336 /**
337 * Drops a driver from the <code>DriverManager</code>'s list.
338 * Applets can only deregister drivers from their own classloaders.
339 *
340 * @param driver the JDBC Driver to drop
341 * @exception SQLException if a database access error occurs
342 */
343 @CallerSensitive
344 public static synchronized void deregisterDriver(Driver driver)
345 throws SQLException {
346 if (driver == null) {
347 return;
348 }
349
350 println("DriverManager.deregisterDriver: " + driver);
351
352 DriverInfo aDriver = new DriverInfo(driver);
353 if(registeredDrivers.contains(aDriver)) {
354 if (isDriverAllowed(driver, Reflection.getCallerClass())) {
355 registeredDrivers.remove(aDriver);
356 } else {
357 // If the caller does not have permission to load the driver then
358 // throw a SecurityException.
359 throw new SecurityException();
360 }
361 } else {
362 println(" couldn't find driver to unload");
363 }
364 }
365
366 /**
367 * Retrieves an Enumeration with all of the currently loaded JDBC drivers
368 * to which the current caller has access.
369 *
370 * <P><B>Note:</B> The classname of a driver can be found using
371 * <CODE>d.getClass().getName()</CODE>
372 *
373 * @return the list of JDBC Drivers loaded by the caller's class loader
374 */
622 if (reason != null) {
623 println("getConnection failed: " + reason);
624 throw reason;
625 }
626
627 println("getConnection: no suitable driver found for "+ url);
628 throw new SQLException("No suitable driver found for "+ url, "08001");
629 }
630
631
632 }
633
634 /*
635 * Wrapper class for registered Drivers in order to not expose Driver.equals()
636 * to avoid the capture of the Driver it being compared to as it might not
637 * normally have access.
638 */
639 class DriverInfo {
640
641 final Driver driver;
642 DriverInfo(Driver driver) {
643 this.driver = driver;
644 }
645
646 @Override
647 public boolean equals(Object other) {
648 return (other instanceof DriverInfo)
649 && this.driver == ((DriverInfo) other).driver;
650 }
651
652 @Override
653 public int hashCode() {
654 return driver.hashCode();
655 }
656
657 @Override
658 public String toString() {
659 return ("driver[className=" + driver + "]");
660 }
661 }
|
93 private DriverManager(){}
94
95
96 /**
97 * Load the initial JDBC drivers by checking the System property
98 * jdbc.properties and then use the {@code ServiceLoader} mechanism
99 */
100 static {
101 loadInitialDrivers();
102 println("JDBC DriverManager initialized");
103 }
104
105 /**
106 * The <code>SQLPermission</code> constant that allows the
107 * setting of the logging stream.
108 * @since 1.3
109 */
110 final static SQLPermission SET_LOG_PERMISSION =
111 new SQLPermission("setLog");
112
113 /**
114 * The {@code SQLPermission} constant that allows the
115 * un-register a registered JDBC driver.
116 * @since 1.8
117 */
118 final static SQLPermission DEREGISTER_DRIVER_PERMISSION =
119 new SQLPermission("deregisterDriver");
120
121 //--------------------------JDBC 2.0-----------------------------
122
123 /**
124 * Retrieves the log writer.
125 *
126 * The <code>getLogWriter</code> and <code>setLogWriter</code>
127 * methods should be used instead
128 * of the <code>get/setlogStream</code> methods, which are deprecated.
129 * @return a <code>java.io.PrintWriter</code> object
130 * @see #setLogWriter
131 * @since 1.2
132 */
133 public static java.io.PrintWriter getLogWriter() {
134 return logWriter;
135 }
136
137 /**
138 * Sets the logging/tracing <code>PrintWriter</code> object
139 * that is used by the <code>DriverManager</code> and all drivers.
140 * <P>
300 // Success!
301 println("getDriver returning " + aDriver.driver.getClass().getName());
302 return (aDriver.driver);
303 }
304
305 } catch(SQLException sqe) {
306 // Drop through and try the next driver.
307 }
308 } else {
309 println(" skipping: " + aDriver.driver.getClass().getName());
310 }
311
312 }
313
314 println("getDriver: no suitable driver");
315 throw new SQLException("No suitable driver", "08001");
316 }
317
318
319 /**
320 * Registers the given driver with the {@code DriverManager}.
321 * A newly-loaded driver class should call
322 * the method {@code registerDriver} to make itself
323 * known to the {@code DriverManager}. If the driver had previously been
324 * registered, no action is taken.
325 *
326 * @param driver the new JDBC Driver that is to be registered with the
327 * {@code DriverManager}
328 * @exception SQLException if a database access error occurs
329 */
330 public static synchronized void registerDriver(java.sql.Driver driver)
331 throws SQLException {
332
333 registerDriver(driver, null);
334 }
335
336 /**
337 * Registers the given driver with the {@code DriverManager}.
338 * A newly-loaded driver class should call
339 * the method {@code registerDriver} to make itself
340 * known to the {@code DriverManager}. If the driver had previously been
341 * registered, no action is taken.
342 *
343 * @param driver the new JDBC Driver that is to be registered with the
344 * {@code DriverManager}
345 * @param da the {@code DriverAction} implementation to be used when
346 * {@code DriverManager#deregisterDriver} is called
347 * @exception SQLException if a database access error occurs
348 */
349 public static synchronized void registerDriver(java.sql.Driver driver,
350 DriverAction da)
351 throws SQLException {
352
353 /* Register the driver if it has not already been added to our list */
354 if(driver != null) {
355 registeredDrivers.addIfAbsent(new DriverInfo(driver, da));
356 } else {
357 // This is for compatibility with the original DriverManager
358 throw new NullPointerException();
359 }
360
361 println("registerDriver: " + driver);
362
363 }
364
365 /**
366 * Removes the specified driver from the {@code DriverManager}'s list of
367 * registered drivers.
368 * <p>
369 * If a {@code null} value is specified for the driver to be removed, then no
370 * action is taken.
371 * <p>
372 * If a security manager exists and its {@code checkPermission} denies
373 * permission, then a {@code SecurityException} will be thrown.
374 * <p>
375 * If the specified driver is not found in the list of registered drivers,
376 * then no action is taken. If the specified driver was found, then the
377 * driver's {@linkplain Driver#deregisterDriver deregisterDriver} method will
378 * be called to release any resources it may hold.
379 * <p>
380 * If a {@code DriverAction} instance was specified when the JDBC driver was
381 * registered, its deregister method will be called
382 * prior to the driver being removed from the list of registered drivers.
383 *
384 * @param driver the JDBC Driver to remove
385 * @exception SQLException if a database access error occurs
386 * @throws SecurityException if a security manager exists and its
387 * {@code checkPermission} method denies permission to deregister a driver.
388 *
389 * @see SecurityManager#checkPermission
390 * @see Driver#deregisterDriver
391 */
392 @CallerSensitive
393 public static synchronized void deregisterDriver(Driver driver)
394 throws SQLException {
395 if (driver == null) {
396 return;
397 }
398
399 SecurityManager sec = System.getSecurityManager();
400 if (sec != null) {
401 sec.checkPermission(DEREGISTER_DRIVER_PERMISSION);
402 }
403
404 println("DriverManager.deregisterDriver: " + driver);
405
406 DriverInfo aDriver = new DriverInfo(driver, null);
407 if(registeredDrivers.contains(aDriver)) {
408 if (isDriverAllowed(driver, Reflection.getCallerClass())) {
409 DriverInfo di = registeredDrivers.get(registeredDrivers.indexOf(aDriver));
410 // If a DriverAction was specified, Call it to notify the
411 // driver that it has been deregistered
412 if(di.action() != null) {
413 di.action().deregister();
414 }
415 registeredDrivers.remove(aDriver);
416 } else {
417 // If the caller does not have permission to load the driver then
418 // throw a SecurityException.
419 throw new SecurityException();
420 }
421 } else {
422 println(" couldn't find driver to unload");
423 }
424 }
425
426 /**
427 * Retrieves an Enumeration with all of the currently loaded JDBC drivers
428 * to which the current caller has access.
429 *
430 * <P><B>Note:</B> The classname of a driver can be found using
431 * <CODE>d.getClass().getName()</CODE>
432 *
433 * @return the list of JDBC Drivers loaded by the caller's class loader
434 */
682 if (reason != null) {
683 println("getConnection failed: " + reason);
684 throw reason;
685 }
686
687 println("getConnection: no suitable driver found for "+ url);
688 throw new SQLException("No suitable driver found for "+ url, "08001");
689 }
690
691
692 }
693
694 /*
695 * Wrapper class for registered Drivers in order to not expose Driver.equals()
696 * to avoid the capture of the Driver it being compared to as it might not
697 * normally have access.
698 */
699 class DriverInfo {
700
701 final Driver driver;
702 DriverAction da;
703 DriverInfo(Driver driver, DriverAction action) {
704 this.driver = driver;
705 da = action;
706 }
707
708 @Override
709 public boolean equals(Object other) {
710 return (other instanceof DriverInfo)
711 && this.driver == ((DriverInfo) other).driver;
712 }
713
714 @Override
715 public int hashCode() {
716 return driver.hashCode();
717 }
718
719 @Override
720 public String toString() {
721 return ("driver[className=" + driver + "]");
722 }
723
724 DriverAction action() {
725 return da;
726 }
727 }
|