Browse Source

ResourcePropertyResource accepts EncodedResource for properties files with a specific encoding

Also added constructor with Charset argument to EncodedResource.

Issue: SPR-10096
pull/201/head
Juergen Hoeller 12 years ago
parent
commit
049169d19f
  1. 58
      spring-core/src/main/java/org/springframework/core/io/support/EncodedResource.java
  2. 30
      spring-core/src/main/java/org/springframework/core/io/support/PropertiesLoaderSupport.java
  3. 56
      spring-core/src/main/java/org/springframework/core/io/support/PropertiesLoaderUtils.java
  4. 75
      spring-core/src/main/java/org/springframework/core/io/support/ResourcePropertySource.java

58
spring-core/src/main/java/org/springframework/core/io/support/EncodedResource.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 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.
@ -17,8 +17,10 @@ @@ -17,8 +17,10 @@
package org.springframework.core.io.support;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.Charset;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
@ -39,7 +41,9 @@ public class EncodedResource { @@ -39,7 +41,9 @@ public class EncodedResource {
private final Resource resource;
private final String encoding;
private String encoding;
private Charset charset;
/**
@ -48,7 +52,8 @@ public class EncodedResource { @@ -48,7 +52,8 @@ public class EncodedResource {
* @param resource the Resource to hold
*/
public EncodedResource(Resource resource) {
this(resource, null);
Assert.notNull(resource, "Resource must not be null");
this.resource = resource;
}
/**
@ -63,6 +68,18 @@ public class EncodedResource { @@ -63,6 +68,18 @@ public class EncodedResource {
this.encoding = encoding;
}
/**
* Create a new EncodedResource for the given Resource,
* using the specified encoding.
* @param resource the Resource to hold
* @param charset the charset to use for reading from the resource
*/
public EncodedResource(Resource resource, Charset charset) {
Assert.notNull(resource, "Resource must not be null");
this.resource = resource;
this.charset = charset;
}
/**
* Return the Resource held.
@ -79,13 +96,36 @@ public class EncodedResource { @@ -79,13 +96,36 @@ public class EncodedResource {
return this.encoding;
}
/**
* Return the charset to use for reading from the resource,
* or {@code null} if none specified.
*/
public final Charset getCharset() {
return this.charset;
}
/**
* Determine whether a {@link Reader} is required as opposed to an {@link InputStream},
* i.e. whether an encoding or a charset has been specified.
* @see #getReader()
* @see #getInputStream()
*/
public boolean requiresReader() {
return (this.encoding != null || this.charset != null);
}
/**
* Open a {@code java.io.Reader} for the specified resource,
* using the specified encoding (if any).
* @throws IOException if opening the Reader failed
* @see #requiresReader()
*/
public Reader getReader() throws IOException {
if (this.encoding != null) {
if (this.charset != null) {
return new InputStreamReader(this.resource.getInputStream(), this.charset);
}
else if (this.encoding != null) {
return new InputStreamReader(this.resource.getInputStream(), this.encoding);
}
else {
@ -93,6 +133,16 @@ public class EncodedResource { @@ -93,6 +133,16 @@ public class EncodedResource {
}
}
/**
* Open an {@code java.io.InputStream} for the specified resource,
* typically assuming that there is no specific encoding to use.
* @throws IOException if opening the InputStream failed
* @see #requiresReader()
*/
public InputStream getInputStream() throws IOException {
return this.resource.getInputStream();
}
@Override
public boolean equals(Object obj) {

30
spring-core/src/main/java/org/springframework/core/io/support/PropertiesLoaderSupport.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 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.
@ -17,8 +17,6 @@ @@ -17,8 +17,6 @@
package org.springframework.core.io.support;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Properties;
import org.apache.commons.logging.Log;
@ -39,9 +37,6 @@ import org.springframework.util.PropertiesPersister; @@ -39,9 +37,6 @@ import org.springframework.util.PropertiesPersister;
*/
public abstract class PropertiesLoaderSupport {
public static final String XML_FILE_EXTENSION = ".xml";
/** Logger available to subclasses */
protected final Log logger = LogFactory.getLog(getClass());
@ -167,7 +162,7 @@ public abstract class PropertiesLoaderSupport { @@ -167,7 +162,7 @@ public abstract class PropertiesLoaderSupport {
/**
* Load properties into the given instance.
* @param props the Properties instance to load into
* @throws java.io.IOException in case of I/O errors
* @throws IOException in case of I/O errors
* @see #setLocations
*/
protected void loadProperties(Properties props) throws IOException {
@ -176,21 +171,9 @@ public abstract class PropertiesLoaderSupport { @@ -176,21 +171,9 @@ public abstract class PropertiesLoaderSupport {
if (logger.isInfoEnabled()) {
logger.info("Loading properties file from " + location);
}
InputStream is = null;
try {
is = location.getInputStream();
String filename = location.getFilename();
if (filename != null && filename.endsWith(XML_FILE_EXTENSION)) {
this.propertiesPersister.loadFromXml(props, is);
}
else {
if (this.fileEncoding != null) {
this.propertiesPersister.load(props, new InputStreamReader(is, this.fileEncoding));
}
else {
this.propertiesPersister.load(props, is);
}
}
PropertiesLoaderUtils.fillProperties(
props, new EncodedResource(location, this.fileEncoding), this.propertiesPersister);
}
catch (IOException ex) {
if (this.ignoreResourceNotFound) {
@ -202,11 +185,6 @@ public abstract class PropertiesLoaderSupport { @@ -202,11 +185,6 @@ public abstract class PropertiesLoaderSupport {
throw ex;
}
}
finally {
if (is != null) {
is.close();
}
}
}
}
}

56
spring-core/src/main/java/org/springframework/core/io/support/PropertiesLoaderUtils.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 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.
@ -18,6 +18,7 @@ package org.springframework.core.io.support; @@ -18,6 +18,7 @@ package org.springframework.core.io.support;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.net.URL;
import java.net.URLConnection;
import java.util.Enumeration;
@ -26,6 +27,8 @@ import java.util.Properties; @@ -26,6 +27,8 @@ import java.util.Properties;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.DefaultPropertiesPersister;
import org.springframework.util.PropertiesPersister;
import org.springframework.util.ResourceUtils;
/**
@ -42,6 +45,9 @@ import org.springframework.util.ResourceUtils; @@ -42,6 +45,9 @@ import org.springframework.util.ResourceUtils;
*/
public abstract class PropertiesLoaderUtils {
private static final String XML_FILE_EXTENSION = ".xml";
/**
* Load properties from the given resource.
* @param resource the resource to load from
@ -120,4 +126,52 @@ public abstract class PropertiesLoaderUtils { @@ -120,4 +126,52 @@ public abstract class PropertiesLoaderUtils {
return properties;
}
/**
* Load the properties from the given encoded resource.
* @see #fillProperties
*/
static Properties loadProperties(EncodedResource resource) throws IOException {
Properties props = new Properties();
fillProperties(props, resource, new DefaultPropertiesPersister());
return props;
}
/**
* Actually load properties from the given EncodedResource into the given Properties instance.
* @param props the Properties instance to load into
* @param resource the resource to load from
* @param persister the PropertiesPersister to use
* @throws IOException in case of I/O errors
*/
static void fillProperties(Properties props, EncodedResource resource, PropertiesPersister persister)
throws IOException {
InputStream stream = null;
Reader reader = null;
try {
String filename = resource.getResource().getFilename();
if (filename != null && filename.endsWith(XML_FILE_EXTENSION)) {
stream = resource.getInputStream();
persister.loadFromXml(props, stream);
}
else if (resource.requiresReader()) {
reader = resource.getReader();
persister.load(props, reader);
}
else {
stream = resource.getInputStream();
persister.load(props, stream);
}
}
finally {
if (stream != null) {
stream.close();
}
if (reader != null) {
reader.close();
}
}
}
}

75
spring-core/src/main/java/org/springframework/core/io/support/ResourcePropertySource.java

@ -17,12 +17,11 @@ @@ -17,12 +17,11 @@
package org.springframework.core.io.support;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
/**
@ -35,16 +34,34 @@ import org.springframework.util.StringUtils; @@ -35,16 +34,34 @@ import org.springframework.util.StringUtils;
* return non-{@code null} and end in ".xml".
*
* @author Chris Beams
* @author Juergen Hoeller
* @since 3.1
*/
public class ResourcePropertySource extends PropertiesPropertySource {
/**
* Create a PropertySource having the given name based on Properties
* loaded from the given resource.
* loaded from the given encoded resource.
*/
public ResourcePropertySource(String name, EncodedResource resource) throws IOException {
super(name, PropertiesLoaderUtils.loadProperties(resource));
}
/**
* Create a PropertySource based on Properties loaded from the given resource.
* The name of the PropertySource will be generated based on the
* {@link Resource#getDescription() description} of the given resource.
*/
public ResourcePropertySource(EncodedResource resource) throws IOException {
this(getNameForResource(resource.getResource()), resource);
}
/**
* Create a PropertySource having the given name based on Properties
* loaded from the given encoded resource.
*/
public ResourcePropertySource(String name, Resource resource) throws IOException {
super(name, loadPropertiesForResource(resource));
super(name, PropertiesLoaderUtils.loadProperties(new EncodedResource(resource)));
}
/**
@ -62,17 +79,7 @@ public class ResourcePropertySource extends PropertiesPropertySource { @@ -62,17 +79,7 @@ public class ResourcePropertySource extends PropertiesPropertySource {
* resource (assuming it is prefixed with {@code classpath:}).
*/
public ResourcePropertySource(String name, String location, ClassLoader classLoader) throws IOException {
this(name, getResourceForLocation(location, classLoader));
}
/**
* Create a PropertySource having the given name based on Properties loaded from
* the given resource location. The default thread context class loader will be
* used to load the resource (assuming the location string is prefixed with
* {@code classpath:}.
*/
public ResourcePropertySource(String name, String location) throws IOException {
this(name, location, ClassUtils.getDefaultClassLoader());
this(name, new DefaultResourceLoader(classLoader).getResource(location));
}
/**
@ -83,7 +90,17 @@ public class ResourcePropertySource extends PropertiesPropertySource { @@ -83,7 +90,17 @@ public class ResourcePropertySource extends PropertiesPropertySource {
* resource.
*/
public ResourcePropertySource(String location, ClassLoader classLoader) throws IOException {
this(getResourceForLocation(location, classLoader));
this(new DefaultResourceLoader(classLoader).getResource(location));
}
/**
* Create a PropertySource having the given name based on Properties loaded from
* the given resource location. The default thread context class loader will be
* used to load the resource (assuming the location string is prefixed with
* {@code classpath:}.
*/
public ResourcePropertySource(String name, String location) throws IOException {
this(name, new DefaultResourceLoader().getResource(location));
}
/**
@ -92,34 +109,12 @@ public class ResourcePropertySource extends PropertiesPropertySource { @@ -92,34 +109,12 @@ public class ResourcePropertySource extends PropertiesPropertySource {
* {@link Resource#getDescription() description} of the resource.
*/
public ResourcePropertySource(String location) throws IOException {
this(getResourceForLocation(location, ClassUtils.getDefaultClassLoader()));
}
private static Resource getResourceForLocation(String location, ClassLoader classLoader) {
return new PathMatchingResourcePatternResolver(classLoader).getResource(location);
this(new DefaultResourceLoader().getResource(location));
}
private static Properties loadPropertiesForResource(Resource resource) throws IOException {
Properties props = new Properties();
InputStream is = resource.getInputStream();
String filename = resource.getFilename();
if (filename != null && filename.endsWith(".xml")) {
props.loadFromXML(is);
}
else {
props.load(is);
}
try {
is.close();
} catch (IOException ex) {
// ignore
}
return props;
}
/**
* Returns the description string for the resource, and if empty returns
* Return the description string for the resource, and if empty returns
* the class name of the resource plus its identity hash code.
*/
private static String getNameForResource(Resource resource) {

Loading…
Cancel
Save