EmbeddedDerbyDataSourceResource.java
/*
* Copyright 2016 Development Entropy (deventropy.org) Contributors
*
* 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.deventropy.junithelper.derby.datasource;
import java.io.File;
import javax.sql.ConnectionPoolDataSource;
import javax.sql.DataSource;
import javax.sql.XADataSource;
import org.apache.derby.jdbc.EmbeddedConnectionPoolDataSource;
import org.apache.derby.jdbc.EmbeddedDataSource;
import org.apache.derby.jdbc.EmbeddedDataSourceInterface;
import org.apache.derby.jdbc.EmbeddedXADataSource;
import org.deventropy.junithelper.derby.DerbyResourceConfig;
import org.deventropy.junithelper.derby.EmbeddedDerbyResource;
import org.junit.rules.TemporaryFolder;
/**
* Provides an in-memory Derby resource capable of providing different kinds of {@link DataSource}s supported by Derby.
* An instance of this class is initialized with the {@link DerbyResourceConfig configuration} and a
* {@link #getDerbySystemHome() Derby System Home}.
*
* <p>This resource extends {@link EmbeddedDerbyResource} and all functionality in that class are available here, please
* consult the documentation of that class on initialization, control of the resource and the underlying Derby
* database.
*
* <p>Example of usage:
* <pre>
* public class SimpleDerbyTest {
*
* private static final String DB_NAME = "test-database";
*
* private TemporaryFolder tempFolder = new TemporaryFolder();
* private EmbeddedDerbyDataSourceResource embeddedDerbyResource =
* new EmbeddedDerbyDataSourceResource(DerbyResourceConfig.buildDefault().useInMemoryDatabase(DB_NAME),
* tempFolder);
*
* @Rule
* public RuleChain derbyRuleChain = RuleChain.outerRule(tempFolder).around(embeddedDerbyResource);
*
* @Test
* public void test () throws SQLException {
* final String jdbcUrl = embeddedDerbyResource.getJdbcUrl();
* DataSource dataSource = null;
* Connection connection = null;
* Statement stmt = null;
* ResultSet rs = null;
*
* try {
* final EmbeddedDerbyDataSourceFactory dsFactory = embeddedDerbyDataSourceResource.getDataSourceFactory();
* assertNotNull(dsFactory);
*
* dataSource = dsFactory.getDataSource(true);
* connection = dataSource.getConnection();
*
* // Check a value
* stmt = connection.createStatement();
* rs = stmt.executeQuery("SELECT 1 FROM SYSIBM.SYSDUMMY1");
*
* assertTrue(rs.next());
* } finally {
* // Close resources
* }
* }
* }
* </pre>
*
* <p>For further information and examples, see
* <a href="http://www.deventropy.org/junit-helper/junit-helper-derby/manual/">User Manual on the Project Website</a>.
*
* @see EmbeddedDerbyResource
* @see DerbyResourceConfig
*
* @author Bindul Bhowmik
*/
public class EmbeddedDerbyDataSourceResource extends EmbeddedDerbyResource {
private final EmbeddedDerbyDataSourceFactory dataSourceFactory = new EmbeddedDerbyDataSourceFactoryImpl();
/**
* Creates a new Derby resource.
*
* @see EmbeddedDerbyResource#EmbeddedDerbyResource(DerbyResourceConfig, File)
*
* @param dbResourceConfig Configurations to setup this resource
* @param derbySystemHomeDir A folder to use as the derby system home
*/
public EmbeddedDerbyDataSourceResource (final DerbyResourceConfig dbResourceConfig, final File derbySystemHomeDir) {
super (dbResourceConfig, derbySystemHomeDir);
}
/**
* Creates a new Derby resource.
*
* @see EmbeddedDerbyResource#EmbeddedDerbyResource(DerbyResourceConfig, TemporaryFolder)
*
* @param dbResourceConfig Configurations to setup this resource
* @param derbySystemHomeParentTmpFolder A temporary folder to use as the derby system home
*/
public EmbeddedDerbyDataSourceResource (final DerbyResourceConfig dbResourceConfig,
final TemporaryFolder derbySystemHomeParentTmpFolder) {
super (dbResourceConfig, derbySystemHomeParentTmpFolder);
}
/**
* Returns the {@link EmbeddedDerbyDataSourceFactory} instance for this resource from which data sources can be
* created / cached. The factory returned supports caching <code>ataSource</code>s created. It also checks the
* state of <code>this</code> instance and will throw {@link IllegalStateException} if the resource is not
* {@link #isActive()}.
*
* @return Factory to create data sources for this instance.
*/
public EmbeddedDerbyDataSourceFactory getDataSourceFactory () {
return dataSourceFactory;
}
private class EmbeddedDerbyDataSourceFactoryImpl implements EmbeddedDerbyDataSourceFactory {
private EmbeddedDataSource embeddedDataSource;
private EmbeddedConnectionPoolDataSource embeddedConnectionPoolDataSource;
private EmbeddedXADataSource embeddedXADataSource;
/* (non-Javadoc)
* @see org.deventropy.junithelper.derby.EmbeddedDerbyDataSourceFactory#getDataSource(boolean)
*/
@Override
public DataSource getDataSource (final boolean cachedInstance) {
ensureActive();
if (cachedInstance) {
if (null == embeddedDataSource) {
embeddedDataSource = createEmbeddedDataSource();
}
return embeddedDataSource;
}
return createEmbeddedDataSource();
}
private EmbeddedDataSource createEmbeddedDataSource () {
final EmbeddedDataSource embeddedDs = new EmbeddedDataSource();
setupDataSource(embeddedDs);
return embeddedDs;
}
/* (non-Javadoc)
* @see org.deventropy.junithelper.derby.EmbeddedDerbyDataSourceFactory#getConnectionPoolDataSource(boolean)
*/
@Override
public ConnectionPoolDataSource getConnectionPoolDataSource (final boolean cachedInstance) {
ensureActive();
if (cachedInstance) {
if (null == embeddedConnectionPoolDataSource) {
embeddedConnectionPoolDataSource = createEmbeddedConnectionPoolDataSource();
}
return embeddedConnectionPoolDataSource;
}
return createEmbeddedConnectionPoolDataSource();
}
private EmbeddedConnectionPoolDataSource createEmbeddedConnectionPoolDataSource () {
final EmbeddedConnectionPoolDataSource connectionPoolDataSource = new EmbeddedConnectionPoolDataSource();
setupDataSource(connectionPoolDataSource);
return connectionPoolDataSource;
}
/* (non-Javadoc)
* @see org.deventropy.junithelper.derby.EmbeddedDerbyDataSourceFactory#getXADataSource(boolean)
*/
@Override
public XADataSource getXADataSource (final boolean cachedInstance) {
ensureActive();
if (cachedInstance) {
if (null == embeddedXADataSource) {
embeddedXADataSource = createEmbeddedXADataSource();
}
return embeddedXADataSource;
}
return createEmbeddedXADataSource();
}
private EmbeddedXADataSource createEmbeddedXADataSource () {
final EmbeddedXADataSource xaDataSource = new EmbeddedXADataSource();
setupDataSource(xaDataSource);
return xaDataSource;
}
private void setupDataSource (final EmbeddedDataSourceInterface dataSource) {
final StringBuilder dsDatabaseName = new StringBuilder()
.append(getConfig().getSubSubProtocol().datasourceDatabaseNamePrefix());
appendDbLocNameToUrl(dsDatabaseName);
dataSource.setDatabaseName(dsDatabaseName.toString());
}
}
}