diff --git a/src/main/java/org/apache/commons/lang3/text/StrLookup.java b/src/main/java/org/apache/commons/lang3/text/StrLookup.java index ede97049e..a507e6e5c 100644 --- a/src/main/java/org/apache/commons/lang3/text/StrLookup.java +++ b/src/main/java/org/apache/commons/lang3/text/StrLookup.java @@ -16,7 +16,9 @@ */ package org.apache.commons.lang3.text; +import java.util.Enumeration; import java.util.Map; +import java.util.Properties; /** * Lookup a String key to a String value. @@ -39,24 +41,7 @@ public abstract class StrLookup { /** * Lookup that always returns null. */ - private static final StrLookup NONE_LOOKUP; - /** - * Lookup that uses System properties. - */ - private static final StrLookup SYSTEM_PROPERTIES_LOOKUP; - static { - NONE_LOOKUP = new MapStrLookup(null); - StrLookup lookup = null; - try { - final Map propMap = System.getProperties(); - @SuppressWarnings("unchecked") // System property keys and values are always Strings - final Map properties = (Map) propMap; - lookup = new MapStrLookup(properties); - } catch (final SecurityException ex) { - lookup = NONE_LOOKUP; - } - SYSTEM_PROPERTIES_LOOKUP = lookup; - } + private static final StrLookup NONE_LOOKUP = new MapStrLookup(null); //----------------------------------------------------------------------- /** @@ -68,9 +53,26 @@ public abstract class StrLookup { return NONE_LOOKUP; } + private static Properties copyProperties(Properties input) { + if (input == null) { + return null; + } + + Properties output = new Properties(); + @SuppressWarnings("unchecked") // Property names are Strings. + Enumeration propertyNames = (Enumeration) input.propertyNames(); + + while (propertyNames.hasMoreElements()) { + String propertyName = propertyNames.nextElement(); + output.setProperty(propertyName, input.getProperty(propertyName)); + } + + return output; + } + /** - * Returns a lookup which uses {@link System#getProperties() System properties} - * to lookup the key to value. + * Returns a new lookup which uses a copy of the current + * {@link System#getProperties() System properties}. *

* If a security manager blocked access to system properties, then null will * be returned from every lookup. @@ -80,7 +82,19 @@ public abstract class StrLookup { * @return a lookup using system properties, not null */ public static StrLookup systemPropertiesLookup() { - return SYSTEM_PROPERTIES_LOOKUP; + Properties systemProperties = null; + + try { + systemProperties = System.getProperties(); + } catch (final SecurityException ex) { + // Squelched. All lookup(String) will return null. + } + + Properties properties = copyProperties(systemProperties); + @SuppressWarnings("unchecked") // System property keys and values are always Strings + final Map propertiesMap = (Map) properties; + + return new MapStrLookup(propertiesMap); } /** diff --git a/src/test/java/org/apache/commons/lang3/text/StrLookupTest.java b/src/test/java/org/apache/commons/lang3/text/StrLookupTest.java index e45a324c8..e6ccccc01 100644 --- a/src/test/java/org/apache/commons/lang3/text/StrLookupTest.java +++ b/src/test/java/org/apache/commons/lang3/text/StrLookupTest.java @@ -53,6 +53,22 @@ public class StrLookupTest { } } + @Test + public void testSystemPropertiesLookupNotSingleton() { + final String osName = "os.name"; + final String originalOsName = System.getProperty(osName); + + StrLookup properties1 = StrLookup.systemPropertiesLookup(); + assertEquals(originalOsName, properties1.lookup(osName)); + + final String differentOsName = "HAL-9000"; + System.setProperty(osName, differentOsName); + StrLookup properties2 = StrLookup.systemPropertiesLookup(); + + assertEquals(originalOsName, properties1.lookup(osName)); + assertEquals(differentOsName, properties2.lookup(osName)); + } + @Test public void testMapLookup() { final Map map = new HashMap();