org.teiid.spring.xa.XADataSourceBuilder Maven / Gradle / Ivy
/*
* Copyright 2012-2016 the original author or authors.
*
* 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 org.teiid.spring.xa;
import java.io.PrintWriter;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.logging.Logger;
import javax.sql.XAConnection;
import javax.sql.XADataSource;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
import org.springframework.boot.context.properties.source.ConfigurationPropertyNameAliases;
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
import org.springframework.boot.context.properties.source.MapConfigurationPropertySource;
import org.springframework.boot.jdbc.DatabaseDriver;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
/**
* Convenience class for building a {@link XADataSource} with common
* implementations and properties.
*/
@ConfigurationProperties(prefix = "spring.xa.datasource")
public class XADataSourceBuilder implements BeanClassLoaderAware, InitializingBean, XADataSource {
private ClassLoader classLoader;
private Map properties = new LinkedHashMap();
private XADataSource delegate;
@Override
public void afterPropertiesSet() throws Exception {
this.delegate = createXaDataSource();
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
}
public XADataSourceBuilder() {
this(null);
}
public XADataSourceBuilder(ClassLoader classLoader) {
this.classLoader = classLoader;
}
public XADataSource build() throws Exception {
return this;
}
public static XADataSourceBuilder create() throws Exception {
return new XADataSourceBuilder();
}
protected XADataSource createXaDataSource() {
String className = dataSourceClassName();
Assert.state(StringUtils.hasLength(className), "No XA DataSource class name specified");
XADataSource dataSource = createXaDataSourceInstance(className);
Bindable bindable = Bindable.ofInstance(dataSource);
bindXaProperties(bindable);
return dataSource;
}
private XADataSource createXaDataSourceInstance(String className) {
try {
Class dataSourceClass = ClassUtils.forName(className, this.classLoader);
Object instance = BeanUtils.instantiateClass(dataSourceClass);
Assert.isInstanceOf(XADataSource.class, instance);
return (XADataSource) instance;
} catch (Exception ex) {
throw new IllegalStateException("Unable to create XADataSource instance from '" + className + "'");
}
}
private void bindXaProperties(Bindable target) {
ConfigurationPropertySource source = new MapConfigurationPropertySource(
this.properties);
ConfigurationPropertyNameAliases aliases = new ConfigurationPropertyNameAliases();
aliases.addAliases("url", "jdbc-url");
aliases.addAliases("username", "user");
aliases.addAliases("portNumber", "port");
aliases.addAliases("serverName", "server");
aliases.addAliases("databaseName", "database");
Binder binder = new Binder(source.withAliases(aliases));
binder.bind(ConfigurationPropertyName.EMPTY, target);
}
public XADataSourceBuilder driverClassName(String driverClassName) {
this.properties.put("driverClassName", driverClassName);
return this;
}
public XADataSourceBuilder username(String username) {
this.properties.put("username", username);
return this;
}
public XADataSourceBuilder password(String password) {
this.properties.put("password", password);
return this;
}
public XADataSourceBuilder port(String port) {
this.properties.put("port", port);
return this;
}
public XADataSourceBuilder server(String server) {
this.properties.put("server", server);
return this;
}
public XADataSourceBuilder database(String database) {
this.properties.put("database", database);
return this;
}
public XADataSourceBuilder dataSourceClassName(String dataSourceClassName) {
this.properties.put("dataSourceClassName", dataSourceClassName);
return this;
}
public String dataSourceClassName() {
String className = this.properties.get("dataSourceClassName");
if (!StringUtils.hasLength(className)) {
String url = this.properties.get("url");
className = DatabaseDriver.fromJdbcUrl(url).getXaDataSourceClassName();
}
return className;
}
public XADataSourceBuilder url(String url) {
this.properties.put("url", url);
return this;
}
public XADataSourceBuilder initialize(boolean initialize) {
this.properties.put("initialize", Boolean.toString(initialize));
return this;
}
public XADataSourceBuilder platform(String platform) {
this.properties.put("platform", platform);
return this;
}
@Override
public PrintWriter getLogWriter() throws SQLException {
return delegate.getLogWriter();
}
@Override
public int getLoginTimeout() throws SQLException {
return delegate.getLoginTimeout();
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return delegate.getParentLogger();
}
@Override
public void setLogWriter(PrintWriter out) throws SQLException {
this.delegate.setLogWriter(out);
}
@Override
public void setLoginTimeout(int seconds) throws SQLException {
this.delegate.setLoginTimeout(seconds);
}
@Override
public XAConnection getXAConnection() throws SQLException {
return this.delegate.getXAConnection();
}
@Override
public XAConnection getXAConnection(String user, String password) throws SQLException {
return this.delegate.getXAConnection(user, password);
}
}