diff --git a/org.springframework.core/src/main/java/org/springframework/core/io/ClassRelativeResourceLoader.java b/org.springframework.core/src/main/java/org/springframework/core/io/ClassRelativeResourceLoader.java new file mode 100644 index 0000000000..dc20e6747f --- /dev/null +++ b/org.springframework.core/src/main/java/org/springframework/core/io/ClassRelativeResourceLoader.java @@ -0,0 +1,75 @@ +/* + * Copyright 2002-2009 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.springframework.core.io; + +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +/** + * {@link ResourceLoader} implementation that interprets plain resource paths + * as relative to a given java.lang.Class. + * + * @author Juergen Hoeller + * @since 3.0 + * @see java.lang.Class#getResource(String) + * @see ClassPathResource#ClassPathResource(String, Class) + */ +public class ClassRelativeResourceLoader extends DefaultResourceLoader { + + private final Class clazz; + + + /** + * Create a new ClassRelativeResourceLoader for the given class. + * @param clazz the class to load resources through + */ + public ClassRelativeResourceLoader(Class clazz) { + Assert.notNull(clazz, "Class must not be null"); + this.clazz = clazz; + setClassLoader(clazz.getClassLoader()); + } + + protected Resource getResourceByPath(String path) { + return new ClassRelativeContextResource(path, this.clazz); + } + + + /** + * ClassPathResource that explicitly expresses a context-relative path + * through implementing the ContextResource interface. + */ + private static class ClassRelativeContextResource extends ClassPathResource implements ContextResource { + + private final Class clazz; + + public ClassRelativeContextResource(String path, Class clazz) { + super(path, clazz); + this.clazz = clazz; + } + + public String getPathWithinContext() { + return getPath(); + } + + @Override + public Resource createRelative(String relativePath) { + String pathToUse = StringUtils.applyRelativePath(getPath(), relativePath); + return new ClassRelativeContextResource(pathToUse, this.clazz); + } + } + +} diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/SimpleDriverDataSource.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/SimpleDriverDataSource.java index 2185c0310b..b1972b29ae 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/SimpleDriverDataSource.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/SimpleDriverDataSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2009 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. @@ -107,8 +107,8 @@ public class SimpleDriverDataSource extends AbstractDriverBasedDataSource { * within the SimpleDriverDataSource. * @see #setDriver */ - public void setDriverClass(Class driverClass) { - this.driver = (Driver) BeanUtils.instantiateClass(driverClass); + public void setDriverClass(Class driverClass) { + this.driver = BeanUtils.instantiateClass(driverClass); } /** diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/AbstractEmbeddedDatabaseConfigurer.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/AbstractEmbeddedDatabaseConfigurer.java index 280d5f576b..634eb57cde 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/AbstractEmbeddedDatabaseConfigurer.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/AbstractEmbeddedDatabaseConfigurer.java @@ -13,38 +13,39 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.jdbc.datasource.embedded; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; - import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** - * Base class for {@link EmbeddedDatabaseConfigurer} implementations providing common shutdown behaviour. + * Base class for {@link EmbeddedDatabaseConfigurer} implementations providing common shutdown behavior. + * * @author Oliver Gierke + * @author Juergen Hoeller * @since 3.0 */ abstract class AbstractEmbeddedDatabaseConfigurer implements EmbeddedDatabaseConfigurer { - private static final Log logger = LogFactory.getLog(AbstractEmbeddedDatabaseConfigurer.class); + protected final Log logger = LogFactory.getLog(getClass()); public void shutdown(DataSource dataSource, String databaseName) { - Connection connection = JdbcUtils.getConnection(dataSource); - Statement stmt = null; try { - stmt = connection.createStatement(); + Connection connection = dataSource.getConnection(); + Statement stmt = connection.createStatement(); stmt.execute("SHUTDOWN"); - } catch (SQLException e) { + } + catch (SQLException ex) { if (logger.isWarnEnabled()) { - logger.warn("Could not shutdown embedded database", e); + logger.warn("Could not shutdown embedded database", ex); } - } finally { - JdbcUtils.closeStatement(stmt); } } + } diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/CannotReadScriptException.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/CannotReadScriptException.java index fe0d703bee..dd2ae82ff9 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/CannotReadScriptException.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/CannotReadScriptException.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.jdbc.datasource.embedded; import org.springframework.core.io.support.EncodedResource; @@ -20,19 +21,19 @@ import org.springframework.core.io.support.EncodedResource; /** * Thrown by {@link ResourceDatabasePopulator} if one of its SQL scripts could * not be read during population. + * * @author Keith Donald * @since 3.0 */ -@SuppressWarnings("serial") public class CannotReadScriptException extends RuntimeException { /** - * Creates a new cannot read script exception. - * + * Constructor a new CannotReadScriptException. * @param resource the resource that could not be read from * @param cause the underlying cause of the resource access failure */ public CannotReadScriptException(EncodedResource resource, Throwable cause) { super("Cannot read SQL script from " + resource, cause); } + } diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/ConnectionProperties.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/ConnectionProperties.java index d4c7ee0a61..a28d7dee1c 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/ConnectionProperties.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/ConnectionProperties.java @@ -13,38 +13,43 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.jdbc.datasource.embedded; +import java.sql.Driver; + /** * DataSourceFactory helper that allows essential JDBC connection properties to be configured consistently, * independent of the actual DataSource implementation. + * * @author Keith Donald * @since 3.0 * @see DataSourceFactory */ public interface ConnectionProperties { - + /** * Set the JDBC driver to use to connect to the database. * @param driverClass the jdbc driver class */ - void setDriverClass(Class driverClass); - + void setDriverClass(Class driverClass); + /** * Sets the JDBC connection URL of the database. * @param url the connection url */ void setUrl(String url); - + /** * Sets the username to use to connect to the database. * @param username the username */ void setUsername(String username); - + /** * Sets the password to use to connect to the database. * @param password the password */ void setPassword(String password); + } diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/DataSourceFactory.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/DataSourceFactory.java index ea4789b9ec..9df27cf6b0 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/DataSourceFactory.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/DataSourceFactory.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.jdbc.datasource.embedded; import javax.sql.DataSource; @@ -20,21 +21,25 @@ import javax.sql.DataSource; import org.springframework.jdbc.datasource.SimpleDriverDataSource; /** - * Encapsulates the creation of a particular DataSource implementation, such as a {@link SimpleDriverDataSource} or connection pool such as Apache DBCP or c3p0. - * Call {@link #getConnectionProperties()} to configure normalized DataSource properties before calling {@link #getDataSource()} to actually get the configured DataSource instance. + * Encapsulates the creation of a particular DataSource implementation, such as a + * {@link SimpleDriverDataSource} or connection pool such as Apache DBCP or C3P0. + * + *

Call {@link #getConnectionProperties()} to configure normalized DataSource properties + * before calling {@link #getDataSource()} to actually get the configured DataSource instance. + * * @author Keith Donald * @since 3.0 */ public interface DataSourceFactory { - + /** * Allows properties of the DataSource to be configured. */ ConnectionProperties getConnectionProperties(); - + /** * Returns the DataSource with the connection properties applied. */ DataSource getDataSource(); - + } diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/DatabasePopulator.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/DatabasePopulator.java index dfa35940ce..e5a3bad750 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/DatabasePopulator.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/DatabasePopulator.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.jdbc.datasource.embedded; import java.sql.Connection; @@ -20,6 +21,7 @@ import java.sql.SQLException; /** * Strategy used to populate an embedded database during initialization. + * * @author Keith Donald * @since 3.0 * @see ResourceDatabasePopulator @@ -32,4 +34,5 @@ public interface DatabasePopulator { * @throws SQLException if an unrecoverable data access exception occurs during database population */ void populate(Connection connection) throws SQLException; -} \ No newline at end of file + +} diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/DerbyEmbeddedDatabaseConfigurer.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/DerbyEmbeddedDatabaseConfigurer.java index d400f7f7d3..8df66a239d 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/DerbyEmbeddedDatabaseConfigurer.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/DerbyEmbeddedDatabaseConfigurer.java @@ -13,26 +13,26 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.jdbc.datasource.embedded; import java.io.File; import java.io.IOException; import java.io.OutputStream; -import java.sql.Connection; import java.sql.SQLException; - +import java.util.Properties; import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.derby.impl.io.VFMemoryStorageFactory; import org.apache.derby.jdbc.EmbeddedDriver; -import org.springframework.jdbc.datasource.SimpleDriverDataSource; -import org.springframework.util.ClassUtils; /** * {@link EmbeddedDatabaseConfigurer} for the Apache Derby database. + * * @author Oliver Gierke + * @author Juergen Hoeller * @since 3.0 */ final class DerbyEmbeddedDatabaseConfigurer implements EmbeddedDatabaseConfigurer { @@ -46,9 +46,6 @@ final class DerbyEmbeddedDatabaseConfigurer implements EmbeddedDatabaseConfigure private static DerbyEmbeddedDatabaseConfigurer INSTANCE; - private DerbyEmbeddedDatabaseConfigurer() { - } - /** * Get the singleton {@link DerbyEmbeddedDatabaseConfigurer} instance. * @return the configurer @@ -59,50 +56,48 @@ final class DerbyEmbeddedDatabaseConfigurer implements EmbeddedDatabaseConfigure // disable log file System.setProperty("derby.stream.error.method", DerbyEmbeddedDatabaseConfigurer.class.getName() + ".getNoopOutputStream"); - ClassUtils.forName("org.apache.derby.jdbc.EmbeddedDriver", DerbyEmbeddedDatabaseConfigurer.class - .getClassLoader()); INSTANCE = new DerbyEmbeddedDatabaseConfigurer(); } return INSTANCE; } + private DerbyEmbeddedDatabaseConfigurer() { + } + public void configureConnectionProperties(ConnectionProperties properties, String databaseName) { - properties.setDriverClass(org.apache.derby.jdbc.EmbeddedDriver.class); + properties.setDriverClass(EmbeddedDriver.class); properties.setUrl(String.format(URL_TEMPLATE, databaseName, "create=true")); properties.setUsername("sa"); properties.setPassword(""); } public void shutdown(DataSource dataSource, String databaseName) { - Connection connection = null; try { - SimpleDriverDataSource shutdownDataSource = new SimpleDriverDataSource(); - shutdownDataSource.setDriverClass(EmbeddedDriver.class); - shutdownDataSource.setUrl(String.format(URL_TEMPLATE, databaseName, "shutdown=true")); - connection = shutdownDataSource.getConnection(); - } catch (SQLException e) { - if (SHUTDOWN_CODE.equals(e.getSQLState())) { + new EmbeddedDriver().connect( + String.format(URL_TEMPLATE, databaseName, "shutdown=true"), new Properties()); + } + catch (SQLException ex) { + if (SHUTDOWN_CODE.equals(ex.getSQLState())) { purgeDatabase(databaseName); - } else { - logger.warn("Could not shutdown in-memory Derby database", e); } - } finally { - JdbcUtils.closeConnection(connection); + else { + logger.warn("Could not shutdown in-memory Derby database", ex); + } } } /** - * Purges the in-memory database, to prevent it from hanging around after - * being shut down - * @param databaseName + * Purge the in-memory database, to prevent it from hanging around after + * being shut down. */ private void purgeDatabase(String databaseName) { // TODO: update this code once Derby adds a proper way to remove an in-memory db // (see http://wiki.apache.org/db-derby/InMemoryBackEndPrimer for details) try { VFMemoryStorageFactory.purgeDatabase(new File(databaseName).getCanonicalPath()); - } catch (IOException ioe) { - logger.warn("Could not purge in-memory Derby database", ioe); + } + catch (IOException ex) { + logger.warn("Could not purge in-memory Derby database", ex); } } @@ -114,9 +109,9 @@ final class DerbyEmbeddedDatabaseConfigurer implements EmbeddedDatabaseConfigure static OutputStream getNoopOutputStream() { return new OutputStream() { public void write(int b) throws IOException { - // ignore the input + // ignore the output } }; } -} \ No newline at end of file +} diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabase.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabase.java index 6a01632c79..634fa5c8fb 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabase.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabase.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.jdbc.datasource.embedded; import javax.sql.DataSource; @@ -21,13 +22,15 @@ import javax.sql.DataSource; * A handle to an EmbeddedDatabase instance. * Is a {@link DataSource}. * Adds a shutdown operation so the embedded database instance can be shutdown. + * * @author Keith Donald * @since 3.0 */ public interface EmbeddedDatabase extends DataSource { - + /** * Shutdown this embedded database. */ void shutdown(); + } diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseBuilder.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseBuilder.java index adfa2252bd..9f1989ff6a 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseBuilder.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseBuilder.java @@ -13,39 +13,55 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.jdbc.datasource.embedded; -import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.ClassRelativeResourceLoader; import org.springframework.core.io.DefaultResourceLoader; -import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; /** * A builder that provides a fluent API for constructing an embedded database. - * Usage example: + * + *

Usage example: *

  * EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
  * EmbeddedDatabase db = builder.script("schema.sql").script("test-data.sql").build();
  * db.shutdown();
  * 
+ * * @author Keith Donald + * @author Juergen Hoeller * @since 3.0 */ public class EmbeddedDatabaseBuilder { - private EmbeddedDatabaseFactory databaseFactory; + private final EmbeddedDatabaseFactory databaseFactory; - private ResourceDatabasePopulator databasePopulator; + private final ResourceDatabasePopulator databasePopulator; + + private final ResourceLoader resourceLoader; + - private ResourceLoader resourceLoader; - /** - * Creates a new embedded database builder. + * Create a new embedded database builder. */ public EmbeddedDatabaseBuilder() { - init(new DefaultResourceLoader()); + this(new DefaultResourceLoader()); + } + + /** + * Create a new embedded database builder withfor the given ResourceLoader. + * @param resourceLoader the ResourceLoader to delegate to + */ + public EmbeddedDatabaseBuilder(ResourceLoader resourceLoader) { + this.databaseFactory = new EmbeddedDatabaseFactory(); + this.databasePopulator = new ResourceDatabasePopulator(); + this.databaseFactory.setDatabasePopulator(this.databasePopulator); + this.resourceLoader = resourceLoader; } + /** * Sets the name of the embedded database * Defaults to 'testdb' if not called. @@ -53,7 +69,7 @@ public class EmbeddedDatabaseBuilder { * @return this, for fluent call chaining */ public EmbeddedDatabaseBuilder name(String databaseName) { - databaseFactory.setDatabaseName(databaseName); + this.databaseFactory.setDatabaseName(databaseName); return this; } @@ -64,7 +80,7 @@ public class EmbeddedDatabaseBuilder { * @return this, for fluent call chaining */ public EmbeddedDatabaseBuilder type(EmbeddedDatabaseType databaseType) { - databaseFactory.setDatabaseType(databaseType); + this.databaseFactory.setDatabaseType(databaseType); return this; } @@ -74,7 +90,7 @@ public class EmbeddedDatabaseBuilder { * @return this, for fluent call chaining */ public EmbeddedDatabaseBuilder script(String sqlResource) { - databasePopulator.addScript(resourceLoader.getResource(sqlResource)); + this.databasePopulator.addScript(resourceLoader.getResource(sqlResource)); return this; } @@ -83,45 +99,28 @@ public class EmbeddedDatabaseBuilder { * @return the embedded database */ public EmbeddedDatabase build() { - return databaseFactory.getDatabase(); - } - - /** - * Factory method that creates a EmbeddedDatabaseBuilder that loads SQL resources relative to the provided class. - * @param clazz the class to load relative to - * @return the embedded database builder - */ - public static EmbeddedDatabaseBuilder relativeTo(final Class clazz) { - ResourceLoader loader = new ResourceLoader() { - public ClassLoader getClassLoader() { - return getClass().getClassLoader(); - } - - public Resource getResource(String location) { - return new ClassPathResource(location, clazz); - } - }; - return new EmbeddedDatabaseBuilder(loader); + return this.databaseFactory.getDatabase(); } - + + /** * Factory method that builds a default EmbeddedDatabase instance. - * The default instance is HSQL with a schema created from classpath:schema.sql and test-data loaded from classpath:test-data.sql. + * The default instance is HSQL with a schema created from "classpath:schema.sql" + * and test-data loaded from "classpath:test-data.sql". * @return an embedded database */ public static EmbeddedDatabase buildDefault() { return new EmbeddedDatabaseBuilder().script("schema.sql").script("test-data.sql").build(); } - - private EmbeddedDatabaseBuilder(ResourceLoader loader) { - init(loader); - } - - private void init(ResourceLoader loader) { - databaseFactory = new EmbeddedDatabaseFactory(); - databasePopulator = new ResourceDatabasePopulator(); - databaseFactory.setDatabasePopulator(databasePopulator); - resourceLoader = loader; + + /** + * Factory method that creates a EmbeddedDatabaseBuilder that loads SQL resources + * relative to the provided class. + * @param clazz the class to load relative to + * @return the embedded database builder + */ + public static EmbeddedDatabaseBuilder relativeTo(Class clazz) { + return new EmbeddedDatabaseBuilder(new ClassRelativeResourceLoader(clazz)); } } diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseConfigurer.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseConfigurer.java index 3b2cea33ad..f82e0be500 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseConfigurer.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseConfigurer.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.jdbc.datasource.embedded; import javax.sql.DataSource; @@ -20,6 +21,7 @@ import javax.sql.DataSource; /** * Encapsulates the configuration required to create, connect to, and shutdown a specific type of embedded database such as HSQL or H2. * Create a implementation for each database type you wish to support; for example HSQL, H2, or some other type. + * * @author Keith Donald * @since 3.0 */ diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseConfigurerFactory.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseConfigurerFactory.java index 4c4bbfbd59..8719cc8ab2 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseConfigurerFactory.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseConfigurerFactory.java @@ -13,13 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.jdbc.datasource.embedded; import org.springframework.util.Assert; /** - * Maps well-known {@link EmbeddedDatabaseType embedded database types} to {@link EmbeddedDatabaseConfigurer} - * strategies. + * Maps well-known {@link EmbeddedDatabaseType embedded database types} to + * {@link EmbeddedDatabaseConfigurer} strategies. + * * @author Keith Donald * @author Oliver Gierke * @since 3.0 @@ -27,25 +29,26 @@ import org.springframework.util.Assert; final class EmbeddedDatabaseConfigurerFactory { public static EmbeddedDatabaseConfigurer getConfigurer(EmbeddedDatabaseType type) throws IllegalStateException { - Assert.notNull(type, "The EmbeddedDatabaseType is required"); + Assert.notNull(type, "EmbeddedDatabaseType is required"); try { switch (type) { - case HSQL: - return HsqlEmbeddedDatabaseConfigurer.getInstance(); - case H2: - return H2EmbeddedDatabaseConfigurer.getInstance(); - case DERBY: - return DerbyEmbeddedDatabaseConfigurer.getInstance(); - default: - throw new UnsupportedOperationException("Other embedded database types not yet supported"); + case HSQL: + return HsqlEmbeddedDatabaseConfigurer.getInstance(); + case H2: + return H2EmbeddedDatabaseConfigurer.getInstance(); + case DERBY: + return DerbyEmbeddedDatabaseConfigurer.getInstance(); + default: + throw new UnsupportedOperationException("Other embedded database types not yet supported"); } - } catch (ClassNotFoundException e) { - throw new IllegalStateException("Drivers for test database type [" + type - + "] are not available in the classpath", e); + } + catch (ClassNotFoundException ex) { + throw new IllegalStateException("Driver for test database type [" + type + + "] is not available in the classpath", ex); } } private EmbeddedDatabaseConfigurerFactory() { } -} \ No newline at end of file +} diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactory.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactory.java index 334d806c32..12c78d0d33 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactory.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactory.java @@ -13,39 +13,43 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.jdbc.datasource.embedded; import java.io.PrintWriter; import java.sql.Connection; import java.sql.SQLException; - import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + +import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.util.Assert; /** * Creates a {@link EmbeddedDatabase} instance. Callers are guaranteed that the returned database has been fully * initialized and populated. - *

- * Can be configured:
+ * + *

Can be configured:
* Call {@link #setDatabaseName(String)} to change the name of the database.
* Call {@link #setDatabaseType(EmbeddedDatabaseType)} to set the database type if you wish to use one of the supported types.
* Call {@link #setDatabaseConfigurer(EmbeddedDatabaseConfigurer)} to configure support for your own embedded database type.
* Call {@link #setDatabasePopulator(DatabasePopulator)} to change the algorithm used to populate the database.
* Call {@link #setDataSourceFactory(DataSourceFactory)} to change the type of DataSource used to connect to the database.
* Call {@link #getDatabase()} to get the {@link EmbeddedDatabase} instance.
+ * * @author Keith Donald + * @author Juergen Hoeller * @since 3.0 */ public class EmbeddedDatabaseFactory { private static Log logger = LogFactory.getLog(EmbeddedDatabaseFactory.class); - private String databaseName; + private String databaseName = "testdb"; - private DataSourceFactory dataSourceFactory; + private DataSourceFactory dataSourceFactory = new SimpleDriverDataSourceFactory(); private EmbeddedDatabaseConfigurer databaseConfigurer; @@ -53,101 +57,114 @@ public class EmbeddedDatabaseFactory { private DataSource dataSource; - /** - * Creates a default {@link EmbeddedDatabaseFactory}. - * Calling {@link #getDatabase()} will create a embedded HSQL database of name 'testdb'. - */ - public EmbeddedDatabaseFactory() { - setDatabaseName("testdb"); - setDatabaseType(EmbeddedDatabaseType.HSQL); - setDataSourceFactory(new SimpleDriverDataSourceFactory()); - } /** - * Sets the name of the database. Defaults to 'testdb'. - * @param name of the test database + * Set the name of the database. Defaults to "testdb". + * @param databaseName name of the test database */ - public void setDatabaseName(String name) { - Assert.notNull(name, "The testDatabaseName is required"); - databaseName = name; + public void setDatabaseName(String databaseName) { + Assert.notNull(databaseName, "Database name is required"); + this.databaseName = databaseName; } /** - * Sets the type of embedded database to use. Call this when you wish to configure one of the pre-supported types. - * Defaults to HSQL. + * Set the type of embedded database to use. Call this when you wish to configure + * one of the pre-supported types. Defaults to HSQL. * @param type the test database type */ public void setDatabaseType(EmbeddedDatabaseType type) { - setDatabaseConfigurer(EmbeddedDatabaseConfigurerFactory.getConfigurer(type)); + this.databaseConfigurer = EmbeddedDatabaseConfigurerFactory.getConfigurer(type); } /** - * Sets the strategy that will be used to configure the embedded database instance. + * Set the strategy that will be used to configure the embedded database instance. * Call this when you wish to use an embedded database type not already supported. * @param configurer the embedded database configurer */ public void setDatabaseConfigurer(EmbeddedDatabaseConfigurer configurer) { + Assert.notNull(configurer, "EmbeddedDatabaseConfigurer is required"); this.databaseConfigurer = configurer; } /** - * Sets the strategy that will be used to populate the embedded database. Defaults to null. + * Set the strategy that will be used to populate the embedded database. Defaults to null. * @param populator the database populator */ public void setDatabasePopulator(DatabasePopulator populator) { - Assert.notNull(populator, "The DatabasePopulator is required"); - databasePopulator = populator; + Assert.notNull(populator, "DatabasePopulator is required"); + this.databasePopulator = populator; } /** - * Sets the factory to use to create the DataSource instance that connects to the embedded database + * Set the factory to use to create the DataSource instance that connects to the embedded database. * Defaults to {@link SimpleDriverDataSourceFactory}. * @param dataSourceFactory the data source factory */ public void setDataSourceFactory(DataSourceFactory dataSourceFactory) { - Assert.notNull(dataSourceFactory, "The DataSourceFactory is required"); + Assert.notNull(dataSourceFactory, "DataSourceFactory is required"); this.dataSourceFactory = dataSourceFactory; } - // other public methods - /** * Factory method that returns the embedded database instance. */ public EmbeddedDatabase getDatabase() { - if (dataSource == null) { + if (this.dataSource == null) { initDatabase(); } - return new EmbeddedDataSourceProxy(dataSource); + return new EmbeddedDataSourceProxy(this.dataSource); } - // subclassing hooks /** * Hook to initialize the embedded database. Subclasses may call to force initialization. After calling this method, * {@link #getDataSource()} returns the DataSource providing connectivity to the db. */ protected void initDatabase() { - // create the embedded database source first + // Create the embedded database source first if (logger.isInfoEnabled()) { - logger.info("Created embedded database '" + databaseName + "'"); + logger.info("Creating embedded database '" + this.databaseName + "'"); } - databaseConfigurer.configureConnectionProperties(dataSourceFactory.getConnectionProperties(), databaseName); - dataSource = dataSourceFactory.getDataSource(); - if (databasePopulator != null) { - // now populate the database + if (this.databaseConfigurer == null) { + this.databaseConfigurer = EmbeddedDatabaseConfigurerFactory.getConfigurer(EmbeddedDatabaseType.HSQL); + } + this.databaseConfigurer.configureConnectionProperties( + this.dataSourceFactory.getConnectionProperties(), this.databaseName); + this.dataSource = this.dataSourceFactory.getDataSource(); + + // Now populate the database + if (this.databasePopulator != null) { populateDatabase(); } } + private void populateDatabase() { + try { + Connection connection = this.dataSource.getConnection(); + try { + this.databasePopulator.populate(connection); + } + finally { + try { + connection.close(); + } + catch (SQLException ex) { + // ignore + } + } + } + catch (SQLException ex) { + throw new DataAccessResourceFailureException("Failed to populate database", ex); + } + } + /** - * Hook that gets the datasource that provides the connectivity to the embedded database. - * Returns null if the datasource has not been initialized or the database has been shutdown. + * Hook that gets the DataSource that provides the connectivity to the embedded database. + *

Returns null if the DataSource has not been initialized or the database has been shut down. * Subclasses may call to access the datasource instance directly. - * @return the datasource */ protected DataSource getDataSource() { - return dataSource; + return this.dataSource; } /** @@ -155,68 +172,56 @@ public class EmbeddedDatabaseFactory { * After calling, {@link #getDataSource()} returns null. Does nothing if no embedded database has been initialized. */ protected void shutdownDatabase() { - if (dataSource != null) { - databaseConfigurer.shutdown(dataSource, databaseName); - dataSource = null; + if (this.dataSource != null) { + this.databaseConfigurer.shutdown(this.dataSource, this.databaseName); + this.dataSource = null; } } - // internal helper methods - - private void populateDatabase() { - Connection connection = JdbcUtils.getConnection(dataSource); - try { - databasePopulator.populate(connection); - } catch (SQLException e) { - throw new RuntimeException("SQLException occurred populating embedded database", e); - } finally { - JdbcUtils.closeConnection(connection); - } - } private class EmbeddedDataSourceProxy implements EmbeddedDatabase { - private DataSource dataSource; + + private final DataSource dataSource; public EmbeddedDataSourceProxy(DataSource dataSource) { this.dataSource = dataSource; } public Connection getConnection() throws SQLException { - return dataSource.getConnection(); + return this.dataSource.getConnection(); } public Connection getConnection(String username, String password) throws SQLException { - return dataSource.getConnection(username, password); + return this.dataSource.getConnection(username, password); } public int getLoginTimeout() throws SQLException { - return dataSource.getLoginTimeout(); + return this.dataSource.getLoginTimeout(); } public PrintWriter getLogWriter() throws SQLException { - return dataSource.getLogWriter(); + return this.dataSource.getLogWriter(); } public void setLoginTimeout(int seconds) throws SQLException { - dataSource.setLoginTimeout(seconds); + this.dataSource.setLoginTimeout(seconds); } public void setLogWriter(PrintWriter out) throws SQLException { - dataSource.setLogWriter(out); + this.dataSource.setLogWriter(out); } public boolean isWrapperFor(Class iface) throws SQLException { - return dataSource.isWrapperFor(iface); + return this.dataSource.isWrapperFor(iface); } public T unwrap(Class iface) throws SQLException { - return dataSource.unwrap(iface); + return this.dataSource.unwrap(iface); } public void shutdown() { shutdownDatabase(); } - } -} \ No newline at end of file +} diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactoryBean.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactoryBean.java index d22dd1c50c..8fd55af0f9 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactoryBean.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactoryBean.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.jdbc.datasource.embedded; import javax.sql.DataSource; @@ -24,18 +25,23 @@ import org.springframework.beans.factory.InitializingBean; /** * A subclass of {@link EmbeddedDatabaseFactory} that implements {@link FactoryBean} for registration as a Spring bean. * Returns the actual {@link DataSource} that provides connectivity to the embedded database to Spring. - * The target DataSource is returned instead of a {@link EmbeddedDatabase} proxy since the FactoryBean will manage the initialization and destruction lifecycle of the database instance. - * Implements DisposableBean to shutdown the embedded database when the managing Spring container is shutdown. + * + *

The target DataSource is returned instead of a {@link EmbeddedDatabase} proxy since the FactoryBean + * will manage the initialization and destruction lifecycle of the database instance. + * + *

Implements DisposableBean to shutdown the embedded database when the managing Spring container is shutdown. + * * @author Keith Donald * @since 3.0 */ -public class EmbeddedDatabaseFactoryBean extends EmbeddedDatabaseFactory implements FactoryBean, InitializingBean, DisposableBean { +public class EmbeddedDatabaseFactoryBean extends EmbeddedDatabaseFactory + implements FactoryBean, InitializingBean, DisposableBean { - public void afterPropertiesSet() throws Exception { + public void afterPropertiesSet() { initDatabase(); } - public DataSource getObject() throws Exception { + public DataSource getObject() { return getDataSource(); } @@ -47,7 +53,7 @@ public class EmbeddedDatabaseFactoryBean extends EmbeddedDatabaseFactory impleme return true; } - public void destroy() throws Exception { + public void destroy() { shutdownDatabase(); } diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseType.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseType.java index 68cc204b80..0a2a7650f6 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseType.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseType.java @@ -13,14 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.jdbc.datasource.embedded; /** * A supported embedded database type. + * * @author Keith Donald * @author Oliver Gierke * @since 3.0 */ public enum EmbeddedDatabaseType { - HSQL, H2, DERBY; + + HSQL, H2, DERBY + } diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/H2EmbeddedDatabaseConfigurer.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/H2EmbeddedDatabaseConfigurer.java index af11907145..c0935524ea 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/H2EmbeddedDatabaseConfigurer.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/H2EmbeddedDatabaseConfigurer.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.jdbc.datasource.embedded; import org.springframework.util.ClassUtils; @@ -20,7 +21,9 @@ import org.springframework.util.ClassUtils; /** * Initializes an H2 embedded database instance. * Call {@link #getInstance()} to get the singleton instance of this class. + * * @author Oliver Gierke + * @author Juergen Hoeller * @since 3.0 */ final class H2EmbeddedDatabaseConfigurer extends AbstractEmbeddedDatabaseConfigurer { @@ -42,15 +45,15 @@ final class H2EmbeddedDatabaseConfigurer extends AbstractEmbeddedDatabaseConfigu return INSTANCE; } + private H2EmbeddedDatabaseConfigurer(Class driverClass) { + this.driverClass = driverClass; + } + public void configureConnectionProperties(ConnectionProperties properties, String databaseName) { - properties.setDriverClass(driverClass); + properties.setDriverClass(this.driverClass); properties.setUrl(String.format("jdbc:h2:mem:%s;DB_CLOSE_DELAY=-1", databaseName)); properties.setUsername("sa"); properties.setPassword(""); } - private H2EmbeddedDatabaseConfigurer(Class driverClass) { - this.driverClass = driverClass; - } - -} \ No newline at end of file +} diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/HsqlEmbeddedDatabaseConfigurer.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/HsqlEmbeddedDatabaseConfigurer.java index bf2a989e70..89e6a4d6a6 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/HsqlEmbeddedDatabaseConfigurer.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/HsqlEmbeddedDatabaseConfigurer.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.jdbc.datasource.embedded; import org.springframework.util.ClassUtils; @@ -20,6 +21,7 @@ import org.springframework.util.ClassUtils; /** * Initializes an HSQL embedded database instance. * Call {@link #getInstance()} to get the singleton instance of this class. + * * @author Keith Donald * @author Oliver Gierke * @since 3.0 @@ -43,15 +45,15 @@ final class HsqlEmbeddedDatabaseConfigurer extends AbstractEmbeddedDatabaseConfi return INSTANCE; } + private HsqlEmbeddedDatabaseConfigurer(Class driverClass) { + this.driverClass = driverClass; + } + public void configureConnectionProperties(ConnectionProperties properties, String databaseName) { - properties.setDriverClass(driverClass); + properties.setDriverClass(this.driverClass); properties.setUrl("jdbc:hsqldb:mem:" + databaseName); properties.setUsername("sa"); properties.setPassword(""); } - private HsqlEmbeddedDatabaseConfigurer(Class driverClass) { - this.driverClass = driverClass; - } - } \ No newline at end of file diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/JdbcUtils.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/JdbcUtils.java deleted file mode 100644 index 7f9418e397..0000000000 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/JdbcUtils.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2002-2009 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.springframework.jdbc.datasource.embedded; - -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; - -import javax.sql.DataSource; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.jdbc.CannotGetJdbcConnectionException; - -/** - * Helper JDBC utilities used by other classes in this package. - * Note there is some duplication here with JdbcUtils in jdbc.support package. - * We may want to consider simply using that at some point. - * @author Keith Donald - * @since 3.0 - */ -final class JdbcUtils { - - private static Log logger = LogFactory.getLog(EmbeddedDatabaseFactory.class); - - private JdbcUtils() { - - } - - public static Connection getConnection(DataSource dataSource) { - try { - return dataSource.getConnection(); - } catch (SQLException ex) { - throw new CannotGetJdbcConnectionException("Could not get JDBC Connection", ex); - } - } - - public static void closeConnection(Connection connection) { - if (connection != null) { - try { - connection.close(); - } catch (SQLException ex) { - logger.debug("Could not close JDBC Connection", ex); - } catch (Throwable ex) { - // We don't trust the JDBC driver: It might throw RuntimeException or Error. - logger.debug("Unexpected exception on closing JDBC Connection", ex); - } - } - } - - public static void closeStatement(Statement stmt) { - if (stmt != null) { - try { - stmt.close(); - } catch (SQLException ex) { - logger.debug("Could not close JDBC Statement", ex); - } catch (Throwable ex) { - // We don't trust the JDBC driver: It might throw RuntimeException or Error. - logger.debug("Unexpected exception on closing JDBC Statement", ex); - } - } - } -} diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/ResourceDatabasePopulator.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/ResourceDatabasePopulator.java index 5f13320d2d..cfbefb60a3 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/ResourceDatabasePopulator.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/ResourceDatabasePopulator.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.jdbc.datasource.embedded; import java.io.IOException; @@ -27,15 +28,17 @@ import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.core.io.Resource; import org.springframework.core.io.support.EncodedResource; import org.springframework.util.StringUtils; /** * Populates a database from SQL scripts defined in external resources. - *

- * Call {@link #addScript(Resource)} to add a SQL script location.
+ * + *

Call {@link #addScript(Resource)} to add a SQL script location.
* Call {@link #setSqlScriptEncoding(String)} to set the encoding for all added scripts.
+ * * @author Keith Donald * @since 3.0 */ @@ -47,6 +50,7 @@ public class ResourceDatabasePopulator implements DatabasePopulator { private String sqlScriptEncoding; + /** * Add a script to execute to populate the database. * @param script the path to a SQL script @@ -65,15 +69,17 @@ public class ResourceDatabasePopulator implements DatabasePopulator { /** * Specify the encoding for SQL scripts, if different from the platform encoding. - * Note setting this property has no effect on added scripts that are already {@link EncodedResource encoded resources}. + * Note setting this property has no effect on added scripts that are already + * {@link EncodedResource encoded resources}. * @see #addScript(Resource) */ public void setSqlScriptEncoding(String sqlScriptEncoding) { this.sqlScriptEncoding = sqlScriptEncoding; } - + + public void populate(Connection connection) throws SQLException { - for (Resource script : scripts) { + for (Resource script : this.scripts) { executeSqlScript(connection, applyEncodingIfNecessary(script), false); } } @@ -81,8 +87,9 @@ public class ResourceDatabasePopulator implements DatabasePopulator { private EncodedResource applyEncodingIfNecessary(Resource script) { if (script instanceof EncodedResource) { return (EncodedResource) script; - } else { - return new EncodedResource(script, sqlScriptEncoding); + } + else { + return new EncodedResource(script, this.sqlScriptEncoding); } } @@ -95,6 +102,7 @@ public class ResourceDatabasePopulator implements DatabasePopulator { */ private void executeSqlScript(Connection connection, EncodedResource resource, boolean continueOnError) throws SQLException { + if (logger.isInfoEnabled()) { logger.info("Executing SQL script from " + resource); } @@ -112,25 +120,34 @@ public class ResourceDatabasePopulator implements DatabasePopulator { } splitSqlScript(script, delimiter, statements); int lineNumber = 0; - for (String statement : statements) { - lineNumber++; - Statement stmt = null; - try { - stmt = connection.createStatement(); - int rowsAffected = stmt.executeUpdate(statement); - if (logger.isDebugEnabled()) { - logger.debug(rowsAffected + " rows affected by SQL: " + statement); + Statement stmt = connection.createStatement(); + try { + for (String statement : statements) { + lineNumber++; + try { + int rowsAffected = stmt.executeUpdate(statement); + if (logger.isDebugEnabled()) { + logger.debug(rowsAffected + " rows affected by SQL: " + statement); + } } - } catch (SQLException e) { - if (continueOnError) { - if (logger.isWarnEnabled()) { - logger.warn("Line " + lineNumber + " statement failed: " + statement, e); + catch (SQLException ex) { + if (continueOnError) { + if (logger.isWarnEnabled()) { + logger.warn("Line " + lineNumber + " statement failed: " + statement, ex); + } + } + else { + throw ex; } - } else { - throw e; } - } finally { - JdbcUtils.closeStatement(stmt); + } + } + finally { + try { + stmt.close(); + } + catch (Throwable ex) { + logger.debug("Could not close JDBC Statement", ex); } } long elapsedTime = System.currentTimeMillis() - startTime; @@ -209,4 +226,4 @@ public class ResourceDatabasePopulator implements DatabasePopulator { } } -} \ No newline at end of file +} diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/SimpleDriverDataSourceFactory.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/SimpleDriverDataSourceFactory.java index 4f065d8f73..89d83823be 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/SimpleDriverDataSourceFactory.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/SimpleDriverDataSourceFactory.java @@ -13,35 +13,39 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.jdbc.datasource.embedded; +import java.sql.Driver; import javax.sql.DataSource; import org.springframework.jdbc.datasource.SimpleDriverDataSource; +import org.springframework.util.Assert; /** * Creates a {@link SimpleDriverDataSource}. + * * @author Keith Donald + * @author Juergen Hoeller * @since 3.0 */ final class SimpleDriverDataSourceFactory implements DataSourceFactory { - private SimpleDriverDataSource dataSource = new SimpleDriverDataSource(); + private final SimpleDriverDataSource dataSource = new SimpleDriverDataSource(); public ConnectionProperties getConnectionProperties() { return new ConnectionProperties() { - public void setDriverClass(Class driverClass) { - dataSource.setDriverClass(driverClass); + @SuppressWarnings("unchecked") + public void setDriverClass(Class driverClass) { + Assert.isAssignable(Driver.class, driverClass); + dataSource.setDriverClass((Class) driverClass); } - public void setUrl(String url) { dataSource.setUrl(url); } - public void setUsername(String username) { dataSource.setUsername(username); } - public void setPassword(String password) { dataSource.setPassword(password); } @@ -49,7 +53,7 @@ final class SimpleDriverDataSourceFactory implements DataSourceFactory { } public DataSource getDataSource() { - return dataSource; + return this.dataSource; } }