# HG changeset patch # Parent a117529cd2c5c0677b0fc25b1ecf819cb37d21fd diff --git a/db/src/org/netbeans/modules/db/explorer/DbDriverManager.java b/db/src/org/netbeans/modules/db/explorer/DbDriverManager.java --- a/db/src/org/netbeans/modules/db/explorer/DbDriverManager.java +++ b/db/src/org/netbeans/modules/db/explorer/DbDriverManager.java @@ -44,12 +44,15 @@ package org.netbeans.modules.db.explorer; + +import java.net.URL; import java.sql.Connection; import java.sql.Driver; import java.sql.DriverManager; import java.sql.SQLException; import java.util.HashSet; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; @@ -57,6 +60,9 @@ import java.util.logging.Level; import java.util.logging.Logger; import org.netbeans.api.db.explorer.JDBCDriver; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; +import org.openide.util.Utilities; /** * Class to load drivers and create connections. It can find drivers and connections from @@ -223,15 +229,80 @@ */ public Driver getDriver(JDBCDriver jdbcDriver) throws SQLException { ClassLoader l = getClassLoader(jdbcDriver); + Object driver; try { - return (Driver)Class.forName(jdbcDriver.getClassName(), true, l).newInstance(); + driver = Class.forName(jdbcDriver.getClassName(), true, l).newInstance(); } catch (Exception e) { SQLException sqlex = createDriverNotFoundException(); sqlex.initCause(e); throw sqlex; } + if (driver instanceof Driver) { + return (Driver) driver; + } else if (driver instanceof javax.sql.CommonDataSource) { + Driver d = findDriverInMetaInfServices(l, jdbcDriver); + if (d != null) { + return d; + } else { + throw createDriverNotFoundException(); + } + } else { + throw createDriverNotFoundException(); + } } - + + /** + * Check whether there is a java.sql.Driver specified in META-INF/services, + * and if so, try to create it. + * + * @return The Driver, or null if it is not specified or cannot be created. + */ + private Driver findDriverInMetaInfServices(ClassLoader loader, + JDBCDriver jdbcDriver) { + String className = findSpecifiedDriverClassName(jdbcDriver); + try { + Driver realDriver = (Driver) Class.forName( + className, true, loader).newInstance(); + LOGGER.log(Level.INFO, + "Class {0} is not valid driver." //NOI18N + + " Using {1} instead", //NOI18N + new Object[]{jdbcDriver.getClassName(), className}); + return realDriver; + } catch (Exception e) { + LOGGER.log(Level.FINE, null, e); + return null; + } + } + + /** + * Find JDBC Driver class name as specified in driver JAR file. + */ + private String findSpecifiedDriverClassName(JDBCDriver jdbcDriver) { + String className = null; + URL[] urls = jdbcDriver.getURLs(); + for (URL url : urls) { + if (url != null) { + if (FileUtil.isArchiveFile(url)) { + try { + FileObject archiveFile = FileUtil.toFileObject( + Utilities.toFile(url.toURI())); + FileObject root = FileUtil.getArchiveRoot(archiveFile); + FileObject servicesDriver = root.getFileObject( + "META-INF/services/java.sql.Driver"); //NOI18N + List lines = servicesDriver.asLines(); + if (!lines.isEmpty() && !lines.get(0).trim().isEmpty()) { + className = lines.get(0).trim(); + break; + } + } catch (Exception e) { + LOGGER.log(Level.FINE, null, e); + } + } + } + } + return className; + } + /** * Gets a driver, but can skip DriverManager and doesn't throw SQLException if a driver can't be found. */