/* * HA-JDBC: High-Availability JDBC * Copyright (C) 2014 Paul Ferraro * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package net.sf.hajdbc.sql; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.beans.PropertyEditor; import java.beans.PropertyEditorManager; import java.lang.reflect.InvocationTargetException; import java.sql.SQLException; import java.util.Properties; import javax.sql.CommonDataSource; import net.sf.hajdbc.Database; import net.sf.hajdbc.Locality; import net.sf.hajdbc.messages.Messages; import net.sf.hajdbc.messages.MessagesFactory; public abstract class CommonDataSourceDatabaseBuilder<Z extends CommonDataSource, D extends Database<Z>> extends AbstractDatabaseBuilder<Z, D> { private static final Messages messages = MessagesFactory.getMessages(); private final Class<Z> dataSourceClass; public CommonDataSourceDatabaseBuilder(String id, Class<Z> dataSourceClass) { super(id); this.dataSourceClass = dataSourceClass; } public CommonDataSourceDatabaseBuilder<Z, D> dataSource(Z dataSource) { return this.connectionSource(dataSource); } @Override public CommonDataSourceDatabaseBuilder<Z, D> connectionSource(Z connectionSource) { super.connectionSource(connectionSource); return this; } /** * Alias for {@link #connectionSource(CommonDataSource)}. * @param className * @return */ public CommonDataSourceDatabaseBuilder<Z, D> dataSourceClass(String className) { return this.location(className); } @Override public CommonDataSourceDatabaseBuilder<Z, D> location(String location) { super.location(location); return this; } @Override public CommonDataSourceDatabaseBuilder<Z, D> property(String name, String value) { super.property(name, value); return this; } @Override public CommonDataSourceDatabaseBuilder<Z, D> credentials(String user, String password) { super.credentials(user, password); return this; } @Override public CommonDataSourceDatabaseBuilder<Z, D> weight(int weight) { super.weight(weight); return this; } @Override public CommonDataSourceDatabaseBuilder<Z, D> locality(Locality locality) { super.locality(locality); return this; } @Override public CommonDataSourceDatabaseBuilder<Z, D> read(D database) { super.read(database); return this; } protected Z getDataSource() throws SQLException { Z dataSource = this.connectionSource; if (dataSource == null) { String location = this.location; if (location == null) { throw new SQLException(messages.noLocation(this.id)); } try { Class<? extends Z> dataSourceClass = this.getClass().getClassLoader().loadClass(location).asSubclass(this.dataSourceClass); dataSource = dataSourceClass.newInstance(); Properties properties = this.properties; if (!properties.isEmpty()) { for (PropertyDescriptor descriptor: Introspector.getBeanInfo(dataSourceClass).getPropertyDescriptors()) { String value = properties.getProperty(descriptor.getName()); if (value != null) { PropertyEditor editor = PropertyEditorManager.findEditor(descriptor.getPropertyType()); if (editor != null) { editor.setAsText(value); descriptor.getWriteMethod().invoke(dataSource, editor.getValue()); } } } } } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | IntrospectionException | IllegalArgumentException | InvocationTargetException e) { throw new SQLException(e); } } return dataSource; } }