SystemEnvironmentPropertySource uses regular property names check instead of optimized Map lookup (for defensiveness in SecurityManager scenarios)

Issue: SPR-12224
This commit is contained in:
Juergen Hoeller 2014-09-19 00:11:44 +02:00
parent 7f8d611598
commit 65cc57dabb
3 changed files with 27 additions and 47 deletions

View File

@ -16,10 +16,7 @@
package org.springframework.core.env;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* A {@link PropertySource} implementation capable of interrogating its
@ -41,24 +38,16 @@ import org.springframework.util.Assert;
* or not.
*
* @author Chris Beams
* @author Juergen Hoeller
* @since 3.1
*/
public abstract class EnumerablePropertySource<T> extends PropertySource<T> {
protected final Log logger = LogFactory.getLog(getClass());
public EnumerablePropertySource(String name, T source) {
super(name, source);
}
/**
* Return the names of all properties contained by the
* {@linkplain #getSource() source} object (never {@code null}).
*/
public abstract String[] getPropertyNames();
/**
* Return whether this {@code PropertySource} contains a property with the given name.
* <p>This implementation checks for the presence of the given name within the
@ -67,19 +56,13 @@ public abstract class EnumerablePropertySource<T> extends PropertySource<T> {
*/
@Override
public boolean containsProperty(String name) {
Assert.notNull(name, "Property name must not be null");
for (String candidate : getPropertyNames()) {
if (candidate.equals(name)) {
if (logger.isDebugEnabled()) {
logger.debug(String.format("PropertySource [%s] contains '%s'", getName(), name));
}
return true;
}
}
if (logger.isTraceEnabled()) {
logger.trace(String.format("PropertySource [%s] does not contain '%s'", getName(), name));
}
return false;
return ObjectUtils.containsElement(getPropertyNames(), name);
}
/**
* Return the names of all properties contained by the
* {@linkplain #getSource() source} object (never {@code null}).
*/
public abstract String[] getPropertyNames();
}

View File

@ -18,13 +18,13 @@ package org.springframework.core.env;
import java.util.Map;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* {@link PropertySource} that reads keys and values from a {@code Map} object.
*
* @author Chris Beams
* @author Juergen Hoeller
* @since 3.1
* @see PropertiesPropertySource
*/
@ -34,25 +34,20 @@ public class MapPropertySource extends EnumerablePropertySource<Map<String, Obje
super(name, source);
}
@Override
public Object getProperty(String name) {
return this.source.get(name);
}
@Override
public boolean containsProperty(String name) {
return this.source.containsKey(name);
}
@Override
public String[] getPropertyNames() {
return StringUtils.toStringArray(this.source.keySet());
}
@Override
public boolean containsProperty(String name) {
Assert.notNull(name, "Property name must not be null");
boolean containsProperty = this.source.containsKey(name);
if (logger.isDebugEnabled()) {
logger.debug(String.format("PropertySource [%s] %s '%s'", getName(),
(containsProperty ? "contains" : "does not contain"), name));
}
return containsProperty;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 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.core.env;
import java.util.Map;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* Specialization of {@link MapPropertySource} designed for use with
@ -70,8 +71,9 @@ public class SystemEnvironmentPropertySource extends MapPropertySource {
super(name, source);
}
/**
* Return true if a property with the given name or any underscore/uppercase variant
* Return {@link true} if a property with the given name or any underscore/uppercase variant
* thereof exists in this property source.
*/
@Override
@ -80,13 +82,11 @@ public class SystemEnvironmentPropertySource extends MapPropertySource {
}
/**
* {@inheritDoc}
* <p>This implementation returns {@code true} if a property with the given name or
* This implementation returns {@code true} if a property with the given name or
* any underscore/uppercase variant thereof exists in this property source.
*/
@Override
public Object getProperty(String name) {
Assert.notNull(name, "property name must not be null");
String actualName = resolvePropertyName(name);
if (logger.isDebugEnabled() && !name.equals(actualName)) {
logger.debug(String.format("PropertySource [%s] does not contain '%s', but found equivalent '%s'",
@ -101,23 +101,24 @@ public class SystemEnvironmentPropertySource extends MapPropertySource {
* found or otherwise the original name. Never returns {@code null}.
*/
private String resolvePropertyName(String name) {
if (super.containsProperty(name)) {
Assert.notNull(name, "Property name must not be null");
if (ObjectUtils.containsElement(getPropertyNames(), name)) {
return name;
}
String usName = name.replace('.', '_');
if (!name.equals(usName) && super.containsProperty(usName)) {
if (!name.equals(usName) && ObjectUtils.containsElement(getPropertyNames(), usName)) {
return usName;
}
String ucName = name.toUpperCase();
if (!name.equals(ucName)) {
if (super.containsProperty(ucName)) {
if (ObjectUtils.containsElement(getPropertyNames(), ucName)) {
return ucName;
}
else {
String usUcName = ucName.replace('.', '_');
if (!ucName.equals(usUcName) && super.containsProperty(usUcName)) {
if (!ucName.equals(usUcName) && ObjectUtils.containsElement(getPropertyNames(), usUcName)) {
return usUcName;
}
}
@ -125,4 +126,5 @@ public class SystemEnvironmentPropertySource extends MapPropertySource {
return name;
}
}