|
|
|
@ -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"); |
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
|
|
* you may not use this file except in compliance with the License. |
|
|
|
* you may not use this file except in compliance with the License. |
|
|
|
@ -16,8 +16,6 @@ |
|
|
|
|
|
|
|
|
|
|
|
package org.springframework.core.env; |
|
|
|
package org.springframework.core.env; |
|
|
|
|
|
|
|
|
|
|
|
import static java.lang.String.format; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.core.convert.ConversionException; |
|
|
|
import org.springframework.core.convert.ConversionException; |
|
|
|
import org.springframework.util.ClassUtils; |
|
|
|
import org.springframework.util.ClassUtils; |
|
|
|
|
|
|
|
|
|
|
|
@ -35,6 +33,7 @@ public class PropertySourcesPropertyResolver extends AbstractPropertyResolver { |
|
|
|
|
|
|
|
|
|
|
|
private final PropertySources propertySources; |
|
|
|
private final PropertySources propertySources; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Create a new resolver against the given property sources. |
|
|
|
* Create a new resolver against the given property sources. |
|
|
|
* @param propertySources the set of {@link PropertySource} objects to use |
|
|
|
* @param propertySources the set of {@link PropertySource} objects to use |
|
|
|
@ -43,11 +42,14 @@ public class PropertySourcesPropertyResolver extends AbstractPropertyResolver { |
|
|
|
this.propertySources = propertySources; |
|
|
|
this.propertySources = propertySources; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public boolean containsProperty(String key) { |
|
|
|
public boolean containsProperty(String key) { |
|
|
|
for (PropertySource<?> propertySource : this.propertySources) { |
|
|
|
if (this.propertySources != null) { |
|
|
|
if (propertySource.containsProperty(key)) { |
|
|
|
for (PropertySource<?> propertySource : this.propertySources) { |
|
|
|
return true; |
|
|
|
if (propertySource.containsProperty(key)) { |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
@ -55,45 +57,41 @@ public class PropertySourcesPropertyResolver extends AbstractPropertyResolver { |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public String getProperty(String key) { |
|
|
|
public String getProperty(String key) { |
|
|
|
if (logger.isTraceEnabled()) { |
|
|
|
return getProperty(key, String.class); |
|
|
|
logger.trace(format("getProperty(\"%s\") (implicit targetType [String])", key)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return this.getProperty(key, String.class); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public <T> T getProperty(String key, Class<T> targetValueType) { |
|
|
|
public <T> T getProperty(String key, Class<T> targetValueType) { |
|
|
|
boolean debugEnabled = logger.isDebugEnabled(); |
|
|
|
boolean debugEnabled = logger.isDebugEnabled(); |
|
|
|
if (logger.isTraceEnabled()) { |
|
|
|
if (logger.isTraceEnabled()) { |
|
|
|
logger.trace(format("getProperty(\"%s\", %s)", key, targetValueType.getSimpleName())); |
|
|
|
logger.trace(String.format("getProperty(\"%s\", %s)", key, targetValueType.getSimpleName())); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (this.propertySources != null) { |
|
|
|
for (PropertySource<?> propertySource : this.propertySources) { |
|
|
|
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) { |
|
|
|
|
|
|
|
Class<?> valueType = value.getClass(); |
|
|
|
|
|
|
|
if (String.class.equals(valueType)) { |
|
|
|
|
|
|
|
value = this.resolveNestedPlaceholders((String) value); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (debugEnabled) { |
|
|
|
if (debugEnabled) { |
|
|
|
logger.debug( |
|
|
|
logger.debug(String.format("Searching for key '%s' in [%s]", key, propertySource.getName())); |
|
|
|
format("Found key '%s' in [%s] with type [%s] and value '%s'", |
|
|
|
|
|
|
|
key, propertySource.getName(), valueType.getSimpleName(), value)); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
if (!this.conversionService.canConvert(valueType, targetValueType)) { |
|
|
|
Object value; |
|
|
|
throw new IllegalArgumentException( |
|
|
|
if ((value = propertySource.getProperty(key)) != null) { |
|
|
|
format("Cannot convert value [%s] from source type [%s] to target type [%s]", |
|
|
|
Class<?> valueType = value.getClass(); |
|
|
|
value, valueType.getSimpleName(), targetValueType.getSimpleName())); |
|
|
|
if (String.class.equals(valueType)) { |
|
|
|
|
|
|
|
value = this.resolveNestedPlaceholders((String) value); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (debugEnabled) { |
|
|
|
|
|
|
|
logger.debug(String.format("Found key '%s' in [%s] with type [%s] and value '%s'", |
|
|
|
|
|
|
|
key, propertySource.getName(), valueType.getSimpleName(), value)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (!this.conversionService.canConvert(valueType, targetValueType)) { |
|
|
|
|
|
|
|
throw new IllegalArgumentException(String.format( |
|
|
|
|
|
|
|
"Cannot convert value [%s] from source type [%s] to target type [%s]", |
|
|
|
|
|
|
|
value, valueType.getSimpleName(), targetValueType.getSimpleName())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return conversionService.convert(value, targetValueType); |
|
|
|
} |
|
|
|
} |
|
|
|
return conversionService.convert(value, targetValueType); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (debugEnabled) { |
|
|
|
if (debugEnabled) { |
|
|
|
logger.debug(format("Could not find key '%s' in any property source. Returning [null]", key)); |
|
|
|
logger.debug(String.format("Could not find key '%s' in any property source. Returning [null]", key)); |
|
|
|
} |
|
|
|
} |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -102,51 +100,52 @@ public class PropertySourcesPropertyResolver extends AbstractPropertyResolver { |
|
|
|
public <T> Class<T> getPropertyAsClass(String key, Class<T> targetValueType) { |
|
|
|
public <T> Class<T> getPropertyAsClass(String key, Class<T> targetValueType) { |
|
|
|
boolean debugEnabled = logger.isDebugEnabled(); |
|
|
|
boolean debugEnabled = logger.isDebugEnabled(); |
|
|
|
if (logger.isTraceEnabled()) { |
|
|
|
if (logger.isTraceEnabled()) { |
|
|
|
logger.trace(format("getPropertyAsClass(\"%s\", %s)", key, targetValueType.getSimpleName())); |
|
|
|
logger.trace(String.format("getPropertyAsClass(\"%s\", %s)", key, targetValueType.getSimpleName())); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (this.propertySources != null) { |
|
|
|
for (PropertySource<?> propertySource : this.propertySources) { |
|
|
|
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) { |
|
|
|
if (debugEnabled) { |
|
|
|
logger.debug( |
|
|
|
logger.debug(String.format("Searching for key '%s' in [%s]", key, propertySource.getName())); |
|
|
|
format("Found key '%s' in [%s] with value '%s'", key, propertySource.getName(), value)); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Object value = propertySource.getProperty(key); |
|
|
|
Class<?> clazz; |
|
|
|
if (value != null) { |
|
|
|
if (value instanceof String) { |
|
|
|
if (debugEnabled) { |
|
|
|
try { |
|
|
|
logger.debug(String.format("Found key '%s' in [%s] with value '%s'", key, propertySource.getName(), value)); |
|
|
|
clazz = ClassUtils.forName((String)value, null); |
|
|
|
|
|
|
|
} catch (Exception ex) { |
|
|
|
|
|
|
|
throw new ClassConversionException((String)value, targetValueType, ex); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
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; |
|
|
|
} |
|
|
|
} |
|
|
|
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) { |
|
|
|
if (debugEnabled) { |
|
|
|
logger.debug(format("Could not find key '%s' in any property source. Returning [null]", key)); |
|
|
|
logger.debug(String.format("Could not find key '%s' in any property source. Returning [null]", key)); |
|
|
|
} |
|
|
|
} |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("serial") |
|
|
|
@SuppressWarnings("serial") |
|
|
|
static class ClassConversionException extends ConversionException { |
|
|
|
private static class ClassConversionException extends ConversionException { |
|
|
|
|
|
|
|
|
|
|
|
public ClassConversionException(Class<?> actual, Class<?> expected) { |
|
|
|
public ClassConversionException(Class<?> actual, Class<?> expected) { |
|
|
|
super(String.format("Actual type %s is not assignable to expected type %s", actual.getName(), expected.getName())); |
|
|
|
super(String.format("Actual type %s is not assignable to expected type %s", actual.getName(), expected.getName())); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -155,4 +154,5 @@ public class PropertySourcesPropertyResolver extends AbstractPropertyResolver { |
|
|
|
super(String.format("Could not find/load class %s during attempt to convert to %s", actual, expected.getName()), ex); |
|
|
|
super(String.format("Could not find/load class %s during attempt to convert to %s", actual, expected.getName()), ex); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|