1f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License.  You may obtain a copy of the License at
8f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.sql;
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2003c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughesimport dalvik.system.VMStack;
2103c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughesimport java.io.PrintStream;
2203c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughesimport java.io.PrintWriter;
23142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilsonimport java.util.ArrayList;
242feeee4119506ed1511942f80fc2f7eb431afab7Elliott Hughesimport java.util.Collections;
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Enumeration;
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Iterator;
2703c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughesimport java.util.List;
2803c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughesimport java.util.Properties;
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Provides facilities for managing JDBC drivers.
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p>
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The {@code DriverManager} class loads JDBC drivers during its initialization,
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * from the list of drivers referenced by the system property {@code
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * "jdbc.drivers"}.
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class DriverManager {
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /*
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Facilities for logging. The Print Stream is deprecated but is maintained
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * here for compatibility.
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static PrintStream thePrintStream;
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static PrintWriter thePrintWriter;
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Login timeout value - by default set to 0 -> "wait forever"
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static int loginTimeout = 0;
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /*
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Set to hold Registered Drivers - initial capacity 10 drivers (will expand
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * automatically if necessary.
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
54142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson    private static final List<Driver> theDrivers = new ArrayList<Driver>(10);
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Permission for setting log
5703c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes    private static final SQLPermission logPermission = new SQLPermission("setLog");
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /*
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Load drivers on initialization
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static {
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        loadInitialDrivers();
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /*
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Loads the set of JDBC drivers defined by the Property "jdbc.drivers" if
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * it is defined.
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static void loadInitialDrivers() {
71ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes        String theDriverList = System.getProperty("jdbc.drivers", null);
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (theDriverList == null) {
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /*
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Get the names of the drivers as an array of Strings from the system
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * property by splitting the property at the separator character ':'
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
8003c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes        String[] theDriverNames = theDriverList.split(":");
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (String element : theDriverNames) {
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // Load the driver class
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Class
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        .forName(element, true, ClassLoader
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                .getSystemClassLoader());
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch (Throwable t) {
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // Ignored
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /*
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * A private constructor to prevent allocation
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private DriverManager() {
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Removes a driver from the {@code DriverManager}'s registered driver list.
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This will only succeed when the caller's class loader loaded the driver
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * that is to be removed. If the driver was loaded by a different class
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * loader, the removal of the driver fails silently.
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * If the removal succeeds, the {@code DriverManager} will not use this
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * driver in the future when asked to get a {@code Connection}.
108142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson     *
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param driver
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the JDBC driver to remove.
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SQLException
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if there is a problem interfering with accessing the
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             database.
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static void deregisterDriver(Driver driver) throws SQLException {
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (driver == null) {
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ClassLoader callerClassLoader = VMStack.getCallingClassLoader();
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!DriverManager.isClassFromClassLoader(driver, callerClassLoader)) {
12103c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes            throw new SecurityException("calling class not authorized to deregister JDBC driver");
12203c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes        }
123142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson        synchronized (theDrivers) {
124142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson            theDrivers.remove(driver);
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Attempts to establish a connection to the given database URL.
130f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param url
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            a URL string representing the database target to connect with.
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a {@code Connection} to the database identified by the URL.
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code null} if no connection can be established.
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SQLException
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if there is an error while attempting to connect to the
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             database identified by the URL.
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static Connection getConnection(String url) throws SQLException {
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return getConnection(url, new Properties());
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Attempts to establish a connection to the given database URL.
145f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param url
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            a URL string representing the database target to connect with
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param info
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            a set of properties to use as arguments to set up the
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            connection. Properties are arbitrary string/value pairs.
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            Normally, at least the properties {@code "user"} and {@code
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            "password"} should be passed, with appropriate settings for
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the user ID and its corresponding password to get access to
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the corresponding database.
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a {@code Connection} to the database identified by the URL.
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code null} if no connection can be established.
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SQLException
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if there is an error while attempting to connect to the
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             database identified by the URL.
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
16103c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes    public static Connection getConnection(String url, Properties info) throws SQLException {
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // 08 - connection exception
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // 001 - SQL-client unable to establish SQL-connection
16403c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes        String sqlState = "08001";
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (url == null) {
16603c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes            throw new SQLException("The url cannot be null", sqlState);
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
168142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson        synchronized (theDrivers) {
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            /*
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project             * Loop over the drivers in the DriverSet checking to see if one can
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project             * open a connection to the supplied URL - return the first
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project             * connection which is returned
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project             */
174142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson            for (Driver theDriver : theDrivers) {
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Connection theConnection = theDriver.connect(url, info);
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (theConnection != null) {
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return theConnection;
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // If we get here, none of the drivers are able to resolve the URL
18203c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes        throw new SQLException("No suitable driver", sqlState);
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Attempts to establish a connection to the given database URL.
187f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param url
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            a URL string representing the database target to connect with.
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param user
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            a user ID used to login to the database.
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param password
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            a password for the user ID to login to the database.
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a {@code Connection} to the database identified by the URL.
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code null} if no connection can be established.
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SQLException
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if there is an error while attempting to connect to the
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             database identified by the URL.
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
200b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes    public static Connection getConnection(String url, String user, String password)
201b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes            throws SQLException {
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Properties theProperties = new Properties();
203b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes        if (user != null) {
20403c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes            theProperties.setProperty("user", user);
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
206b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes        if (password != null) {
20703c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes            theProperties.setProperty("password", password);
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return getConnection(url, theProperties);
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Tries to find a driver that can interpret the supplied URL.
214f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param url
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the URL of a database.
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a {@code Driver} that matches the provided URL. {@code null} if
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         no {@code Driver} understands the URL
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SQLException
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if there is any kind of problem accessing the database.
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static Driver getDriver(String url) throws SQLException {
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ClassLoader callerClassLoader = VMStack.getCallingClassLoader();
224142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson        synchronized (theDrivers) {
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            /*
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project             * Loop over the drivers in the DriverSet checking to see if one
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project             * does understand the supplied URL - return the first driver which
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project             * does understand the URL
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project             */
230fb0ec0e650bf8be35acb0d47da0311a7c446aa33Elliott Hughes            for (Driver driver : theDrivers) {
231fb0ec0e650bf8be35acb0d47da0311a7c446aa33Elliott Hughes                if (driver.acceptsURL(url) &&
232fb0ec0e650bf8be35acb0d47da0311a7c446aa33Elliott Hughes                        DriverManager.isClassFromClassLoader(driver, callerClassLoader)) {
233fb0ec0e650bf8be35acb0d47da0311a7c446aa33Elliott Hughes                    return driver;
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // If no drivers understand the URL, throw an SQLException
238142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson        // SQLState: 08 - connection exception
239142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson        // 001 - SQL-client unable to establish SQL-connection
24003c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes        throw new SQLException("No suitable driver", "08001");
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns an {@code Enumeration} that contains all of the loaded JDBC
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * drivers that the current caller can access.
246f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return An {@code Enumeration} containing all the currently loaded JDBC
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code Drivers}.
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static Enumeration<Driver> getDrivers() {
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /*
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Synchronize to avoid clashes with additions and removals of drivers
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * in the DriverSet
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
2552feeee4119506ed1511942f80fc2f7eb431afab7Elliott Hughes        ClassLoader callerClassLoader = VMStack.getCallingClassLoader();
256142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson        synchronized (theDrivers) {
2572feeee4119506ed1511942f80fc2f7eb431afab7Elliott Hughes            ArrayList<Driver> result = new ArrayList<Driver>();
2582feeee4119506ed1511942f80fc2f7eb431afab7Elliott Hughes            for (Driver driver : theDrivers) {
2592feeee4119506ed1511942f80fc2f7eb431afab7Elliott Hughes                if (DriverManager.isClassFromClassLoader(driver, callerClassLoader)) {
2602feeee4119506ed1511942f80fc2f7eb431afab7Elliott Hughes                    result.add(driver);
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2632feeee4119506ed1511942f80fc2f7eb431afab7Elliott Hughes            return Collections.enumeration(result);
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the login timeout when connecting to a database in seconds.
269f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the login timeout in seconds.
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static int getLoginTimeout() {
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return loginTimeout;
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the log {@code PrintStream} used by the {@code DriverManager} and
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * all the JDBC Drivers.
279142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson     *
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @deprecated use {@link #getLogWriter()} instead.
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the {@code PrintStream} used for logging activities.
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Deprecated
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static PrintStream getLogStream() {
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return thePrintStream;
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Retrieves the log writer.
290f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return A {@code PrintWriter} object used as the log writer. {@code null}
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         if no log writer is set.
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static PrintWriter getLogWriter() {
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return thePrintWriter;
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Prints a message to the current JDBC log stream. This is either the
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code PrintWriter} or (deprecated) the {@code PrintStream}, if set.
301f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param message
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the message to print to the JDBC log stream.
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static void println(String message) {
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (thePrintWriter != null) {
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            thePrintWriter.println(message);
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            thePrintWriter.flush();
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else if (thePrintStream != null) {
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            thePrintStream.println(message);
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            thePrintStream.flush();
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /*
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * If neither the PrintWriter not the PrintStream are set, then silently
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * do nothing the message is not recorded and no exception is generated.
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Registers a given JDBC driver with the {@code DriverManager}.
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * A newly loaded JDBC driver class should register itself with the
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code DriverManager} by calling this method.
324142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson     *
325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param driver
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code Driver} to register with the {@code DriverManager}.
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SQLException
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if a database access error occurs.
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static void registerDriver(Driver driver) throws SQLException {
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (driver == null) {
33286acc043d3334651ee26c65467d78d6cefedd397Kenny Root            throw new NullPointerException("driver == null");
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
334142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson        synchronized (theDrivers) {
335142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson            theDrivers.add(driver);
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the login timeout when connecting to a database in seconds.
341f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param seconds
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            seconds until timeout. 0 indicates wait forever.
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static void setLoginTimeout(int seconds) {
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        loginTimeout = seconds;
347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the print stream to use for logging data from the {@code
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * DriverManager} and the JDBC drivers.
352142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson     *
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @deprecated Use {@link #setLogWriter} instead.
354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param out
355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code PrintStream} to use for logging.
356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Deprecated
358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static void setLogStream(PrintStream out) {
359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        thePrintStream = out;
360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the {@code PrintWriter} that is used by all loaded drivers, and also
364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the {@code DriverManager}.
365f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param out
367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code PrintWriter} to be used.
368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static void setLogWriter(PrintWriter out) {
370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        thePrintWriter = out;
371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Determines whether the supplied object was loaded by the given {@code ClassLoader}.
375f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param theObject
377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the object to check.
378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param theClassLoader
379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code ClassLoader}.
380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the Object does belong to the {@code ClassLoader}
381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         , {@code false} otherwise
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static boolean isClassFromClassLoader(Object theObject,
384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ClassLoader theClassLoader) {
385142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson
386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((theObject == null) || (theClassLoader == null)) {
387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
389142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson
390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Class<?> objectClass = theObject.getClass();
391142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson
392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Class<?> checkClass = Class.forName(objectClass.getName(), true,
394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    theClassLoader);
395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (checkClass == objectClass) {
396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return true;
397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (Throwable t) {
399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Empty
400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
404