Java tutorial
/** * Copyright 2014 www.migratebird.com * * Licensed 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 com.migratebird.datasource; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.migratebird.database.DatabaseException; import com.migratebird.database.DatabaseInfo; /** * Factory class for a very simple DataSource that provides access to a database without any connection pooling facilities. * Only the parameterless getConnection() method is implemented. */ public class SimpleDataSource { /* The logger instance for this class */ private static final Log logger = LogFactory.getLog(SimpleDataSource.class); /** * Static factory that returns a data source providing access to the database using the driver with the given driver * class name, the given connection url, user name and password * * @param databaseInfo The database connection parameters, not null * @return a DataSource that gives access to the database */ public static DataSource createDataSource(DatabaseInfo databaseInfo) { String driverClassName = databaseInfo.getDriverClassName(); String url = databaseInfo.getUrl(); String userName = databaseInfo.getUserName(); String password = databaseInfo.getPassword(); logger.info("Creating data source. Driver: " + driverClassName + ", url: " + url + ", user: " + userName + ", password: <not shown>"); return (DataSource) Proxy.newProxyInstance(SimpleDataSource.class.getClassLoader(), new Class<?>[] { DataSource.class }, new SimpleDataSourceInvocationHandler(driverClassName, url, userName, password)); } /** * Invocation handler for a dynamic proxy that implements the javax.sql.DataSource interface. This invocation handler * implements the getConnection method: this method will create a new database connection to the database configured * with the driverClassName, url, userName and password given with the constructor invocation. */ protected static class SimpleDataSourceInvocationHandler implements InvocationHandler { private String driverClassName; private String url; private String userName; private String password; protected SimpleDataSourceInvocationHandler(String driverClassName, String url, String userName, String password) { this.driverClassName = driverClassName; this.url = url; this.userName = userName; this.password = password; } /** * Handles all invocations on the DataSource. We only implement the parameterless getConnection method, since this * is the only method used in migratebird * * @param dataSourceProxy The proxy that represents the datasource * @param method The method invoked on the datasource * @param args The arguments of the invoked method * @return The return object * @throws Throwable */ @Override public Object invoke(Object dataSourceProxy, Method method, Object[] args) throws Throwable { if (isEqualsMethod(method)) { return dataSourceProxy == args[0]; } else if (isHashCodeMethod(method)) { // We simply use the hashcode of the invocation handler return hashCode(); } else if (isParameterLessGetConnectionMethod(method)) { return getDatabaseConnection(); } return null; } /** * @return A connection to the database */ protected Connection getDatabaseConnection() { try { Class.forName(driverClassName); } catch (ClassNotFoundException e) { throw new DatabaseException( "Unable to connect to database. Driver class not found: " + driverClassName, e); } try { return DriverManager.getConnection(url, userName, password); } catch (SQLException e) { throw new DatabaseException( "Unable to connect to database. Could not create connection for database url: " + url + ", user name: " + userName + ", password: <not shown>", e); } } /** * @param method The invoked method * @return Whether the given method is the equals method */ protected boolean isEqualsMethod(Method method) { return "equals".equals(method.getName()) && method.getParameterTypes().length == 1 && Object.class.equals(method.getParameterTypes()[0]); } /** * @param method The invoked method * @return Whether the given method is the hashCode method */ protected boolean isHashCodeMethod(Method method) { return "hashCode".equals(method.getName()) && method.getParameterTypes().length == 0; } /** * @param method The method invoked on the datasource proxy * @return whether the given method is the method DataSource.getConnection() */ protected boolean isParameterLessGetConnectionMethod(Method method) { return "getConnection".equals(method.getName()) && method.getParameterTypes().length == 0; } } }