Remove FactoryBean nature from data sourde initializer

This commit is contained in:
dsyer
2008-08-17 09:43:54 +00:00
parent f77c3c9269
commit d8df436e8e
11 changed files with 489 additions and 315 deletions

View File

@@ -22,30 +22,60 @@ import java.util.List;
import javax.sql.DataSource;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
public class InitializingDataSourceFactoryBean extends AbstractFactoryBean {
/**
* Wrapper for a {@link DataSource} that can run scripts on start up and shut
* down. Us as a bean definition <br/><br/>
*
* Run this class to initialize a database in a running server process.
* Make sure the server is running first by launching the "hsql-server" from the
* <code>hsql.server</code> project. Then you can right click in Eclipse and
* Run As -&gt; Java Application. Do the same any time you want to wipe the
* database and start again.
*
* @author Dave Syer
*
*/
public class DataSourceInitializer implements InitializingBean, DisposableBean {
private static final Log logger = LogFactory.getLog(DataSourceInitializer.class);
private Resource[] initScripts;
private Resource destroyScript;
private Resource[] destroyScripts;
private DataSource dataSource;
private boolean ignoreFailedDrop = true;
private static boolean initialized = false;
/**
* Main method as convenient entry point.
*
* @param args
*/
public static void main(String... args) {
new ClassPathXmlApplicationContext(ClassUtils.addResourcePathToPackagePath(DataSourceInitializer.class,
DataSourceInitializer.class.getSimpleName() + "-context.xml"));
}
/**
* @throws Throwable
* @see java.lang.Object#finalize()
@@ -56,42 +86,40 @@ public class InitializingDataSourceFactoryBean extends AbstractFactoryBean {
logger.debug("finalize called");
}
protected void destroyInstance(Object instance) throws Exception {
try {
doExecuteScript(destroyScript);
}
catch (Exception e) {
if (logger.isDebugEnabled()) {
logger.warn("Could not execute destroy script [" + destroyScript + "]", e);
public void destroy() {
if (destroyScripts==null) return;
for (int i = 0; i < destroyScripts.length; i++) {
Resource destroyScript = initScripts[i];
try {
doExecuteScript(destroyScript);
}
else {
logger.warn("Could not execute destroy script [" + destroyScript + "]");
catch (Exception e) {
if (logger.isDebugEnabled()) {
logger.warn("Could not execute destroy script [" + destroyScript + "]", e);
}
else {
logger.warn("Could not execute destroy script [" + destroyScript + "]");
}
}
}
}
public void afterPropertiesSet() throws Exception {
Assert.notNull(dataSource);
super.afterPropertiesSet();
initialize();
}
protected Object createInstance() throws Exception {
Assert.notNull(dataSource);
private void initialize() {
if (!initialized) {
try {
doExecuteScript(destroyScript);
}
catch (Exception e) {
logger.debug("Could not execute destroy script [" + destroyScript + "]", e);
}
destroy();
if (initScripts != null) {
for (Resource initScript : initScripts) {
for (int i = 0; i < initScripts.length; i++) {
Resource initScript = initScripts[i];
doExecuteScript(initScript);
}
}
initialized = true;
}
return dataSource;
}
private void doExecuteScript(final Resource scriptResource) {
@@ -102,7 +130,7 @@ public class InitializingDataSourceFactoryBean extends AbstractFactoryBean {
@SuppressWarnings("unchecked")
public Object doInTransaction(TransactionStatus status) {
SimpleJdbcTemplate jdbcTemplate = new SimpleJdbcTemplate(dataSource);
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
String[] scripts;
try {
scripts = StringUtils.delimitedListToStringArray(stripComments(IOUtils.readLines(scriptResource
@@ -111,15 +139,17 @@ public class InitializingDataSourceFactoryBean extends AbstractFactoryBean {
catch (IOException e) {
throw new BeanInitializationException("Cannot load script from [" + scriptResource + "]", e);
}
for (String script1 : scripts) {
String script = script1.trim();
for (int i = 0; i < scripts.length; i++) {
String script = scripts[i].trim();
if (StringUtils.hasText(script)) {
try {
jdbcTemplate.getJdbcOperations().execute(script);
} catch (DataAccessException e) {
jdbcTemplate.execute(script);
}
catch (DataAccessException e) {
if (ignoreFailedDrop && script.toLowerCase().startsWith("drop")) {
logger.debug("DROP script failed (ignoring): " + script);
} else {
}
else {
throw e;
}
}
@@ -136,32 +166,24 @@ public class InitializingDataSourceFactoryBean extends AbstractFactoryBean {
StringBuffer buffer = new StringBuffer();
for (String line : list) {
if (!line.startsWith("//") && !line.startsWith("--")) {
buffer.append(line).append("\n");
buffer.append(line + "\n");
}
}
return buffer.toString();
}
public Class<DataSource> getObjectType() {
return DataSource.class;
}
public void setInitScript(Resource initScript) {
this.initScripts = new Resource[] { initScript };
}
public void setInitScripts(Resource[] initScripts) {
this.initScripts = initScripts;
}
public void setDestroyScript(Resource destroyScript) {
this.destroyScript = destroyScript;
public void setDestroyScripts(Resource[] destroyScripts) {
this.destroyScripts = destroyScripts;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public void setIgnoreFailedDrop(boolean ignoreFailedDrop) {
this.ignoreFailedDrop = ignoreFailedDrop;
}

View File

@@ -1,151 +0,0 @@
/*
* Copyright 2006-2007 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 test.jdbc.datasource;
import java.io.IOException;
import java.util.List;
import javax.sql.DataSource;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
public class InitializingDataSourceFactoryBean extends AbstractFactoryBean {
private Resource[] initScripts;
private Resource destroyScript;
DataSource dataSource;
private static boolean initialized = false;
/**
* @throws Throwable
* @see java.lang.Object#finalize()
*/
protected void finalize() throws Throwable {
super.finalize();
initialized = false;
logger.debug("finalize called");
}
protected void destroyInstance(Object instance) throws Exception {
try {
doExecuteScript(destroyScript);
}
catch (Exception e) {
if (logger.isDebugEnabled()) {
logger.warn("Could not execute destroy script [" + destroyScript + "]", e);
}
else {
logger.warn("Could not execute destroy script [" + destroyScript + "]");
}
}
}
public void afterPropertiesSet() throws Exception {
Assert.notNull(dataSource);
super.afterPropertiesSet();
}
protected Object createInstance() throws Exception {
Assert.notNull(dataSource);
if (!initialized) {
try {
doExecuteScript(destroyScript);
}
catch (Exception e) {
logger.debug("Could not execute destroy script [" + destroyScript + "]", e);
}
if (initScripts != null) {
for (int i = 0; i < initScripts.length; i++) {
Resource initScript = initScripts[i];
doExecuteScript(initScript);
}
}
initialized = true;
}
return dataSource;
}
private void doExecuteScript(final Resource scriptResource) {
if (scriptResource == null || !scriptResource.exists())
return;
TransactionTemplate transactionTemplate = new TransactionTemplate(new DataSourceTransactionManager(dataSource));
transactionTemplate.execute(new TransactionCallback() {
@SuppressWarnings("unchecked")
public Object doInTransaction(TransactionStatus status) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
String[] scripts;
try {
scripts = StringUtils.delimitedListToStringArray(stripComments(IOUtils.readLines(scriptResource
.getInputStream())), ";");
}
catch (IOException e) {
throw new BeanInitializationException("Cannot load script from [" + scriptResource + "]", e);
}
for (int i = 0; i < scripts.length; i++) {
String script = scripts[i].trim();
if (StringUtils.hasText(script)) {
jdbcTemplate.execute(scripts[i]);
}
}
return null;
}
});
}
private String stripComments(List<String> list) {
StringBuffer buffer = new StringBuffer();
for (String line : list) {
if (!line.startsWith("//") && !line.startsWith("--")) {
buffer.append(line + "\n");
}
}
return buffer.toString();
}
public Class<DataSource> getObjectType() {
return DataSource.class;
}
public void setInitScripts(Resource[] initScripts) {
this.initScripts = initScripts;
}
public void setDestroyScript(Resource destroyScript) {
this.destroyScript = destroyScript;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
}

View File

@@ -22,27 +22,60 @@ import java.util.List;
import javax.sql.DataSource;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
public class InitializingDataSourceFactoryBean extends AbstractFactoryBean {
/**
* Wrapper for a {@link DataSource} that can run scripts on start up and shut
* down. Us as a bean definition <br/><br/>
*
* Run this class to initialize a database in a running server process.
* Make sure the server is running first by launching the "hsql-server" from the
* <code>hsql.server</code> project. Then you can right click in Eclipse and
* Run As -&gt; Java Application. Do the same any time you want to wipe the
* database and start again.
*
* @author Dave Syer
*
*/
public class DataSourceInitializer implements InitializingBean, DisposableBean {
private static final Log logger = LogFactory.getLog(DataSourceInitializer.class);
private Resource[] initScripts;
private Resource destroyScript;
private Resource[] destroyScripts;
DataSource dataSource;
private DataSource dataSource;
private boolean ignoreFailedDrop = true;
private static boolean initialized = false;
/**
* Main method as convenient entry point.
*
* @param args
*/
public static void main(String... args) {
new ClassPathXmlApplicationContext(ClassUtils.addResourcePathToPackagePath(DataSourceInitializer.class,
DataSourceInitializer.class.getSimpleName() + "-context.xml"));
}
/**
* @throws Throwable
* @see java.lang.Object#finalize()
@@ -53,34 +86,32 @@ public class InitializingDataSourceFactoryBean extends AbstractFactoryBean {
logger.debug("finalize called");
}
protected void destroyInstance(Object instance) throws Exception {
try {
doExecuteScript(destroyScript);
}
catch (Exception e) {
if (logger.isDebugEnabled()) {
logger.warn("Could not execute destroy script [" + destroyScript + "]", e);
public void destroy() {
if (destroyScripts==null) return;
for (int i = 0; i < destroyScripts.length; i++) {
Resource destroyScript = initScripts[i];
try {
doExecuteScript(destroyScript);
}
else {
logger.warn("Could not execute destroy script [" + destroyScript + "]");
catch (Exception e) {
if (logger.isDebugEnabled()) {
logger.warn("Could not execute destroy script [" + destroyScript + "]", e);
}
else {
logger.warn("Could not execute destroy script [" + destroyScript + "]");
}
}
}
}
public void afterPropertiesSet() throws Exception {
Assert.notNull(dataSource);
super.afterPropertiesSet();
initialize();
}
protected Object createInstance() throws Exception {
Assert.notNull(dataSource);
private void initialize() {
if (!initialized) {
try {
doExecuteScript(destroyScript);
}
catch (Exception e) {
logger.debug("Could not execute destroy script [" + destroyScript + "]", e);
}
destroy();
if (initScripts != null) {
for (int i = 0; i < initScripts.length; i++) {
Resource initScript = initScripts[i];
@@ -89,7 +120,6 @@ public class InitializingDataSourceFactoryBean extends AbstractFactoryBean {
}
initialized = true;
}
return dataSource;
}
private void doExecuteScript(final Resource scriptResource) {
@@ -112,7 +142,17 @@ public class InitializingDataSourceFactoryBean extends AbstractFactoryBean {
for (int i = 0; i < scripts.length; i++) {
String script = scripts[i].trim();
if (StringUtils.hasText(script)) {
jdbcTemplate.execute(scripts[i]);
try {
jdbcTemplate.execute(script);
}
catch (DataAccessException e) {
if (ignoreFailedDrop && script.toLowerCase().startsWith("drop")) {
logger.debug("DROP script failed (ignoring): " + script);
}
else {
throw e;
}
}
}
}
return null;
@@ -132,20 +172,20 @@ public class InitializingDataSourceFactoryBean extends AbstractFactoryBean {
return buffer.toString();
}
public Class<DataSource> getObjectType() {
return DataSource.class;
}
public void setInitScripts(Resource[] initScripts) {
this.initScripts = initScripts;
}
public void setDestroyScript(Resource destroyScript) {
this.destroyScript = destroyScript;
public void setDestroyScripts(Resource[] destroyScripts) {
this.destroyScripts = destroyScripts;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public void setIgnoreFailedDrop(boolean ignoreFailedDrop) {
this.ignoreFailedDrop = ignoreFailedDrop;
}
}

View File

@@ -1,13 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="dataSource" class="test.jdbc.datasource.InitializingDataSourceFactoryBean">
<property name="dataSource">
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:mem:testdb;sql.enforce_strict_size=true" />
</bean>
</property>
<bean class="test.jdbc.datasource.DataSourceInitializer">
<property name="dataSource" ref="dataSource" />
<property name="initScripts">
<list>
<value>schema-hsqldb.sql</value>
@@ -15,6 +10,10 @@
</list>
</property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:mem:testdb;sql.enforce_strict_size=true" />
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>

View File

@@ -22,27 +22,60 @@ import java.util.List;
import javax.sql.DataSource;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
public class InitializingDataSourceFactoryBean extends AbstractFactoryBean {
/**
* Wrapper for a {@link DataSource} that can run scripts on start up and shut
* down. Us as a bean definition <br/><br/>
*
* Run this class to initialize a database in a running server process.
* Make sure the server is running first by launching the "hsql-server" from the
* <code>hsql.server</code> project. Then you can right click in Eclipse and
* Run As -&gt; Java Application. Do the same any time you want to wipe the
* database and start again.
*
* @author Dave Syer
*
*/
public class DataSourceInitializer implements InitializingBean, DisposableBean {
private static final Log logger = LogFactory.getLog(DataSourceInitializer.class);
private Resource[] initScripts;
private Resource destroyScript;
private Resource[] destroyScripts;
DataSource dataSource;
private DataSource dataSource;
private boolean ignoreFailedDrop = true;
private static boolean initialized = false;
/**
* Main method as convenient entry point.
*
* @param args
*/
public static void main(String... args) {
new ClassPathXmlApplicationContext(ClassUtils.addResourcePathToPackagePath(DataSourceInitializer.class,
DataSourceInitializer.class.getSimpleName() + "-context.xml"));
}
/**
* @throws Throwable
* @see java.lang.Object#finalize()
@@ -53,34 +86,32 @@ public class InitializingDataSourceFactoryBean extends AbstractFactoryBean {
logger.debug("finalize called");
}
protected void destroyInstance(Object instance) throws Exception {
try {
doExecuteScript(destroyScript);
}
catch (Exception e) {
if (logger.isDebugEnabled()) {
logger.warn("Could not execute destroy script [" + destroyScript + "]", e);
public void destroy() {
if (destroyScripts==null) return;
for (int i = 0; i < destroyScripts.length; i++) {
Resource destroyScript = initScripts[i];
try {
doExecuteScript(destroyScript);
}
else {
logger.warn("Could not execute destroy script [" + destroyScript + "]");
catch (Exception e) {
if (logger.isDebugEnabled()) {
logger.warn("Could not execute destroy script [" + destroyScript + "]", e);
}
else {
logger.warn("Could not execute destroy script [" + destroyScript + "]");
}
}
}
}
public void afterPropertiesSet() throws Exception {
Assert.notNull(dataSource);
super.afterPropertiesSet();
initialize();
}
protected Object createInstance() throws Exception {
Assert.notNull(dataSource);
private void initialize() {
if (!initialized) {
try {
doExecuteScript(destroyScript);
}
catch (Exception e) {
logger.debug("Could not execute destroy script [" + destroyScript + "]", e);
}
destroy();
if (initScripts != null) {
for (int i = 0; i < initScripts.length; i++) {
Resource initScript = initScripts[i];
@@ -89,7 +120,6 @@ public class InitializingDataSourceFactoryBean extends AbstractFactoryBean {
}
initialized = true;
}
return dataSource;
}
private void doExecuteScript(final Resource scriptResource) {
@@ -112,7 +142,17 @@ public class InitializingDataSourceFactoryBean extends AbstractFactoryBean {
for (int i = 0; i < scripts.length; i++) {
String script = scripts[i].trim();
if (StringUtils.hasText(script)) {
jdbcTemplate.execute(scripts[i]);
try {
jdbcTemplate.execute(script);
}
catch (DataAccessException e) {
if (ignoreFailedDrop && script.toLowerCase().startsWith("drop")) {
logger.debug("DROP script failed (ignoring): " + script);
}
else {
throw e;
}
}
}
}
return null;
@@ -132,20 +172,20 @@ public class InitializingDataSourceFactoryBean extends AbstractFactoryBean {
return buffer.toString();
}
public Class<DataSource> getObjectType() {
return DataSource.class;
}
public void setInitScripts(Resource[] initScripts) {
this.initScripts = initScripts;
}
public void setDestroyScript(Resource destroyScript) {
this.destroyScript = destroyScript;
public void setDestroyScripts(Resource[] destroyScripts) {
this.destroyScripts = destroyScripts;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public void setIgnoreFailedDrop(boolean ignoreFailedDrop) {
this.ignoreFailedDrop = ignoreFailedDrop;
}
}

View File

@@ -2,14 +2,13 @@
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="dataSource" class="test.jdbc.datasource.InitializingDataSourceFactoryBean">
<property name="dataSource" ref="hsql" />
<bean id="dataSourceInitializer" class="test.jdbc.datasource.DataSourceInitializer">
<property name="dataSource" ref="dataSource" />
<property name="initScripts" value="org/springframework/batch/jms/init.sql" />
<property name="destroyScript" value="org/springframework/batch/jms/destroy.sql" />
<property name="destroyScripts" value="org/springframework/batch/jms/destroy.sql" />
</bean>
<bean id="hsql" class="org.springframework.jdbc.datasource.DriverManagerDataSource" lazy-init="true"
autowire-candidate="false">
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" lazy-init="true">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:mem:testdb" />
</bean>

View File

@@ -22,27 +22,60 @@ import java.util.List;
import javax.sql.DataSource;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
public class InitializingDataSourceFactoryBean extends AbstractFactoryBean {
/**
* Wrapper for a {@link DataSource} that can run scripts on start up and shut
* down. Us as a bean definition <br/><br/>
*
* Run this class to initialize a database in a running server process.
* Make sure the server is running first by launching the "hsql-server" from the
* <code>hsql.server</code> project. Then you can right click in Eclipse and
* Run As -&gt; Java Application. Do the same any time you want to wipe the
* database and start again.
*
* @author Dave Syer
*
*/
public class DataSourceInitializer implements InitializingBean, DisposableBean {
private static final Log logger = LogFactory.getLog(DataSourceInitializer.class);
private Resource[] initScripts;
private Resource destroyScript;
private Resource[] destroyScripts;
DataSource dataSource;
private DataSource dataSource;
private boolean ignoreFailedDrop = true;
private static boolean initialized = false;
/**
* Main method as convenient entry point.
*
* @param args
*/
public static void main(String... args) {
new ClassPathXmlApplicationContext(ClassUtils.addResourcePathToPackagePath(DataSourceInitializer.class,
DataSourceInitializer.class.getSimpleName() + "-context.xml"));
}
/**
* @throws Throwable
* @see java.lang.Object#finalize()
@@ -53,34 +86,32 @@ public class InitializingDataSourceFactoryBean extends AbstractFactoryBean {
logger.debug("finalize called");
}
protected void destroyInstance(Object instance) throws Exception {
try {
doExecuteScript(destroyScript);
}
catch (Exception e) {
if (logger.isDebugEnabled()) {
logger.warn("Could not execute destroy script [" + destroyScript + "]", e);
public void destroy() {
if (destroyScripts==null) return;
for (int i = 0; i < destroyScripts.length; i++) {
Resource destroyScript = initScripts[i];
try {
doExecuteScript(destroyScript);
}
else {
logger.warn("Could not execute destroy script [" + destroyScript + "]");
catch (Exception e) {
if (logger.isDebugEnabled()) {
logger.warn("Could not execute destroy script [" + destroyScript + "]", e);
}
else {
logger.warn("Could not execute destroy script [" + destroyScript + "]");
}
}
}
}
public void afterPropertiesSet() throws Exception {
Assert.notNull(dataSource);
super.afterPropertiesSet();
initialize();
}
protected Object createInstance() throws Exception {
Assert.notNull(dataSource);
private void initialize() {
if (!initialized) {
try {
doExecuteScript(destroyScript);
}
catch (Exception e) {
logger.debug("Could not execute destroy script [" + destroyScript + "]", e);
}
destroy();
if (initScripts != null) {
for (int i = 0; i < initScripts.length; i++) {
Resource initScript = initScripts[i];
@@ -89,7 +120,6 @@ public class InitializingDataSourceFactoryBean extends AbstractFactoryBean {
}
initialized = true;
}
return dataSource;
}
private void doExecuteScript(final Resource scriptResource) {
@@ -112,7 +142,17 @@ public class InitializingDataSourceFactoryBean extends AbstractFactoryBean {
for (int i = 0; i < scripts.length; i++) {
String script = scripts[i].trim();
if (StringUtils.hasText(script)) {
jdbcTemplate.execute(scripts[i]);
try {
jdbcTemplate.execute(script);
}
catch (DataAccessException e) {
if (ignoreFailedDrop && script.toLowerCase().startsWith("drop")) {
logger.debug("DROP script failed (ignoring): " + script);
}
else {
throw e;
}
}
}
}
return null;
@@ -132,20 +172,20 @@ public class InitializingDataSourceFactoryBean extends AbstractFactoryBean {
return buffer.toString();
}
public Class<DataSource> getObjectType() {
return DataSource.class;
}
public void setInitScripts(Resource[] initScripts) {
this.initScripts = initScripts;
}
public void setDestroyScript(Resource destroyScript) {
this.destroyScript = destroyScript;
public void setDestroyScripts(Resource[] destroyScripts) {
this.destroyScripts = destroyScripts;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public void setIgnoreFailedDrop(boolean ignoreFailedDrop) {
this.ignoreFailedDrop = ignoreFailedDrop;
}
}

View File

@@ -4,15 +4,14 @@
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">
<bean id="dataSource" class="test.jdbc.datasource.InitializingDataSourceFactoryBean">
<property name="dataSource">
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:mem:testdb" />
</bean>
</property>
<bean class="test.jdbc.datasource.DataSourceInitializer">
<property name="dataSource" ref="dataSource"/>
<property name="initScripts" value="org/springframework/batch/item/database/init-foo-schema-hsqldb.sql" />
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:mem:testdb" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />

View File

@@ -3,25 +3,20 @@
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">
<bean id="dataSource" class="test.jdbc.datasource.InitializingDataSourceFactoryBean">
<property name="dataSource">
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:mem:testdb" />
</bean>
</property>
<bean class="test.jdbc.datasource.DataSourceInitializer">
<property name="dataSource" ref="dataSource"/>
<property name="initScripts" value="org/springframework/batch/item/database/init-foo-schema-hsqldb.sql" />
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:mem:testdb" />
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="incrementerParent" class="org.springframework.jdbc.support.incrementer.HsqlMaxValueIncrementer"
abstract="true">
<property name="dataSource" ref="dataSource" />
<property name="columnName" value="ID" />
</bean>
</beans>

View File

@@ -3,7 +3,7 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="dataSourceInitializer" class="test.jdbc.datasource.InitializingDataSourceFactoryBean" autowire-candidate="false">
<bean id="dataSourceInitializer" class="test.jdbc.datasource.DataSourceInitializer">
<property name="dataSource" ref="dataSource"/>
<property name="initScripts">
<list>

View File

@@ -0,0 +1,191 @@
/*
* Copyright 2006-2007 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 test.jdbc.datasource;
import java.io.IOException;
import java.util.List;
import javax.sql.DataSource;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
/**
* Wrapper for a {@link DataSource} that can run scripts on start up and shut
* down. Us as a bean definition <br/><br/>
*
* Run this class to initialize a database in a running server process.
* Make sure the server is running first by launching the "hsql-server" from the
* <code>hsql.server</code> project. Then you can right click in Eclipse and
* Run As -&gt; Java Application. Do the same any time you want to wipe the
* database and start again.
*
* @author Dave Syer
*
*/
public class DataSourceInitializer implements InitializingBean, DisposableBean {
private static final Log logger = LogFactory.getLog(DataSourceInitializer.class);
private Resource[] initScripts;
private Resource[] destroyScripts;
private DataSource dataSource;
private boolean ignoreFailedDrop = true;
private static boolean initialized = false;
/**
* Main method as convenient entry point.
*
* @param args
*/
public static void main(String... args) {
new ClassPathXmlApplicationContext(ClassUtils.addResourcePathToPackagePath(DataSourceInitializer.class,
DataSourceInitializer.class.getSimpleName() + "-context.xml"));
}
/**
* @throws Throwable
* @see java.lang.Object#finalize()
*/
protected void finalize() throws Throwable {
super.finalize();
initialized = false;
logger.debug("finalize called");
}
public void destroy() {
if (destroyScripts==null) return;
for (int i = 0; i < destroyScripts.length; i++) {
Resource destroyScript = initScripts[i];
try {
doExecuteScript(destroyScript);
}
catch (Exception e) {
if (logger.isDebugEnabled()) {
logger.warn("Could not execute destroy script [" + destroyScript + "]", e);
}
else {
logger.warn("Could not execute destroy script [" + destroyScript + "]");
}
}
}
}
public void afterPropertiesSet() throws Exception {
Assert.notNull(dataSource);
initialize();
}
private void initialize() {
if (!initialized) {
destroy();
if (initScripts != null) {
for (int i = 0; i < initScripts.length; i++) {
Resource initScript = initScripts[i];
doExecuteScript(initScript);
}
}
initialized = true;
}
}
private void doExecuteScript(final Resource scriptResource) {
if (scriptResource == null || !scriptResource.exists())
return;
TransactionTemplate transactionTemplate = new TransactionTemplate(new DataSourceTransactionManager(dataSource));
transactionTemplate.execute(new TransactionCallback() {
@SuppressWarnings("unchecked")
public Object doInTransaction(TransactionStatus status) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
String[] scripts;
try {
scripts = StringUtils.delimitedListToStringArray(stripComments(IOUtils.readLines(scriptResource
.getInputStream())), ";");
}
catch (IOException e) {
throw new BeanInitializationException("Cannot load script from [" + scriptResource + "]", e);
}
for (int i = 0; i < scripts.length; i++) {
String script = scripts[i].trim();
if (StringUtils.hasText(script)) {
try {
jdbcTemplate.execute(script);
}
catch (DataAccessException e) {
if (ignoreFailedDrop && script.toLowerCase().startsWith("drop")) {
logger.debug("DROP script failed (ignoring): " + script);
}
else {
throw e;
}
}
}
}
return null;
}
});
}
private String stripComments(List<String> list) {
StringBuffer buffer = new StringBuffer();
for (String line : list) {
if (!line.startsWith("//") && !line.startsWith("--")) {
buffer.append(line + "\n");
}
}
return buffer.toString();
}
public void setInitScripts(Resource[] initScripts) {
this.initScripts = initScripts;
}
public void setDestroyScripts(Resource[] destroyScripts) {
this.destroyScripts = destroyScripts;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public void setIgnoreFailedDrop(boolean ignoreFailedDrop) {
this.ignoreFailedDrop = ignoreFailedDrop;
}
}