general polishing (backported from 3.1)
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2011 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.
|
||||
@@ -19,6 +19,8 @@ package org.springframework.jdbc.config;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
@@ -28,34 +30,31 @@ import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactoryBean;
|
||||
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.xml.DomUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.beans.factory.xml.BeanDefinitionParser} that parses {@code embedded-database} element and
|
||||
* creates a {@link BeanDefinition} for {@link EmbeddedDatabaseFactoryBean}. Picks up nested {@code script} elements and
|
||||
* configures a {@link ResourceDatabasePopulator} for them.
|
||||
*
|
||||
* {@link org.springframework.beans.factory.xml.BeanDefinitionParser} that parses an {@code embedded-database}
|
||||
* element and creates a {@link BeanDefinition} for {@link EmbeddedDatabaseFactoryBean}. Picks up nested
|
||||
* {@code script} elements and configures a {@link ResourceDatabasePopulator} for them.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @since 3.0
|
||||
*/
|
||||
class EmbeddedDatabaseBeanDefinitionParser extends AbstractBeanDefinitionParser {
|
||||
|
||||
private static final String NAME_PROPERTY = "databaseName";
|
||||
|
||||
@Override
|
||||
protected AbstractBeanDefinition parseInternal(Element element, ParserContext context) {
|
||||
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(EmbeddedDatabaseFactoryBean.class);
|
||||
setDatabaseType(element, builder);
|
||||
setDatabasePopulator(element, context, builder);
|
||||
setDatabasePopulator(element, builder);
|
||||
useIdAsDatabaseNameIfGiven(element, builder);
|
||||
return getSourcedBeanDefinition(builder, element, context);
|
||||
builder.getRawBeanDefinition().setSource(parserContext.extractSource(element));
|
||||
return builder.getBeanDefinition();
|
||||
}
|
||||
|
||||
private void useIdAsDatabaseNameIfGiven(Element element, BeanDefinitionBuilder builder) {
|
||||
|
||||
String id = element.getAttribute(ID_ATTRIBUTE);
|
||||
if (StringUtils.hasText(id)) {
|
||||
builder.addPropertyValue(NAME_PROPERTY, id);
|
||||
builder.addPropertyValue("databaseName", id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,34 +65,24 @@ class EmbeddedDatabaseBeanDefinitionParser extends AbstractBeanDefinitionParser
|
||||
}
|
||||
}
|
||||
|
||||
private void setDatabasePopulator(Element element, ParserContext context, BeanDefinitionBuilder builder) {
|
||||
private void setDatabasePopulator(Element element, BeanDefinitionBuilder builder) {
|
||||
List<Element> scripts = DomUtils.getChildElementsByTagName(element, "script");
|
||||
if (scripts.size() > 0) {
|
||||
builder.addPropertyValue("databasePopulator", createDatabasePopulator(scripts, context));
|
||||
builder.addPropertyValue("databasePopulator", createDatabasePopulator(scripts));
|
||||
}
|
||||
}
|
||||
|
||||
private BeanDefinition createDatabasePopulator(List<Element> scripts, ParserContext context) {
|
||||
private BeanDefinition createDatabasePopulator(List<Element> scripts) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(ResourceDatabasePopulator.class);
|
||||
List<String> locations = new ArrayList<String>();
|
||||
for (Element scriptElement : scripts) {
|
||||
locations.add(scriptElement.getAttribute("location"));
|
||||
}
|
||||
// Use a factory bean for the resources so they can be given an order if a pattern is used
|
||||
BeanDefinitionBuilder resourcesFactory = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(SortedResourcesFactoryBean.class);
|
||||
BeanDefinitionBuilder resourcesFactory = BeanDefinitionBuilder.genericBeanDefinition(SortedResourcesFactoryBean.class);
|
||||
resourcesFactory.addConstructorArgValue(locations);
|
||||
builder.addPropertyValue("scripts", resourcesFactory.getBeanDefinition());
|
||||
|
||||
return builder.getBeanDefinition();
|
||||
}
|
||||
|
||||
private AbstractBeanDefinition getSourcedBeanDefinition(
|
||||
BeanDefinitionBuilder builder, Element source, ParserContext context) {
|
||||
|
||||
AbstractBeanDefinition definition = builder.getBeanDefinition();
|
||||
definition.setSource(context.extractSource(source));
|
||||
return definition;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2011 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.
|
||||
@@ -19,6 +19,8 @@ package org.springframework.jdbc.config;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
@@ -27,24 +29,25 @@ import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
|
||||
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
|
||||
import org.springframework.util.xml.DomUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.beans.factory.xml.BeanDefinitionParser} that parses an {@code initialize-database} element and
|
||||
* creates a {@link BeanDefinition} of type {@link DataSourceInitializer}. Picks up nested {@code script} elements and
|
||||
* configures a {@link ResourceDatabasePopulator} for them.
|
||||
* {@link org.springframework.beans.factory.xml.BeanDefinitionParser} that parses an {@code initialize-database}
|
||||
* element and creates a {@link BeanDefinition} of type {@link DataSourceInitializer}. Picks up nested
|
||||
* {@code script} elements and configures a {@link ResourceDatabasePopulator} for them.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @since 3.0
|
||||
*/
|
||||
public class InitializeDatabaseBeanDefinitionParser extends AbstractBeanDefinitionParser {
|
||||
|
||||
@Override
|
||||
protected AbstractBeanDefinition parseInternal(Element element, ParserContext context) {
|
||||
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(DataSourceInitializer.class);
|
||||
builder.addPropertyReference("dataSource", element.getAttribute("data-source"));
|
||||
builder.addPropertyValue("enabled", element.getAttribute("enabled"));
|
||||
setDatabasePopulator(element, context, builder);
|
||||
return getSourcedBeanDefinition(builder, element, context);
|
||||
setDatabasePopulator(element, builder);
|
||||
builder.getRawBeanDefinition().setSource(parserContext.extractSource(element));
|
||||
return builder.getBeanDefinition();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -52,14 +55,14 @@ public class InitializeDatabaseBeanDefinitionParser extends AbstractBeanDefiniti
|
||||
return true;
|
||||
}
|
||||
|
||||
private void setDatabasePopulator(Element element, ParserContext context, BeanDefinitionBuilder builder) {
|
||||
private void setDatabasePopulator(Element element, BeanDefinitionBuilder builder) {
|
||||
List<Element> scripts = DomUtils.getChildElementsByTagName(element, "script");
|
||||
if (scripts.size() > 0) {
|
||||
builder.addPropertyValue("databasePopulator", createDatabasePopulator(element, scripts, context));
|
||||
builder.addPropertyValue("databasePopulator", createDatabasePopulator(element, scripts));
|
||||
}
|
||||
}
|
||||
|
||||
private BeanDefinition createDatabasePopulator(Element element, List<Element> scripts, ParserContext context) {
|
||||
private BeanDefinition createDatabasePopulator(Element element, List<Element> scripts) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(ResourceDatabasePopulator.class);
|
||||
builder.addPropertyValue("ignoreFailedDrops", element.getAttribute("ignore-failures").equals("DROPS"));
|
||||
builder.addPropertyValue("continueOnError", element.getAttribute("ignore-failures").equals("ALL"));
|
||||
@@ -71,19 +74,11 @@ public class InitializeDatabaseBeanDefinitionParser extends AbstractBeanDefiniti
|
||||
}
|
||||
|
||||
// Use a factory bean for the resources so they can be given an order if a pattern is used
|
||||
BeanDefinitionBuilder resourcesFactory = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(SortedResourcesFactoryBean.class);
|
||||
BeanDefinitionBuilder resourcesFactory = BeanDefinitionBuilder.genericBeanDefinition(SortedResourcesFactoryBean.class);
|
||||
resourcesFactory.addConstructorArgValue(locations);
|
||||
builder.addPropertyValue("scripts", resourcesFactory.getBeanDefinition());
|
||||
|
||||
return builder.getBeanDefinition();
|
||||
}
|
||||
|
||||
private AbstractBeanDefinition getSourcedBeanDefinition(BeanDefinitionBuilder builder, Element source,
|
||||
ParserContext context) {
|
||||
AbstractBeanDefinition definition = builder.getBeanDefinition();
|
||||
definition.setSource(context.extractSource(source));
|
||||
return definition;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2011 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.
|
||||
@@ -68,6 +68,16 @@ public class EmbeddedDatabaseFactory {
|
||||
this.databaseName = databaseName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, "DataSourceFactory is required");
|
||||
this.dataSourceFactory = dataSourceFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the type of embedded database to use. Call this when you wish to configure
|
||||
* one of the pre-supported types. Defaults to HSQL.
|
||||
@@ -83,7 +93,6 @@ public class EmbeddedDatabaseFactory {
|
||||
* @param configurer the embedded database configurer
|
||||
*/
|
||||
public void setDatabaseConfigurer(EmbeddedDatabaseConfigurer configurer) {
|
||||
Assert.notNull(configurer, "EmbeddedDatabaseConfigurer is required");
|
||||
this.databaseConfigurer = configurer;
|
||||
}
|
||||
|
||||
@@ -92,20 +101,9 @@ public class EmbeddedDatabaseFactory {
|
||||
* @param populator the database populator
|
||||
*/
|
||||
public void setDatabasePopulator(DatabasePopulator populator) {
|
||||
Assert.notNull(populator, "DatabasePopulator is required");
|
||||
this.databasePopulator = populator;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, "DataSourceFactory is required");
|
||||
this.dataSourceFactory = dataSourceFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method that returns the embedded database instance.
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
/**
|
||||
*
|
||||
* Provides extensible support for creating embedded database instances.
|
||||
* HSQL in-memory support provided natively
|
||||
*
|
||||
*/
|
||||
package org.springframework.jdbc.datasource.embedded;
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
/**
|
||||
*
|
||||
* Provides extensible support for initializing databases through scripts.
|
||||
*
|
||||
*/
|
||||
package org.springframework.jdbc.datasource.init;
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports type="javax.sql.DataSource" />
|
||||
<tool:exports type="javax.sql.DataSource"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -26,8 +26,7 @@
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="beans:identifiedType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="script" type="scriptType"
|
||||
minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element name="script" type="scriptType" minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A SQL script to execute during embedded database initialization.
|
||||
@@ -35,8 +34,7 @@
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="type" type="databaseType"
|
||||
default="HSQL">
|
||||
<xsd:attribute name="type" type="databaseType" default="HSQL">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The type of embedded database to create, such as HSQL, H2 or Derby. Defaults to HSQL.
|
||||
@@ -50,36 +48,32 @@
|
||||
|
||||
<xsd:element name="initialize-database">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation
|
||||
source="java:org.springframework.jdbc.embedded.DataSourceInitializer"><![CDATA[
|
||||
<xsd:documentation source="java:org.springframework.jdbc.embedded.DataSourceInitializer"><![CDATA[
|
||||
Initializes a database instance with SQL scripts provided in nested <script/> elements.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="script" type="scriptType" minOccurs="1"
|
||||
maxOccurs="unbounded">
|
||||
<xsd:element name="script" type="scriptType" minOccurs="1" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A SQL script to execute during database initialization.
|
||||
]]></xsd:documentation>
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="data-source" type="xsd:string"
|
||||
default="dataSource">
|
||||
<xsd:attribute name="data-source" type="xsd:string" default="dataSource">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A reference to a data source that should be initialized. Defaults to "dataSource".
|
||||
]]></xsd:documentation>
|
||||
A reference to a data source that should be initialized. Defaults to "dataSource".
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref" />
|
||||
<tool:expected-type type="javax.sql.DataSource" />
|
||||
<tool:annotation kind="ref"/>
|
||||
<tool:expected-type type="javax.sql.DataSource"/>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="enabled" type="xsd:string" use="optional"
|
||||
default="true">
|
||||
<xsd:attribute name="enabled" type="xsd:string" use="optional" default="true">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Is this bean "enabled", meaning the scripts will be executed?
|
||||
@@ -87,8 +81,7 @@
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="ignore-failures" use="optional"
|
||||
default="NONE">
|
||||
<xsd:attribute name="ignore-failures" use="optional" default="NONE">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Should failed SQL statements be ignored during initialization?
|
||||
@@ -159,4 +152,4 @@
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
</xsd:schema>
|
||||
</xsd:schema>
|
||||
|
||||
@@ -1,21 +1,40 @@
|
||||
package org.springframework.jdbc.config;
|
||||
/*
|
||||
* Copyright 2002-2011 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.
|
||||
*/
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
package org.springframework.jdbc.config;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.jdbc.BadSqlGrammarException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
public class InitializeDatabaseIntegrationTest {
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class InitializeDatabaseIntegrationTests {
|
||||
|
||||
private String enabled;
|
||||
private ClassPathXmlApplicationContext context;
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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.config;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
@@ -15,7 +31,10 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
public class JdbcNamespaceIntegrationTest {
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class JdbcNamespaceIntegrationTests {
|
||||
|
||||
@Test
|
||||
public void testCreateEmbeddedDatabase() throws Exception {
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
<!-- This cache relies on data created in the initialize-database element. It works fine
|
||||
if the bean definitions are registered in the right order. (Could possibly be fixed later.) -->
|
||||
<bean class="org.springframework.jdbc.config.InitializeDatabaseIntegrationTest$CacheData">
|
||||
<bean class="org.springframework.jdbc.config.InitializeDatabaseIntegrationTests$CacheData">
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
</bean>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user