Fix assumption about file-based Resources in PropertiesLoaderSupport (SPR-7547)

When using PropertiesLoaderSupport implementations (principally
PropertyPlaceholderConfigurer), an assumption was made that any
Resource representing a set of properties must be file-based.  SPR-7547
exposed the fact that if a non-file-based Resource implementation such
as ByteArrayResource were passed in, an IllegalStateException would be thrown
from the AbstractResource base class' implementation of getFilename().

This is now patched, and PropertiesLoaderSupport implementations treat
Resource implementations equally, regardless of file-orientation.

See also SPR-7552.
This commit is contained in:
Chris Beams 2010-09-13 20:23:26 +00:00
parent 334a294e2a
commit 05bcc4028d
3 changed files with 54 additions and 1 deletions

View File

@ -0,0 +1,44 @@
package org.springframework.beans.factory.config;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.rootBeanDefinition;
import org.junit.Test;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.core.io.ByteArrayResource;
import test.beans.TestBean;
/**
* Tests cornering SPR-7547.
*
* @author Chris Beams
*/
public class PropertyPlaceholderConfigurerTests {
/**
* Prior to the fix for SPR-7547, the following would throw
* IllegalStateException because the PropertiesLoaderSupport base class
* assumed ByteArrayResource implements Resource.getFilename(). It does
* not, and AbstractResource.getFilename() is called instead, raising the
* exception. The following now works, as getFilename() is called in a
* try/catch to check whether the resource is actually file-based or not.
*
* See SPR-7552, which suggests paths to address the root issue rather than
* just patching the problem.
*/
@Test
public void repro() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.registerBeanDefinition("testBean",
rootBeanDefinition(TestBean.class)
.addPropertyValue("name", "${my.name}").getBeanDefinition());
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
ppc.setLocation(new ByteArrayResource("my.name=Inigo Montoya".getBytes()));
ppc.postProcessBeanFactory(bf);
TestBean testBean = bf.getBean(TestBean.class);
assertThat(testBean.getName(), equalTo("Inigo Montoya"));
}
}

View File

@ -179,7 +179,15 @@ public abstract class PropertiesLoaderSupport {
InputStream is = null;
try {
is = location.getInputStream();
if (location.getFilename().endsWith(XML_FILE_EXTENSION)) {
String filename = null;
try {
filename = location.getFilename();
} catch (IllegalStateException ex) {
// resource is not file-based. See SPR-7552.
}
if (filename != null && filename.endsWith(XML_FILE_EXTENSION)) {
this.propertiesPersister.loadFromXml(props, is);
}
else {

View File

@ -0,0 +1 @@
../images