Introduce PropertyResolver#getPropertyAsClass

This commit is contained in:
Chris Beams
2011-05-06 18:59:05 +00:00
parent 275d43dfde
commit 4b5208faad
4 changed files with 143 additions and 2 deletions

View File

@@ -196,6 +196,10 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment {
return this.propertyResolver.getProperty(key, targetType);
}
public <T> Class<T> getPropertyAsClass(String key, Class<T> targetType) {
return this.propertyResolver.getPropertyAsClass(key, targetType);
}
public String getRequiredProperty(String key) throws IllegalStateException {
return this.propertyResolver.getRequiredProperty(key);
}

View File

@@ -41,6 +41,15 @@ public interface PropertyResolver {
*/
<T> T getProperty(String key, Class<T> targetType);
/**
* Convert the property value associated with the given key to a {@code Class}
* of type {@code T} or {@code null} if the key cannot be resolved.
* @throws ConversionException if class specified by property value cannot be found
* or loaded or if targetType is not assignable from class specified by property value
* @see #getProperty(String, Class)
*/
<T> Class<T> getPropertyAsClass(String key, Class<T> targetType);
/**
* Return the property value associated with the given key, converted to the given
* targetType (never {@code null}).

View File

@@ -18,6 +18,9 @@ package org.springframework.core.env;
import static java.lang.String.format;
import org.springframework.core.convert.ConversionException;
import org.springframework.util.ClassUtils;
/**
* {@link PropertyResolver} implementation that resolves property values against
* an underlying set of {@link PropertySources}.
@@ -58,7 +61,7 @@ public class PropertySourcesPropertyResolver extends AbstractPropertyResolver {
if (logger.isTraceEnabled()) {
logger.trace(format("getProperty(\"%s\", %s)", key, targetValueType.getSimpleName()));
}
for (PropertySource<?> propertySource : this.propertySources) {
if (debugEnabled) {
logger.debug(format("Searching for key '%s' in [%s]", key, propertySource.getName()));
@@ -79,11 +82,68 @@ public class PropertySourcesPropertyResolver extends AbstractPropertyResolver {
return conversionService.convert(value, targetValueType);
}
}
if (debugEnabled) {
logger.debug(format("Could not find key '%s' in any property source. Returning [null]", key));
}
return null;
}
public <T> Class<T> getPropertyAsClass(String key, Class<T> targetValueType) {
boolean debugEnabled = logger.isDebugEnabled();
if (logger.isTraceEnabled()) {
logger.trace(format("getPropertyAsClass(\"%s\", %s)", key, targetValueType.getSimpleName()));
}
for (PropertySource<?> propertySource : this.propertySources) {
if (debugEnabled) {
logger.debug(format("Searching for key '%s' in [%s]", key, propertySource.getName()));
}
Object value;
if ((value = propertySource.getProperty(key)) != null) {
if (debugEnabled) {
logger.debug(
format("Found key '%s' in [%s] with value '%s'", key, propertySource.getName(), value));
}
Class<?> clazz;
if (value instanceof String) {
try {
clazz = ClassUtils.forName((String)value, null);
} catch (Exception ex) {
throw new ClassConversionException((String)value, targetValueType, ex);
}
}
else if (value instanceof Class) {
clazz = (Class<?>)value;
} else {
clazz = value.getClass();
}
if (!targetValueType.isAssignableFrom(clazz)) {
throw new ClassConversionException(clazz, targetValueType);
}
@SuppressWarnings("unchecked")
Class<T> targetClass = (Class<T>)clazz;
return targetClass;
}
}
if (debugEnabled) {
logger.debug(format("Could not find key '%s' in any property source. Returning [null]", key));
}
return null;
}
@SuppressWarnings("serial")
static class ClassConversionException extends ConversionException {
public ClassConversionException(Class<?> actual, Class<?> expected) {
super(String.format("Actual type %s is not assignable to expected type %s", actual.getName(), expected.getName()));
}
public ClassConversionException(String actual, Class<?> expected, Exception ex) {
super(String.format("Could not find/load class %s during attempt to convert to %s", actual, expected.getName()), ex);
}
}
}