/* * Copyright 2015-2016 http://hsweb.me * * 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.hsweb.web.datasource.dynamic; import com.atomikos.jdbc.AtomikosDataSourceBean; import org.hsweb.web.core.datasource.DatabaseType; import org.hsweb.web.core.datasource.DynamicDataSource; import org.hsweb.web.service.datasource.DynamicDataSourceService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.jdbc.datasource.AbstractDataSource; import org.springframework.util.Assert; import javax.sql.DataSource; import javax.sql.XAConnection; import javax.sql.XADataSource; import java.io.Closeable; import java.sql.Connection; import java.sql.SQLException; public class DynamicXaDataSourceImpl extends AbstractDataSource implements DynamicDataSource, XADataSource, Closeable { private Logger logger = LoggerFactory.getLogger(DynamicDataSource.class); private javax.sql.DataSource defaultDataSource = null; private DatabaseType defaultDatabaseType; protected DynamicDataSourceService dynamicDataSourceService; public DynamicXaDataSourceImpl(javax.sql.DataSource defaultDataSource, DatabaseType defaultDatabaseType) { Assert.notNull(defaultDataSource); Assert.notNull(defaultDatabaseType); this.defaultDataSource = defaultDataSource; this.defaultDatabaseType = defaultDatabaseType; } @Override public Connection getConnection() throws SQLException { return getActiveDataSource().getConnection(); } @Override public Connection getConnection(String username, String password) throws SQLException { return getActiveDataSource().getConnection(username, password); } public DataSource getActiveDataSource() { String sourceId = DynamicDataSource.getActiveDataSourceId(); logger.info("use datasource:{}", sourceId == null ? "default" : sourceId); if (sourceId == null || dynamicDataSourceService == null) return defaultDataSource; DataSource dataSource = dynamicDataSourceService.getDataSource(sourceId); if (dataSource == null) { logger.info("use datasource:{} fail,because its not exists! use default datasource now.", sourceId); return defaultDataSource; } return dataSource; } @Override public DatabaseType getActiveDataBaseType() { String sourceId = DynamicDataSource.getActiveDataSourceId(); if (sourceId == null || dynamicDataSourceService == null) return defaultDatabaseType; String type = dynamicDataSourceService.getDataBaseType(sourceId); if (type == null) return defaultDatabaseType; return DatabaseType.valueOf(type); } public XADataSource getActiveXADataSource() { DataSource activeDs = getActiveDataSource(); XADataSource xaDataSource; if (activeDs instanceof XADataSource) xaDataSource = ((XADataSource) activeDs); else if (activeDs instanceof AtomikosDataSourceBean) { xaDataSource = ((AtomikosDataSourceBean) activeDs).getXaDataSource(); } else { throw new UnsupportedOperationException(activeDs.getClass() + " is not XADataSource"); } return xaDataSource; } public synchronized void setDynamicDataSourceService(DynamicDataSourceService dynamicDataSourceService) { if (this.dynamicDataSourceService != null) throw new UnsupportedOperationException(); this.dynamicDataSourceService = dynamicDataSourceService; } @Override public XAConnection getXAConnection() throws SQLException { return getActiveXADataSource().getXAConnection(); } @Override public XAConnection getXAConnection(String user, String password) throws SQLException { return getActiveXADataSource().getXAConnection(user, password); } public void close() { try { if (dynamicDataSourceService != null) dynamicDataSourceService.destroyAll(); } catch (Exception e) { logger.error("close datasource error", e); } } }