home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 November / Chip_1998-11_cd.bin / tema / Cafe / main.bin / DriverManager.java < prev    next >
Text File  |  1997-05-20  |  15KB  |  425 lines

  1. /*
  2.  * @(#)DriverManager.java    1.5 97/02/11
  3.  * 
  4.  * Copyright (c) 1995, 1996 Sun Microsystems, Inc. All Rights Reserved.
  5.  * 
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not
  8.  * disclose such Confidential Information and shall use it only in
  9.  * accordance with the terms of the license agreement you entered into
  10.  * with Sun.
  11.  * 
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  15.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  16.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  17.  * THIS SOFTWARE OR ITS DERIVATIVES.
  18.  * 
  19.  * CopyrightVersion 1.1_beta
  20.  * 
  21.  */
  22.  
  23. package java.sql;
  24.  
  25. /**
  26.  * <P>The DriverManager provides a basic service for managing a set of
  27.  * JDBC drivers.
  28.  *
  29.  * <P>As part of its initialization, the DriverManager class will
  30.  * attempt to load the driver classes referenced in the "jdbc.drivers"
  31.  * system property. This allows a user to customize the JDBC Drivers
  32.  * used by their applications. For example in your
  33.  * ~/.hotjava/properties file you might specify:
  34.  * <CODE>jdbc.drivers=foo.bah.Driver:wombat.sql.Driver:bad.taste.ourDriver</CODE>
  35.  *
  36.  * A program can also explicitly load JDBC drivers at any time. For
  37.  * example, the my.sql.Driver is loaded with the following statement:
  38.  * <CODE>Class.forName("my.sql.Driver");</CODE>
  39.  *
  40.  * <P>When getConnection is called the DriverManager will attempt to
  41.  * locate a suitable driver from amongst those loaded at
  42.  * initialization and those loaded explicitly using the same classloader
  43.  * as the current applet or application.
  44.  *
  45.  * @see Driver
  46.  * @see Connection 
  47.  */
  48. public class DriverManager {
  49.  
  50.     /**
  51.      * Attempt to establish a connection to the given database URL.
  52.      * The DriverManager attempts to select an appropriate driver from
  53.      * the set of registered JDBC drivers.
  54.      *
  55.      * @param url a database url of the form jdbc:<em>subprotocol</em>:<em>subname</em>
  56.      * @param info a list of arbitrary string tag/value pairs as
  57.      * connection arguments; normally at least a "user" and
  58.      * "password" property should be included
  59.      * @return a Connection to the URL 
  60.      * @exception SQLException if a database-access error occurs.
  61.      */
  62.     public static synchronized Connection getConnection(String url, 
  63.             java.util.Properties info) throws SQLException {
  64.     if(url == null) {
  65.         throw new SQLException("The url cannot be null", "08001");
  66.     }
  67.  
  68.         println("DriverManager.getConnection(\"" + url + "\")");
  69.  
  70.         if (!initialized) {
  71.             initialize();
  72.         }
  73.  
  74.         // Figure out the current security context.
  75.         Object currentSecurityContext = getSecurityContext();
  76.  
  77.         // Walk through the loaded drivers attempting to make a connection.
  78.         // Remember the first exception that gets raised so we can reraise it.
  79.         SQLException reason = null;
  80.         for (int i = 0; i < drivers.size(); i++) {
  81.             DriverInfo di = (DriverInfo)drivers.elementAt(i);
  82.             // if the driver isn't part of the base system and doesn't come
  83.             // from the same security context as the current caller, skip it.
  84.             if (di.securityContext != null && 
  85.                         di.securityContext != currentSecurityContext) {
  86.                 println("    skipping: " + di);
  87.                 continue;
  88.             }
  89.             try {
  90.                 println("    trying " + di);
  91.                 Connection result = di.driver.connect(url, info);
  92.                 if (result != null) {
  93.                     // Success!
  94.                     println("getConnection returning " + di);
  95.                     return (result);
  96.                 }
  97.             } catch (SQLException ex) {
  98.                 if (reason == null) {
  99.                     reason = ex;
  100.                 }
  101.             }
  102.         }
  103.  
  104.         // if we got here nobody could connect.
  105.         if (reason != null)    {
  106.             println("getConnection failed: " + reason);
  107.             throw reason;
  108.         }
  109.  
  110.         println("getConnection: no suitable driver");
  111.         throw new SQLException("No suitable driver", "08001");
  112.     }
  113.  
  114.     /**
  115.      * Attempt to establish a connection to the given database URL.
  116.      * The DriverManager attempts to select an appropriate driver from
  117.      * the set of registered JDBC drivers.
  118.      *
  119.      * @param url a database url of the form jdbc:<em>subprotocol</em>:<em>subname</em>
  120.      * @param user the database user on whose behalf the Connection is being made
  121.      * @param password the user's password
  122.      * @return a Connection to the URL 
  123.      * @exception SQLException if a database-access error occurs.
  124.      */
  125.     public static synchronized Connection getConnection(String url, 
  126.                     String user, String password) throws SQLException {
  127.         java.util.Properties info = new java.util.Properties();
  128.     if (user != null) {
  129.         info.put("user", user);
  130.     }
  131.     if (password != null) {
  132.         info.put("password", password);
  133.     }
  134.         return (getConnection(url, info));
  135.     }
  136.  
  137.     /**
  138.      * Attempt to establish a connection to the given database URL.
  139.      * The DriverManager attempts to select an appropriate driver from
  140.      * the set of registered JDBC drivers.
  141.      *
  142.      * @param url a database url of the form jdbc:<em>subprotocol</em>:<em>subname</em>
  143.      * @return a Connection to the URL 
  144.      * @exception SQLException if a database-access error occurs.
  145.      */
  146.     public static synchronized Connection getConnection(String url) 
  147.                                     throws SQLException {
  148.         java.util.Properties info = new java.util.Properties();
  149.         return (getConnection(url, info));
  150.     }
  151.  
  152.     /**
  153.      * Attempt to locate a driver that understands the given URL.
  154.      * The DriverManager attempts to select an appropriate driver from
  155.      * the set of registered JDBC drivers. 
  156.      *
  157.      * @param url a database url of the form jdbc:<em>subprotocol</em>:<em>subname</em>
  158.      * @return a Driver that can connect to the URL 
  159.      * @exception SQLException if a database-access error occurs.
  160.      */
  161.     public static Driver getDriver(String url) throws SQLException {
  162.         println("DriverManager.getDriver(\"" + url + "\")");
  163.  
  164.         if (!initialized) {
  165.             initialize();
  166.         }
  167.  
  168.         // Figure out the current security context.
  169.         Object currentSecurityContext = getSecurityContext();
  170.  
  171.         // Walk through the loaded drivers attempting to locate someone
  172.     // who understands the given URL.
  173.         for (int i = 0; i < drivers.size(); i++) {
  174.             DriverInfo di = (DriverInfo)drivers.elementAt(i);
  175.             // If the driver isn't part of the base system and doesn't come
  176.             // from the same security context as the current caller, skip it.
  177.             if (di.securityContext != null && 
  178.                         di.securityContext != currentSecurityContext) {
  179.                 println("    skipping: " + di);
  180.                 continue;
  181.             }
  182.             try {
  183.                 println("    trying " + di);
  184.         if (di.driver.acceptsURL(url)) {
  185.             // Success!
  186.                     println("getDriver returning " + di);
  187.                     return (di.driver);
  188.                 }
  189.             } catch (SQLException ex) {
  190.         // Drop through and try the next driver.
  191.             }
  192.         }
  193.  
  194.         println("getDriver: no suitable driver");
  195.         throw new SQLException("No suitable driver", "08001");
  196.     }
  197.  
  198.  
  199.     /**
  200.      * A newly loaded driver class should call registerDriver to make itself
  201.      * known to the DriverManager.
  202.      *
  203.      * @param driver the new JDBC Driver 
  204.      * @exception SQLException if a database-access error occurs.
  205.      */
  206.     public static synchronized void registerDriver(java.sql.Driver driver)
  207.                         throws SQLException {
  208.         if (!initialized) {
  209.             initialize();
  210.         }
  211.         DriverInfo di = new DriverInfo();
  212.         di.driver = driver;
  213.         di.className = driver.getClass().getName();
  214.         // Note our current securityContext.
  215.         di.securityContext = getSecurityContext();
  216.         drivers.addElement(di);
  217.         println("registerDriver: " + di);
  218.     }
  219.  
  220.  
  221.     /**
  222.      * Drop a Driver from the DriverManager's list.  Applets can only
  223.      * deregister Drivers from their own classloader.
  224.      *
  225.      * @param driver the JDBC Driver to drop 
  226.      * @exception SQLException if a database-access error occurs.
  227.      */
  228.     public static void deregisterDriver(Driver driver) throws SQLException {
  229.         // Figure out the current security context.
  230.         Object currentSecurityContext = getSecurityContext();
  231.         println("DriverManager.deregisterDriver: " + driver);
  232.  
  233.         // Walk through the loaded drivers.
  234.         int i;
  235.         DriverInfo di = null;
  236.         for (i = 0; i < drivers.size(); i++) {
  237.             di = (DriverInfo)drivers.elementAt(i);
  238.             if (di.driver == driver) {
  239.                 break;
  240.             }
  241.         }
  242.         // If we can't find the driver just return.
  243.         if (i >= drivers.size()) {
  244.             println("    couldn't find driver to unload");
  245.             return;
  246.         }
  247.  
  248.             // If an applet is trying to free a driver from somewhere else
  249.         // throw a security exception.
  250.         if (currentSecurityContext != null &&
  251.                 di.securityContext != currentSecurityContext) {
  252.             throw new SecurityException();
  253.         }
  254.  
  255.         // Remove the driver.  Other entries in drivers get shuffled down.
  256.         drivers.removeElementAt(i);
  257.     
  258.     }
  259.  
  260.     /**
  261.      * Return an Enumeration of all the currently loaded JDBC drivers
  262.      * which the current caller has access to.
  263.      *
  264.      * <P><B>Note:</B> The classname of a driver can be found using
  265.      * <CODE>d.getClass().getName()</CODE>
  266.      *
  267.      * @return the list of JDBC Drivers loaded by the caller's class loader
  268.      */
  269.     public static java.util.Enumeration getDrivers() {
  270.         java.util.Vector result = new java.util.Vector();
  271.  
  272.         if (!initialized) {
  273.             initialize();
  274.         }
  275.  
  276.         // Figure out the current security context.
  277.         Object currentSecurityContext = getSecurityContext();
  278.  
  279.         // Walk through the loaded drivers.
  280.         for (int i = 0; i < drivers.size(); i++) {
  281.             DriverInfo di = (DriverInfo)drivers.elementAt(i);
  282.             // if the driver isn't part of the base system and doesn't come
  283.             // from the same security context as the current caller, skip it.
  284.             if (di.securityContext != null && 
  285.                         di.securityContext != currentSecurityContext) {
  286.                 println("    skipping: " + di);
  287.                 continue;
  288.             }
  289.             result.addElement(di.driver);
  290.         }
  291.  
  292.         return (result.elements());
  293.     }
  294.  
  295.  
  296.     /**
  297.      * Set the maximum time in seconds that all drivers can wait
  298.      * when attempting to log in to a database.
  299.      *
  300.      * @param seconds the driver login time limit
  301.      */
  302.     public static void setLoginTimeout(int seconds) {
  303.         loginTimeout = seconds;
  304.     }
  305.  
  306.     /**
  307.      * Get the maximum time in seconds that all drivers can wait
  308.      * when attempting to log in to a database.
  309.      *
  310.      * @return the driver login time limit
  311.      */
  312.     public static int getLoginTimeout() {
  313.         return (loginTimeout);
  314.     }
  315.  
  316.  
  317.     /**
  318.      * Set the logging/tracing PrintStream that is used by the DriverManager
  319.      * and all drivers.
  320.      *
  321.      * @param out the new logging/tracing PrintStream; to disable, set to null
  322.      */
  323.     public static void setLogStream(java.io.PrintStream out) {
  324.         logStream = out;
  325.     }
  326.  
  327.     /**
  328.      * Get the logging/tracing PrintStream that is used by the DriverManager
  329.      * and all drivers.
  330.      *
  331.      * @return the logging/tracing PrintStream; if disabled, is null
  332.      */
  333.     public static java.io.PrintStream getLogStream() {
  334.         return (logStream);
  335.     }
  336.  
  337.     /**
  338.      * Print a message to the current JDBC log stream
  339.      *
  340.      * @param message a log or tracing message
  341.      */
  342.     public static void println(String message) {
  343.         if (logStream != null) {
  344.             logStream.println(message);
  345.         }
  346.     }
  347.  
  348.     //-------------------------------------------------------------------------
  349.  
  350.     private static Object getSecurityContext() {
  351.         // Get the securityContext for our caller.  For applets this
  352.         // will be the applet classloader base URL.
  353.         SecurityManager security = System.getSecurityManager();    
  354.         if (security == null) {
  355.             return (null);
  356.         }
  357.         return (security.getSecurityContext());
  358.     }
  359.  
  360.     private static void loadInitialDrivers() {
  361.         String drivers;
  362.         try {
  363.             drivers = System.getProperty("jdbc.drivers");
  364.         } catch (Exception ex) {
  365.             drivers = null;
  366.         }
  367.         println("DriverManager.initialize: jdbc.drivers = " + drivers);
  368.         if (drivers == null) {
  369.             return;
  370.         }
  371.         while (drivers.length() != 0) {
  372.             int x = drivers.indexOf(':');
  373.             String driver;
  374.             if (x < 0) {
  375.                 driver = drivers;
  376.                 drivers = "";
  377.             } else {
  378.                 driver = drivers.substring(0, x);
  379.                 drivers = drivers.substring(x+1);
  380.             }
  381.             if (driver.length() == 0) {
  382.                 continue;
  383.             }
  384.             try {
  385.                 println("DriverManager.Initialize: loading " + driver);
  386.                 Class.forName(driver);
  387.             } catch (Exception ex) {
  388.                 println("DriverManager.Initialize: load failed: " + ex);
  389.             }
  390.         }
  391.     }
  392.  
  393.     // Class initialization.
  394.     static void initialize() {
  395.         if (initialized) {
  396.             return;
  397.         }
  398.         initialized = true;
  399.         loadInitialDrivers();
  400.         println("JDBC DriverManager initialized");
  401.     }
  402.  
  403.     // Prevent the DriverManager class from being instantiated.
  404.     private DriverManager(){}
  405.  
  406.     private static java.util.Vector drivers = new java.util.Vector();
  407.     private static int loginTimeout = 0;
  408.     private static java.io.PrintStream logStream = null;
  409.     private static boolean initialized = false;
  410.  
  411. }
  412.  
  413.  
  414. // DriverInfo is a package-private support class.
  415. class DriverInfo {
  416.     Driver         driver;
  417.     Object        securityContext;
  418.     String        className;
  419.  
  420.     public String toString() {
  421.         return ("driver[className=" + className + ",context=" +
  422.         securityContext + "," + driver + "]");
  423.     }
  424. }
  425.