001: /*
002: * Copyright (C) 2005 - 2008 JasperSoft Corporation. All rights reserved.
003: * http://www.jaspersoft.com.
004: *
005: * Unless you have purchased a commercial license agreement from JasperSoft,
006: * the following license terms apply:
007: *
008: * This program is free software; you can redistribute it and/or modify
009: * it under the terms of the GNU General Public License version 2 as published by
010: * the Free Software Foundation.
011: *
012: * This program is distributed WITHOUT ANY WARRANTY; and without the
013: * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
014: * See the GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, see http://www.gnu.org/licenses/gpl.txt
018: * or write to:
019: *
020: * Free Software Foundation, Inc.,
021: * 59 Temple Place - Suite 330,
022: * Boston, MA USA 02111-1307
023: *
024: *
025: *
026: *
027: * DriverPool.java
028: *
029: * Created on 25 maggio 2004, 16.34
030: *
031: */
032:
033: package it.businesslogic.ireport.connection;
034:
035: /*
036: * Copyright 2002 by Mark A. Kobold
037: *
038: * The contents of this file are subject to the Mozilla Public License Version 1.1
039: * (the "License"); you may not use this file except in compliance with the License.
040: * You may obtain a copy of the License at http://www.mozilla.org/MPL/
041: *
042: * Software distributed under the License is distributed on an "AS IS" basis,
043: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
044: * for the specific language governing rights and limitations under the License.
045: *
046: * The Original Code is iSQL-Viewer, A Mutli-Platform Database Tool.
047: *
048: * The Initial Developer of the Original Code is Markus A. Kobold.
049: *
050: * Portions created by Mark A. Kobold are
051: * Copyright (C) Copyright (C) 2000 Mark A. Kobold. All Rights Reserved.
052: * Contributor(s): Mark A. Kobold <mkobold@sprintpcs.com>.
053: *
054: * Contributor(s): all the names of the contributors are added in the source code
055: * where applicable.
056: *
057: * If you didn't download this code from the following link, you should check if
058: * you aren't using an obsolete version:
059: * http://isql.sourceforge.net/
060: */
061: import java.sql.Driver;
062: import java.sql.SQLException;
063: import java.util.ArrayList;
064: import java.util.Iterator;
065:
066: /**
067: * Utility object for loading and pooling JDBC drivers.
068: * <p>
069: * This class was originally embedded into the DatabaseConnection object, it has
070: * been moved out for clarity. The main goal of this class is to provide a few of the
071: * same functions provided java.sql.DriverManager object but in a way that is better
072: * suited for the iSQL-Viewer program.
073: * <p>
074: * The main shortcoming of the java.sql.DriverManager is that the driver manager
075: * will not allow you to use a registered driver that was loaded with a different
076: * classloader than classloader from the calling class. Basically in short terms
077: * the default DriverManager really only seems to work when all the code and JDBC
078: * drivers are from the same classloader, which doesn't work with the iSQL-Viewer
079: * system since there are runtime and classloader for each ServiceDefinition object.
080: *
081: * @see java.sql.DriverManager
082: * @author Markus A. Kobold <mkobold at sprintpcs dot com>
083: */
084: public final class DriverPool {
085: private DriverPool() {
086:
087: }
088:
089: // This is a collection of Driver Objects that are registered through the
090: // RegisterDriver method.
091: private static final ArrayList driverSet = new ArrayList();
092:
093: /**
094: * Check method to ensure we don't have multiple instances of the same
095: * driver.
096: * <p>
097: * If the Major version and the Minors version of the Driver plus the class
098: * names are the same the the driver will be considerd all ready
099: * registered.
100: * <p>
101: * This method is generally called from the registerDriver() method.
102: *
103: * @param jdbcDriver Driver Instance to check.
104: * @return true if similar class is registered
105: * @see #registerDriver(String, ClassLoader)
106: */
107: private static boolean isDriverAllReadyRegistered(Driver jdbcDriver) {
108: int verCheckSum = (jdbcDriver.getMajorVersion() * 10)
109: + jdbcDriver.getMinorVersion();
110: Iterator drivers = driverSet.iterator();
111: while (drivers.hasNext()) {
112: Driver driver = (Driver) drivers.next();
113: int checkSum = (driver.getMajorVersion() * 10)
114: + driver.getMinorVersion();
115: if (checkSum == verCheckSum
116: && (driver.getClass().getName().equals(jdbcDriver
117: .getClass().getName())))
118: return true;
119: }
120: return false;
121: }
122:
123: /**
124: * Simple Driver registration method.
125: * <p>
126: * To overcome the security configuration of the java.sql.DriverManager
127: * object this method provides simple instantiation of the given driver by
128: * class name with a given ClassLoader. The java.sql.DriverManager works
129: * really only if all classes are under the same ClassLoader, for most
130: * cases this is not allways an option.
131: * <p>
132: * If a Driver is all ready registered this method will actually do
133: * nothing.
134: *
135: * @param driverClass the fully qaulified name of the Driver e.g.
136: * 'org.my.sql.Driver'
137: * @param cl ClassLoader to try and load the Driver with.
138: * @throws ClassNotFoundException if an Error Occurs with creating the
139: * Driver instance.
140: * @see #deregisterDriver(Driver)
141: * @see #getDriver(String)
142: */
143: public static void registerDriver(String driverClass, ClassLoader cl)
144: throws ClassNotFoundException {
145: if (cl == null)
146: cl = Thread.currentThread().getContextClassLoader();
147:
148: if (driverClass == null)
149: return;
150:
151: try {
152: Driver jdbcDriver = (Driver) Class.forName(driverClass,
153: false, cl).newInstance();
154: if (!isDriverAllReadyRegistered(jdbcDriver)) {
155: synchronized (driverSet) {
156: driverSet.add(jdbcDriver);
157: }
158: String[] p = new String[] { driverClass,
159: jdbcDriver.toString() };
160:
161: }
162: } catch (Throwable t) {
163: throw new ClassNotFoundException(driverClass);
164: }
165: }
166:
167: /**
168: * Deregisters JDBC Driver object by refrence.
169: * <p>
170: * This will search through all registered drivers and remove the driver if
171: * the object refrences are the same.
172: *
173: * @param jdbcDriver Driver Object that needs to be deregistered.
174: * @see #registerDriver(String,ClassLoader)
175: */
176: public static void deregisterDriver(Driver jdbcDriver) {
177: if (jdbcDriver == null) {
178: return;
179: }
180:
181: try {
182:
183: String[] p = new String[] {
184: jdbcDriver.getClass().getName(),
185: jdbcDriver.toString() };
186: synchronized (driverSet) {
187: int i = 0;
188: for (i = 0; i < driverSet.size(); i++) {
189: Driver di = (Driver) driverSet.get(i);
190: if (di == jdbcDriver) {
191: break;
192: }
193: }
194:
195: // If we can't find the driver just return.
196: if (i >= driverSet.size()) {
197: return;
198: }
199:
200: driverSet.remove(i);
201: }
202: } catch (Throwable t) {
203: t.printStackTrace();
204: }
205: }
206:
207: /**
208: * Retrieval method for getting a driver by URL.
209: * <p>
210: * This will iterate through all registered drivers and if the value
211: * returned by the acceptsURL() of the driver is true then the driver is
212: * returned.
213: * <p>
214: * if all internally registered drivers fail against the URL then an
215: * attempt to fall back to the original DriverManager and attempt to
216: * retrieve a driver from there will be made.
217: *
218: * @param jdbcURL URL of JDBC Connection
219: * @return Instance of the JDBC Driver that can accept the given URL
220: * @throws SQLException if the java.sql.DriverManager fallback fails.
221: */
222: public static Driver getDriver(String jdbcURL) throws SQLException {
223: Iterator drivers = driverSet.iterator();
224: while (drivers.hasNext()) {
225: Driver jdbcDriver = (Driver) drivers.next();
226: try {
227: if (jdbcDriver.acceptsURL(jdbcURL))
228: return jdbcDriver;
229: } catch (Throwable t) {
230: }
231:
232: }
233: return null; //DriverPool.getDriver(jdbcURL);
234: }
235:
236: }
|