RESOLVED - issue SPR-6365: spring-jdbc.xsd script element claims resource patterns can be used for any SQL resource location but this is only supported for initialize-database tag
Added resource pattern feature to embedded datasource XML parser.
This commit is contained in:
parent
3f65721ba8
commit
7519162e65
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
package org.springframework.jdbc.config;
|
package org.springframework.jdbc.config;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
|
@ -23,9 +24,7 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||||
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
|
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
|
||||||
import org.springframework.beans.factory.xml.ParserContext;
|
import org.springframework.beans.factory.xml.ParserContext;
|
||||||
import org.springframework.core.io.Resource;
|
|
||||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactoryBean;
|
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactoryBean;
|
||||||
import org.springframework.jdbc.datasource.init.DatabasePopulator;
|
|
||||||
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
|
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.util.xml.DomUtils;
|
import org.springframework.util.xml.DomUtils;
|
||||||
|
|
@ -62,13 +61,25 @@ public class EmbeddedDatabaseBeanDefinitionParser extends AbstractBeanDefinition
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private DatabasePopulator createDatabasePopulator(List<Element> scripts, ParserContext context) {
|
private BeanDefinition createDatabasePopulator(List<Element> scripts, ParserContext context) {
|
||||||
ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
|
|
||||||
|
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(ResourceDatabasePopulator.class);
|
||||||
|
|
||||||
|
List<String> locations = new ArrayList<String>();
|
||||||
for (Element scriptElement : scripts) {
|
for (Element scriptElement : scripts) {
|
||||||
Resource script = context.getReaderContext().getResourceLoader().getResource(scriptElement.getAttribute("location"));
|
String location = scriptElement.getAttribute("location");
|
||||||
populator.addScript(script);
|
locations.add(location);
|
||||||
}
|
}
|
||||||
return populator;
|
|
||||||
|
// 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);
|
||||||
|
resourcesFactory.addConstructorArgValue(context.getReaderContext().getResourceLoader());
|
||||||
|
resourcesFactory.addConstructorArgValue(locations);
|
||||||
|
builder.addPropertyValue("scripts", resourcesFactory.getBeanDefinition());
|
||||||
|
|
||||||
|
return builder.getBeanDefinition();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private AbstractBeanDefinition getSourcedBeanDefinition(BeanDefinitionBuilder builder, Element source,
|
private AbstractBeanDefinition getSourcedBeanDefinition(BeanDefinitionBuilder builder, Element source,
|
||||||
|
|
|
||||||
|
|
@ -16,24 +16,14 @@
|
||||||
|
|
||||||
package org.springframework.jdbc.config;
|
package org.springframework.jdbc.config;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
import org.springframework.beans.factory.FactoryBean;
|
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||||
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
|
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
|
||||||
import org.springframework.beans.factory.xml.ParserContext;
|
import org.springframework.beans.factory.xml.ParserContext;
|
||||||
import org.springframework.core.io.Resource;
|
|
||||||
import org.springframework.core.io.ResourceLoader;
|
|
||||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
|
||||||
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
|
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
|
||||||
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
|
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
|
||||||
import org.springframework.util.xml.DomUtils;
|
import org.springframework.util.xml.DomUtils;
|
||||||
|
|
@ -80,7 +70,7 @@ public class InitializeDatabaseBeanDefinitionParser extends AbstractBeanDefiniti
|
||||||
locations.add(location);
|
locations.add(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use a factor bean for the resources so they can be given an order if a pattern is used
|
// Use a factory bean for the resources so they can be given an order if a pattern is used
|
||||||
BeanDefinitionBuilder resourcesFactory = BeanDefinitionBuilder
|
BeanDefinitionBuilder resourcesFactory = BeanDefinitionBuilder
|
||||||
.genericBeanDefinition(SortedResourcesFactoryBean.class);
|
.genericBeanDefinition(SortedResourcesFactoryBean.class);
|
||||||
resourcesFactory.addConstructorArgValue(context.getReaderContext().getResourceLoader());
|
resourcesFactory.addConstructorArgValue(context.getReaderContext().getResourceLoader());
|
||||||
|
|
@ -97,62 +87,4 @@ public class InitializeDatabaseBeanDefinitionParser extends AbstractBeanDefiniti
|
||||||
return definition;
|
return definition;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class SortedResourcesFactoryBean implements FactoryBean<Resource[]> {
|
|
||||||
|
|
||||||
private static final Log logger = LogFactory.getLog(SortedResourcesFactoryBean.class);
|
|
||||||
|
|
||||||
private ResourceLoader resourceLoader;
|
|
||||||
|
|
||||||
private List<String> locations;
|
|
||||||
|
|
||||||
public SortedResourcesFactoryBean(ResourceLoader resourceLoader, List<String> locations) {
|
|
||||||
super();
|
|
||||||
this.resourceLoader = resourceLoader;
|
|
||||||
this.locations = locations;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Resource[] getObject() throws Exception {
|
|
||||||
List<Resource> scripts = new ArrayList<Resource>();
|
|
||||||
for (String location : locations) {
|
|
||||||
|
|
||||||
if (logger.isDebugEnabled()) {
|
|
||||||
logger.debug("Adding resources from pattern: " + location);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resourceLoader instanceof ResourcePatternResolver) {
|
|
||||||
List<Resource> resources = new ArrayList<Resource>(Arrays
|
|
||||||
.asList(((ResourcePatternResolver) resourceLoader).getResources(location)));
|
|
||||||
Collections.<Resource> sort(resources, new Comparator<Resource>() {
|
|
||||||
public int compare(Resource o1, Resource o2) {
|
|
||||||
try {
|
|
||||||
return o1.getURL().toString().compareTo(o2.getURL().toString());
|
|
||||||
} catch (IOException e) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
for (Resource resource : resources) {
|
|
||||||
scripts.add(resource);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
scripts.add(resourceLoader.getResource(location));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return scripts.toArray(new Resource[scripts.size()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Class<? extends Resource[]> getObjectType() {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSingleton() {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.springframework.jdbc.config;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.springframework.beans.factory.FactoryBean;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
|
import org.springframework.core.io.ResourceLoader;
|
||||||
|
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||||
|
|
||||||
|
public class SortedResourcesFactoryBean implements FactoryBean<Resource[]> {
|
||||||
|
|
||||||
|
private static final Log logger = LogFactory.getLog(SortedResourcesFactoryBean.class);
|
||||||
|
|
||||||
|
private ResourceLoader resourceLoader;
|
||||||
|
private List<String> locations;
|
||||||
|
|
||||||
|
public SortedResourcesFactoryBean(ResourceLoader resourceLoader, List<String> locations) {
|
||||||
|
super();
|
||||||
|
this.resourceLoader = resourceLoader;
|
||||||
|
this.locations = locations;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Resource[] getObject() throws Exception {
|
||||||
|
List<Resource> scripts = new ArrayList<Resource>();
|
||||||
|
for (String location : locations) {
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("Adding resources from pattern: "+location);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resourceLoader instanceof ResourcePatternResolver) {
|
||||||
|
List<Resource> resources = new ArrayList<Resource>(Arrays
|
||||||
|
.asList(((ResourcePatternResolver) resourceLoader).getResources(location)));
|
||||||
|
Collections.<Resource> sort(resources, new Comparator<Resource>() {
|
||||||
|
public int compare(Resource o1, Resource o2) {
|
||||||
|
try {
|
||||||
|
return o1.getURL().toString().compareTo(o2.getURL().toString());
|
||||||
|
} catch (IOException e) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
for (Resource resource : resources) {
|
||||||
|
scripts.add(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
scripts.add(resourceLoader.getResource(location));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return scripts.toArray(new Resource[scripts.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Class<? extends Resource[]> getObjectType() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSingleton() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -20,6 +20,14 @@ public class JdbcNamespaceIntegrationTest {
|
||||||
context.close();
|
context.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateWithResourcePattern() throws Exception {
|
||||||
|
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||||
|
"org/springframework/jdbc/config/jdbc-config-pattern.xml");
|
||||||
|
assertCorrectSetup(context.getBean("dataSource", DataSource.class));
|
||||||
|
context.close();
|
||||||
|
}
|
||||||
|
|
||||||
private void assertCorrectSetup(DataSource dataSource) {
|
private void assertCorrectSetup(DataSource dataSource) {
|
||||||
JdbcTemplate t = new JdbcTemplate(dataSource);
|
JdbcTemplate t = new JdbcTemplate(dataSource);
|
||||||
assertEquals(1, t.queryForInt("select count(*) from T_TEST"));
|
assertEquals(1, t.queryForInt("select count(*) from T_TEST"));
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
|
||||||
|
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.xsd
|
||||||
|
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd">
|
||||||
|
|
||||||
|
<jdbc:embedded-database id="dataSource">
|
||||||
|
<jdbc:script location="classpath:org/springframework/jdbc/config/db-schema.sql"/>
|
||||||
|
<jdbc:script location="classpath:org/springframework/jdbc/config/*-data.sql"/>
|
||||||
|
</jdbc:embedded-database>
|
||||||
|
|
||||||
|
</beans>
|
||||||
Loading…
Reference in New Issue