/***************************************************************** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. ****************************************************************/ package org.apache.cayenne.datasource; import java.io.PrintWriter; import java.sql.Connection; import java.sql.Driver; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.util.Properties; import javax.sql.DataSource; import org.apache.cayenne.CayenneRuntimeException; import org.apache.cayenne.util.Util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * A non-pooling DataSource implementation wrapping a JDBC driver. */ public class DriverDataSource implements DataSource { private static final Logger LOGGER = LoggerFactory.getLogger(DriverDataSource.class); protected Driver driver; protected String connectionUrl; protected String userName; protected String password; /** * Loads JDBC driver using current thread class loader. * * @since 3.0 * @deprecated since 4.0 as class loading should not happen here. */ @Deprecated private static Driver loadDriver(String driverClassName) { Class<?> driverClass; try { driverClass = Util.getJavaClass(driverClassName); } catch (Exception ex) { throw new CayenneRuntimeException("Can not load JDBC driver named '%s': %s", driverClassName, ex.getMessage()); } try { return (Driver) driverClass.newInstance(); } catch (Exception ex) { throw new CayenneRuntimeException("Error instantiating driver '%s': %s", driverClassName, ex.getMessage()); } } /** * Creates a new DriverDataSource. If "driverClassName" is null, * DriverDataSource will consult DriverManager for a registered driver for * the given URL. So when specifying null, a user must take care of * registering the driver. "connectionUrl" on the other hand must NOT be * null. * * @deprecated since 4.0 as class loading should not happen here. Use { * {@link #DriverDataSource(Driver, String, String, String)}. */ @Deprecated public DriverDataSource(String driverClassName, String connectionUrl) { this(driverClassName, connectionUrl, null, null); } /** * Creates a new DriverDataSource. If "driverClassName" is null, * DriverDataSource will consult DriverManager for a registered driver for * the given URL. So when specifying null, a user must take care of * registering the driver. "connectionUrl" on the other hand must NOT be * null. * * @deprecated since 4.0 as class loading should not happen here. Use * {@link #DriverDataSource(Driver, String, String, String)}. */ @Deprecated public DriverDataSource(String driverClassName, String connectionUrl, String userName, String password) { this(loadDriver(driverClassName), connectionUrl, userName, password); } /** * Creates a DriverDataSource wrapping a given Driver. If "driver" is null, * DriverDataSource will consult DriverManager for a registered driver for * the given URL. So when specifying null, a user must take care of * registering the driver. "connectionUrl" on the other hand must NOT be * null. * * @since 1.1 */ public DriverDataSource(Driver driver, String connectionUrl, String userName, String password) { if (connectionUrl == null) { throw new NullPointerException("Null 'connectionUrl'"); } this.driver = driver; this.connectionUrl = connectionUrl; this.userName = userName; this.password = password; } /** * Returns a new database connection, using preconfigured data to locate the * database and obtain a connection. */ @Override public Connection getConnection() throws SQLException { // login with internal credentials return getConnection(userName, password); } /** * Returns a new database connection using provided credentials to login to * the database. */ @Override public Connection getConnection(String userName, String password) throws SQLException { try { logConnect(connectionUrl, userName, password); Connection c = null; if (driver == null) { c = DriverManager.getConnection(connectionUrl, userName, password); } else { Properties connectProperties = new Properties(); if (userName != null) { connectProperties.put("user", userName); } if (password != null) { connectProperties.put("password", password); } c = driver.connect(connectionUrl, connectProperties); } // some drivers (Oracle) return null connections instead of throwing // an exception... fix it here if (c == null) { throw new SQLException("Can't establish connection: " + connectionUrl); } LOGGER.info("+++ Connecting: SUCCESS."); return c; } catch (SQLException ex) { LOGGER.info("*** Connecting: FAILURE.", ex); throw ex; } } private void logConnect(String url, String userName, String password) { if (LOGGER.isInfoEnabled()) { StringBuilder buf = new StringBuilder("Connecting to '").append(url).append("' as '").append(userName) .append("'"); LOGGER.info(buf.toString()); } } @Override public int getLoginTimeout() throws SQLException { return -1; } @Override public void setLoginTimeout(int seconds) throws SQLException { // noop } @Override public PrintWriter getLogWriter() throws SQLException { return DriverManager.getLogWriter(); } @Override public void setLogWriter(PrintWriter out) throws SQLException { DriverManager.setLogWriter(out); } /** * @since 3.0 * @deprecated since 4.0. Connection parameters are immutable and not * readable. */ @Deprecated public String getConnectionUrl() { return connectionUrl; } /** * @since 3.0 * @deprecated since 4.0. Connection parameters are immutable. */ @Deprecated public void setConnectionUrl(String connectionUrl) { this.connectionUrl = connectionUrl; } /** * @since 3.0 * @deprecated since 4.0. Connection parameters are immutable and not * readable. */ @Deprecated public String getPassword() { return password; } /** * @deprecated since 4.0. Connection parameters are immutable. * @since 3.0 */ @Deprecated public void setPassword(String password) { this.password = password; } /** * @since 3.0 * @deprecated since 4.0. Connection parameters are immutable and not * readable. */ @Deprecated public String getUserName() { return userName; } /** * @since 3.0 * @deprecated since 4.0. Connection parameters are immutable. */ @Deprecated public void setUserName(String userName) { this.userName = userName; } /** * @since 3.0 */ @Override public boolean isWrapperFor(Class<?> iface) throws SQLException { throw new UnsupportedOperationException(); } /** * @since 3.0 */ @Override public <T> T unwrap(Class<T> iface) throws SQLException { throw new UnsupportedOperationException(); } /** * @since 3.1 */ @Override public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException { throw new UnsupportedOperationException(); } }