提交 2c637dcb 编写于 作者: J Juergen Hoeller

ReaderEditor supports Reader injection analogous to InputStreamEditor (from...

ReaderEditor supports Reader injection analogous to InputStreamEditor (from Spring resource location)

Also, EncodedResource implements InputStreamSource now since it declares getInputStream() anyway.

Issue: SPR-12876
上级 ceb17fca
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2015 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,7 @@ package org.springframework.beans;
import java.beans.PropertyEditor;
import java.io.File;
import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URI;
......@@ -60,6 +61,7 @@ import org.springframework.beans.propertyeditors.InputStreamEditor;
import org.springframework.beans.propertyeditors.LocaleEditor;
import org.springframework.beans.propertyeditors.PatternEditor;
import org.springframework.beans.propertyeditors.PropertiesEditor;
import org.springframework.beans.propertyeditors.ReaderEditor;
import org.springframework.beans.propertyeditors.StringArrayPropertyEditor;
import org.springframework.beans.propertyeditors.TimeZoneEditor;
import org.springframework.beans.propertyeditors.URIEditor;
......@@ -211,6 +213,7 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
this.defaultEditors.put(Locale.class, new LocaleEditor());
this.defaultEditors.put(Pattern.class, new PatternEditor());
this.defaultEditors.put(Properties.class, new PropertiesEditor());
this.defaultEditors.put(Reader.class, new ReaderEditor());
this.defaultEditors.put(Resource[].class, new ResourceArrayPropertyEditor());
this.defaultEditors.put(TimeZone.class, new TimeZoneEditor());
this.defaultEditors.put(URI.class, new URIEditor());
......
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2015 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.
......@@ -25,13 +25,13 @@ import org.springframework.util.Assert;
/**
* One-way PropertyEditor which can convert from a text String to a
* {@code java.io.InputStream}, interpreting the given String
* as Spring resource location (e.g. a URL String).
* {@code java.io.InputStream}, interpreting the given String as a
* Spring resource location (e.g. a URL String).
*
* <p>Supports Spring-style URL notation: any fully qualified standard URL
* ("file:", "http:", etc) and Spring's special "classpath:" pseudo-URL.
*
* <p>Note that in the default usage, the stream is not closed by Spring itself!
* <p>Note that such streams do usually not get closed by Spring itself!
*
* @author Juergen Hoeller
* @since 1.0.1
......@@ -73,8 +73,7 @@ public class InputStreamEditor extends PropertyEditorSupport {
setValue(resource != null ? resource.getInputStream() : null);
}
catch (IOException ex) {
throw new IllegalArgumentException(
"Could not retrieve InputStream for " + resource + ": " + ex.getMessage());
throw new IllegalArgumentException("Failed to retrieve InputStream for " + resource, ex);
}
}
......
/*
* Copyright 2002-2015 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.beans.propertyeditors;
import java.beans.PropertyEditorSupport;
import java.io.IOException;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceEditor;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.util.Assert;
/**
* One-way PropertyEditor which can convert from a text String to a
* {@code java.io.Reader}, interpreting the given String as a Spring
* resource location (e.g. a URL String).
*
* <p>Supports Spring-style URL notation: any fully qualified standard URL
* ("file:", "http:", etc) and Spring's special "classpath:" pseudo-URL.
*
* <p>Note that such readers do usually not get closed by Spring itself!
*
* @author Juergen Hoeller
* @since 4.2
* @see java.io.Reader
* @see org.springframework.core.io.ResourceEditor
* @see org.springframework.core.io.ResourceLoader
* @see InputStreamEditor
*/
public class ReaderEditor extends PropertyEditorSupport {
private final ResourceEditor resourceEditor;
/**
* Create a new ReaderEditor,
* using the default ResourceEditor underneath.
*/
public ReaderEditor() {
this.resourceEditor = new ResourceEditor();
}
/**
* Create a new ReaderEditor,
* using the given ResourceEditor underneath.
* @param resourceEditor the ResourceEditor to use
*/
public ReaderEditor(ResourceEditor resourceEditor) {
Assert.notNull(resourceEditor, "ResourceEditor must not be null");
this.resourceEditor = resourceEditor;
}
@Override
public void setAsText(String text) throws IllegalArgumentException {
this.resourceEditor.setAsText(text);
Resource resource = (Resource) this.resourceEditor.getValue();
try {
setValue(resource != null ? new EncodedResource(resource).getReader() : null);
}
catch (IOException ex) {
throw new IllegalArgumentException("Failed to retrieve Reader for " + resource, ex);
}
}
/**
* This implementation returns {@code null} to indicate that
* there is no appropriate text representation.
*/
@Override
public String getAsText() {
return null;
}
}
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2015 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,7 @@ package org.springframework.beans.support;
import java.beans.PropertyEditor;
import java.io.File;
import java.io.InputStream;
import java.io.Reader;
import java.net.URI;
import java.net.URL;
......@@ -32,10 +33,10 @@ import org.springframework.beans.propertyeditors.ClassEditor;
import org.springframework.beans.propertyeditors.FileEditor;
import org.springframework.beans.propertyeditors.InputSourceEditor;
import org.springframework.beans.propertyeditors.InputStreamEditor;
import org.springframework.beans.propertyeditors.ReaderEditor;
import org.springframework.beans.propertyeditors.URIEditor;
import org.springframework.beans.propertyeditors.URLEditor;
import org.springframework.core.env.PropertyResolver;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.ContextResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceEditor;
......@@ -102,6 +103,7 @@ public class ResourceEditorRegistrar implements PropertyEditorRegistrar {
doRegisterEditor(registry, InputStream.class, new InputStreamEditor(baseEditor));
doRegisterEditor(registry, InputSource.class, new InputSourceEditor(baseEditor));
doRegisterEditor(registry, File.class, new FileEditor(baseEditor));
doRegisterEditor(registry, Reader.class, new ReaderEditor(baseEditor));
doRegisterEditor(registry, URL.class, new URLEditor(baseEditor));
ClassLoader classLoader = this.resourceLoader.getClassLoader();
......
/*
* Copyright 2002-2006 the original author or authors.
* Copyright 2002-2015 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.
......@@ -30,9 +30,9 @@ import static org.junit.Assert.*;
* @author Rick Evans
* @author Chris Beams
*/
public final class InputStreamEditorTests {
public class InputStreamEditorTests {
@Test(expected=IllegalArgumentException.class)
@Test(expected = IllegalArgumentException.class)
public void testCtorWithNullResourceEditor() throws Exception {
new InputStreamEditor(null);
}
......@@ -41,7 +41,8 @@ public final class InputStreamEditorTests {
public void testSunnyDay() throws Exception {
InputStream stream = null;
try {
String resource = "classpath:" + ClassUtils.classPackageAsResourcePath(getClass()) + "/" + ClassUtils.getShortName(getClass()) + ".class";
String resource = "classpath:" + ClassUtils.classPackageAsResourcePath(getClass()) +
"/" + ClassUtils.getShortName(getClass()) + ".class";
InputStreamEditor editor = new InputStreamEditor();
editor.setAsText(resource);
Object value = editor.getValue();
......@@ -49,14 +50,15 @@ public final class InputStreamEditorTests {
assertTrue(value instanceof InputStream);
stream = (InputStream) value;
assertTrue(stream.available() > 0);
} finally {
}
finally {
if (stream != null) {
stream.close();
}
}
}
@Test(expected=IllegalArgumentException.class)
@Test(expected = IllegalArgumentException.class)
public void testWhenResourceDoesNotExist() throws Exception {
String resource = "classpath:bingo!";
InputStreamEditor editor = new InputStreamEditor();
......@@ -66,7 +68,8 @@ public final class InputStreamEditorTests {
@Test
public void testGetAsTextReturnsNullByDefault() throws Exception {
assertNull(new InputStreamEditor().getAsText());
String resource = "classpath:" + ClassUtils.classPackageAsResourcePath(getClass()) + "/" + ClassUtils.getShortName(getClass()) + ".class";
String resource = "classpath:" + ClassUtils.classPackageAsResourcePath(getClass()) +
"/" + ClassUtils.getShortName(getClass()) + ".class";
InputStreamEditor editor = new InputStreamEditor();
editor.setAsText(resource);
assertNull(editor.getAsText());
......
/*
* Copyright 2002-2015 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.beans.propertyeditors;
import java.io.Reader;
import org.junit.Test;
import org.springframework.util.ClassUtils;
import static org.junit.Assert.*;
/**
* Unit tests for the {@link ReaderEditor} class.
*
* @author Juergen Hoeller
* @since 4.2
*/
public class ReaderEditorTests {
@Test(expected = IllegalArgumentException.class)
public void testCtorWithNullResourceEditor() throws Exception {
new InputStreamEditor(null);
}
@Test
public void testSunnyDay() throws Exception {
Reader reader = null;
try {
String resource = "classpath:" + ClassUtils.classPackageAsResourcePath(getClass()) +
"/" + ClassUtils.getShortName(getClass()) + ".class";
ReaderEditor editor = new ReaderEditor();
editor.setAsText(resource);
Object value = editor.getValue();
assertNotNull(value);
assertTrue(value instanceof Reader);
reader = (Reader) value;
assertTrue(reader.ready());
}
finally {
if (reader != null) {
reader.close();
}
}
}
@Test(expected = IllegalArgumentException.class)
public void testWhenResourceDoesNotExist() throws Exception {
String resource = "classpath:bingo!";
ReaderEditor editor = new ReaderEditor();
editor.setAsText(resource);
}
@Test
public void testGetAsTextReturnsNullByDefault() throws Exception {
assertNull(new ReaderEditor().getAsText());
String resource = "classpath:" + ClassUtils.classPackageAsResourcePath(getClass()) +
"/" + ClassUtils.getShortName(getClass()) + ".class";
ReaderEditor editor = new ReaderEditor();
editor.setAsText(resource);
assertNull(editor.getAsText());
}
}
......@@ -16,7 +16,13 @@
package org.springframework.context.expression;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.Serializable;
import java.net.URI;
import java.net.URL;
import java.security.AccessControlException;
import java.security.Permission;
import java.util.Properties;
......@@ -36,13 +42,18 @@ import org.springframework.beans.factory.support.AutowireCandidateQualifier;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.tests.Assume;
import org.springframework.tests.TestGroup;
import org.springframework.tests.sample.beans.TestBean;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.SerializationTestUtils;
import org.springframework.util.StopWatch;
......@@ -56,6 +67,7 @@ public class ApplicationContextExpressionTests {
private static final Log factoryLog = LogFactory.getLog(DefaultListableBeanFactory.class);
@Test
public void genericApplicationContext() throws Exception {
GenericApplicationContext ac = new GenericApplicationContext();
......@@ -312,6 +324,27 @@ public class ApplicationContextExpressionTests {
assertTrue(str.startsWith("test-"));
}
@Test
public void resourceInjection() throws IOException {
System.setProperty("logfile", "log4j.properties");
try {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(ResourceInjectionBean.class);
ResourceInjectionBean resourceInjectionBean = ac.getBean(ResourceInjectionBean.class);
Resource resource = new ClassPathResource("log4j.properties");
assertEquals(resource, resourceInjectionBean.resource);
assertEquals(resource.getURL(), resourceInjectionBean.url);
assertEquals(resource.getURI(), resourceInjectionBean.uri);
assertEquals(resource.getFile(), resourceInjectionBean.file);
assertArrayEquals(FileCopyUtils.copyToByteArray(resource.getInputStream()),
FileCopyUtils.copyToByteArray(resourceInjectionBean.inputStream));
assertEquals(FileCopyUtils.copyToString(new EncodedResource(resource).getReader()),
FileCopyUtils.copyToString(resourceInjectionBean.reader));
}
finally {
System.getProperties().remove("logfile");
}
}
@SuppressWarnings("serial")
public static class ValueTestBean implements Serializable {
......@@ -450,4 +483,26 @@ public class ApplicationContextExpressionTests {
}
}
public static class ResourceInjectionBean {
@Value("classpath:#{systemProperties.logfile}")
Resource resource;
@Value("classpath:#{systemProperties.logfile}")
URL url;
@Value("classpath:#{systemProperties.logfile}")
URI uri;
@Value("classpath:#{systemProperties.logfile}")
File file;
@Value("classpath:#{systemProperties.logfile}")
InputStream inputStream;
@Value("classpath:#{systemProperties.logfile}")
Reader reader;
}
}
......@@ -22,6 +22,7 @@ import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.Charset;
import org.springframework.core.io.InputStreamSource;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
......@@ -39,7 +40,7 @@ import org.springframework.util.ObjectUtils;
* @see java.io.Reader
* @see java.nio.charset.Charset
*/
public class EncodedResource {
public class EncodedResource implements InputStreamSource {
private final Resource resource;
......@@ -85,6 +86,7 @@ public class EncodedResource {
this.charset = charset;
}
/**
* Return the {@code Resource} held by this {@code EncodedResource}.
*/
......@@ -146,6 +148,7 @@ public class EncodedResource {
* @see #requiresReader()
* @see #getReader()
*/
@Override
public InputStream getInputStream() throws IOException {
return this.resource.getInputStream();
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册