Skip to content

Commit 7519162

Browse files
author
David Syer
committed
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.
1 parent 3f65721 commit 7519162

File tree

5 files changed

+115
-76
lines changed

5 files changed

+115
-76
lines changed

org.springframework.jdbc/src/main/java/org/springframework/jdbc/config/EmbeddedDatabaseBeanDefinitionParser.java

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,15 @@
1616

1717
package org.springframework.jdbc.config;
1818

19+
import java.util.ArrayList;
1920
import java.util.List;
2021

2122
import org.springframework.beans.factory.config.BeanDefinition;
2223
import org.springframework.beans.factory.support.AbstractBeanDefinition;
2324
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
2425
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
2526
import org.springframework.beans.factory.xml.ParserContext;
26-
import org.springframework.core.io.Resource;
2727
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactoryBean;
28-
import org.springframework.jdbc.datasource.init.DatabasePopulator;
2928
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
3029
import org.springframework.util.StringUtils;
3130
import org.springframework.util.xml.DomUtils;
@@ -62,13 +61,25 @@ private void setDatabasePopulator(Element element, ParserContext context, BeanDe
6261
}
6362
}
6463

65-
private DatabasePopulator createDatabasePopulator(List<Element> scripts, ParserContext context) {
66-
ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
64+
private BeanDefinition createDatabasePopulator(List<Element> scripts, ParserContext context) {
65+
66+
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(ResourceDatabasePopulator.class);
67+
68+
List<String> locations = new ArrayList<String>();
6769
for (Element scriptElement : scripts) {
68-
Resource script = context.getReaderContext().getResourceLoader().getResource(scriptElement.getAttribute("location"));
69-
populator.addScript(script);
70+
String location = scriptElement.getAttribute("location");
71+
locations.add(location);
7072
}
71-
return populator;
73+
74+
// Use a factory bean for the resources so they can be given an order if a pattern is used
75+
BeanDefinitionBuilder resourcesFactory = BeanDefinitionBuilder
76+
.genericBeanDefinition(SortedResourcesFactoryBean.class);
77+
resourcesFactory.addConstructorArgValue(context.getReaderContext().getResourceLoader());
78+
resourcesFactory.addConstructorArgValue(locations);
79+
builder.addPropertyValue("scripts", resourcesFactory.getBeanDefinition());
80+
81+
return builder.getBeanDefinition();
82+
7283
}
7384

7485
private AbstractBeanDefinition getSourcedBeanDefinition(BeanDefinitionBuilder builder, Element source,

org.springframework.jdbc/src/main/java/org/springframework/jdbc/config/InitializeDatabaseBeanDefinitionParser.java

Lines changed: 1 addition & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,14 @@
1616

1717
package org.springframework.jdbc.config;
1818

19-
import java.io.IOException;
2019
import java.util.ArrayList;
21-
import java.util.Arrays;
22-
import java.util.Collections;
23-
import java.util.Comparator;
2420
import java.util.List;
2521

26-
import org.apache.commons.logging.Log;
27-
import org.apache.commons.logging.LogFactory;
28-
import org.springframework.beans.factory.FactoryBean;
2922
import org.springframework.beans.factory.config.BeanDefinition;
3023
import org.springframework.beans.factory.support.AbstractBeanDefinition;
3124
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
3225
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
3326
import org.springframework.beans.factory.xml.ParserContext;
34-
import org.springframework.core.io.Resource;
35-
import org.springframework.core.io.ResourceLoader;
36-
import org.springframework.core.io.support.ResourcePatternResolver;
3727
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
3828
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
3929
import org.springframework.util.xml.DomUtils;
@@ -80,7 +70,7 @@ private BeanDefinition createDatabasePopulator(Element element, List<Element> sc
8070
locations.add(location);
8171
}
8272

83-
// Use a factor bean for the resources so they can be given an order if a pattern is used
73+
// Use a factory bean for the resources so they can be given an order if a pattern is used
8474
BeanDefinitionBuilder resourcesFactory = BeanDefinitionBuilder
8575
.genericBeanDefinition(SortedResourcesFactoryBean.class);
8676
resourcesFactory.addConstructorArgValue(context.getReaderContext().getResourceLoader());
@@ -97,62 +87,4 @@ private AbstractBeanDefinition getSourcedBeanDefinition(BeanDefinitionBuilder bu
9787
return definition;
9888
}
9989

100-
public static class SortedResourcesFactoryBean implements FactoryBean<Resource[]> {
101-
102-
private static final Log logger = LogFactory.getLog(SortedResourcesFactoryBean.class);
103-
104-
private ResourceLoader resourceLoader;
105-
106-
private List<String> locations;
107-
108-
public SortedResourcesFactoryBean(ResourceLoader resourceLoader, List<String> locations) {
109-
super();
110-
this.resourceLoader = resourceLoader;
111-
this.locations = locations;
112-
}
113-
114-
public Resource[] getObject() throws Exception {
115-
List<Resource> scripts = new ArrayList<Resource>();
116-
for (String location : locations) {
117-
118-
if (logger.isDebugEnabled()) {
119-
logger.debug("Adding resources from pattern: " + location);
120-
}
121-
122-
if (resourceLoader instanceof ResourcePatternResolver) {
123-
List<Resource> resources = new ArrayList<Resource>(Arrays
124-
.asList(((ResourcePatternResolver) resourceLoader).getResources(location)));
125-
Collections.<Resource> sort(resources, new Comparator<Resource>() {
126-
public int compare(Resource o1, Resource o2) {
127-
try {
128-
return o1.getURL().toString().compareTo(o2.getURL().toString());
129-
} catch (IOException e) {
130-
return 0;
131-
}
132-
}
133-
});
134-
for (Resource resource : resources) {
135-
scripts.add(resource);
136-
}
137-
138-
} else {
139-
scripts.add(resourceLoader.getResource(location));
140-
}
141-
142-
}
143-
return scripts.toArray(new Resource[scripts.size()]);
144-
}
145-
146-
public Class<? extends Resource[]> getObjectType() {
147-
// TODO Auto-generated method stub
148-
return null;
149-
}
150-
151-
public boolean isSingleton() {
152-
// TODO Auto-generated method stub
153-
return false;
154-
}
155-
156-
}
157-
15890
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/**
2+
*
3+
*/
4+
package org.springframework.jdbc.config;
5+
6+
import java.io.IOException;
7+
import java.util.ArrayList;
8+
import java.util.Arrays;
9+
import java.util.Collections;
10+
import java.util.Comparator;
11+
import java.util.List;
12+
13+
import org.apache.commons.logging.Log;
14+
import org.apache.commons.logging.LogFactory;
15+
import org.springframework.beans.factory.FactoryBean;
16+
import org.springframework.core.io.Resource;
17+
import org.springframework.core.io.ResourceLoader;
18+
import org.springframework.core.io.support.ResourcePatternResolver;
19+
20+
public class SortedResourcesFactoryBean implements FactoryBean<Resource[]> {
21+
22+
private static final Log logger = LogFactory.getLog(SortedResourcesFactoryBean.class);
23+
24+
private ResourceLoader resourceLoader;
25+
private List<String> locations;
26+
27+
public SortedResourcesFactoryBean(ResourceLoader resourceLoader, List<String> locations) {
28+
super();
29+
this.resourceLoader = resourceLoader;
30+
this.locations = locations;
31+
}
32+
33+
public Resource[] getObject() throws Exception {
34+
List<Resource> scripts = new ArrayList<Resource>();
35+
for (String location : locations) {
36+
37+
if (logger.isDebugEnabled()) {
38+
logger.debug("Adding resources from pattern: "+location);
39+
}
40+
41+
if (resourceLoader instanceof ResourcePatternResolver) {
42+
List<Resource> resources = new ArrayList<Resource>(Arrays
43+
.asList(((ResourcePatternResolver) resourceLoader).getResources(location)));
44+
Collections.<Resource> sort(resources, new Comparator<Resource>() {
45+
public int compare(Resource o1, Resource o2) {
46+
try {
47+
return o1.getURL().toString().compareTo(o2.getURL().toString());
48+
} catch (IOException e) {
49+
return 0;
50+
}
51+
}
52+
});
53+
for (Resource resource : resources) {
54+
scripts.add(resource);
55+
}
56+
57+
} else {
58+
scripts.add(resourceLoader.getResource(location));
59+
}
60+
61+
}
62+
return scripts.toArray(new Resource[scripts.size()]);
63+
}
64+
65+
public Class<? extends Resource[]> getObjectType() {
66+
// TODO Auto-generated method stub
67+
return null;
68+
}
69+
70+
public boolean isSingleton() {
71+
// TODO Auto-generated method stub
72+
return false;
73+
}
74+
75+
}

org.springframework.jdbc/src/test/java/org/springframework/jdbc/config/JdbcNamespaceIntegrationTest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ public void testCreateEmbeddedDatabase() throws Exception {
2020
context.close();
2121
}
2222

23+
@Test
24+
public void testCreateWithResourcePattern() throws Exception {
25+
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
26+
"org/springframework/jdbc/config/jdbc-config-pattern.xml");
27+
assertCorrectSetup(context.getBean("dataSource", DataSource.class));
28+
context.close();
29+
}
30+
2331
private void assertCorrectSetup(DataSource dataSource) {
2432
JdbcTemplate t = new JdbcTemplate(dataSource);
2533
assertEquals(1, t.queryForInt("select count(*) from T_TEST"));
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<beans xmlns="http://www.springframework.org/schema/beans"
3+
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
6+
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd">
7+
8+
<jdbc:embedded-database id="dataSource">
9+
<jdbc:script location="classpath:org/springframework/jdbc/config/db-schema.sql"/>
10+
<jdbc:script location="classpath:org/springframework/jdbc/config/*-data.sql"/>
11+
</jdbc:embedded-database>
12+
13+
</beans>

0 commit comments

Comments
 (0)