prepared support for SPRNET-1167 (Properties class now supports reading in null values)

This commit is contained in:
eeichinger
2009-02-21 11:27:39 +00:00
parent c7f299b6ec
commit f84fdfa443
4 changed files with 108 additions and 13 deletions

View File

@@ -30,7 +30,25 @@ namespace Spring.Util
{
/// <summary>
/// An implementation of the Java Properties class.
/// </summary>
/// </summary>
/// <remarks>
/// For the complete syntax see <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/Properties.html#load(java.io.InputStream)">java.util.Properties JavaDoc</a>.
/// This class supports an extended syntax. There may also be sole keys on a line, in that case values are treated as <c>null</c>.
/// <example>
/// <code>
/// key1 = value
/// key2:
/// key3
/// </code>
/// will result in the name/value pairs:
/// <list>
/// <item>key1:="value"</item>
/// <item>key2:=string.Empty</item>
/// <item>key3:=&lt;null&gt;</item>
/// </list>
/// note, that to specify a <c>null</c> value, the key <b>must not</b> be followed by any character except newline.
/// </example>
/// </remarks>
/// <author>Simon White</author>
[Serializable]
public class Properties : Hashtable
@@ -122,7 +140,7 @@ namespace Spring.Util
key = keyvalue[0];
value = keyvalue[1];
if (value.EndsWith("\\"))
if (value != null && value.EndsWith("\\"))
{
value = value.Substring(0, value.Length - 1);
isContinuation = true;
@@ -155,8 +173,10 @@ namespace Spring.Util
/// <param name="line">The string.</param>
/// <returns>The string with all leading whitespace removed.</returns>
private static string RemoveLeadingWhitespace(string line)
{
string trimmed = null;
{
if (line == null) return null;
string trimmed = string.Empty;
for (int i = 0; i < line.Length; i++)
{
if (Whitespace.IndexOf(line[i]) == -1)
@@ -175,7 +195,7 @@ namespace Spring.Util
/// <returns>An array containing the key / value pair.</returns>
private static string[] SplitLine(string line)
{
string key = null;
string key = line;
string value = null;
int index = 0;
@@ -202,14 +222,23 @@ namespace Spring.Util
// first ignore leading whitespace and initial separator
// (if one's there)
index++;
if (index >= len)
if (index > len)
{
return null;
}
value = line.Substring(index);
value = RemoveLeadingWhitespace(value);
// this is an extension to support key-only lines and specifying null values
value = null;
}
else if (index == len)
{
value = string.Empty;
}
else
{
value = line.Substring(index);
value = RemoveLeadingWhitespace(value);
}
if (Separators.IndexOf(value[0]) != -1)
if (value != null && value.Length > 0
&& Separators.IndexOf(value[0]) != -1)
{
value = value.Substring(1);
value = RemoveLeadingWhitespace(value);

View File

@@ -672,6 +672,7 @@ namespace Spring.Util
/// <returns>The converted string.</returns>
public static string ConvertEscapedCharacters(string inputString)
{
if (inputString == null) return null;
StringBuilder sb = new StringBuilder(inputString.Length);
for (int i = 0; i < inputString.Length; i++)
{

View File

@@ -20,6 +20,7 @@
#region Imports
using System;
using System.Collections;
using NUnit.Framework;
using Spring.Context.Support;
@@ -115,6 +116,55 @@ namespace Spring.Objects.Factory.Config
TestObject tb1 = (TestObject)ac.GetObject("tb1");
Assert.AreEqual(35, tb1.Age);
Assert.AreEqual("Erich", tb1.Name);
}
}
[Test]
[Ignore("Does not work yet because IVariableSource cannot differentiate between invalid key and key with a null value")]
public void WhitespaceHandling()
{
StaticApplicationContext ac = new StaticApplicationContext();
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.Add("name", "${name}");
pvs.Add("nickname", "${nickname}");
ac.RegisterSingleton("tb1", typeof(TestObject), pvs);
IList variableSources = new ArrayList();
variableSources.Add(new DictionaryVariableSource(new string[] { "name", string.Empty, "nickname", null }));
pvs = new MutablePropertyValues();
pvs.Add("VariableSources", variableSources);
ac.RegisterSingleton("configurer", typeof(VariablePlaceholderConfigurer), pvs);
ac.Refresh();
TestObject tb1 = (TestObject)ac.GetObject("tb1");
Assert.AreEqual(string.Empty, tb1.Name);
Assert.AreEqual(null, tb1.Nickname);
}
[Test]
public void BailsOnUnresolvableVariable()
{
StaticApplicationContext ac = new StaticApplicationContext();
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.Add("nickname", "${nickname}");
ac.RegisterSingleton("tb1", typeof(TestObject), pvs);
IList variableSources = new ArrayList();
variableSources.Add(new DictionaryVariableSource(new string[] { }));
pvs = new MutablePropertyValues();
pvs.Add("VariableSources", variableSources);
ac.RegisterSingleton("configurer", typeof(VariablePlaceholderConfigurer), pvs);
try
{
ac.Refresh();
Assert.Fail("something changed wrt VariablePlaceholder resolution");
}
catch (ObjectDefinitionStoreException ex)
{
Assert.IsTrue( ex.Message.IndexOf("nickname") > -1 );
}
}
}
}

View File

@@ -101,7 +101,7 @@ namespace Spring.Util
}
[Test]
public void ListAndLoad ()
public void ListAndLoad()
{
Properties props = new Properties();
props.Add ("foo", "this");
@@ -151,6 +151,21 @@ namespace Spring.Util
Assert.IsTrue("true".Equals(props["leadingspace"]));
}
[Test]
public void WhitespaceProperties()
{
string input = "key1 =\t\nkey2:\nkey3";
Stream s = new MemoryStream(Encoding.ASCII.GetBytes(input));
Properties props = new Properties();
props.Load(s);
Assert.AreEqual(string.Empty, props["key1"], "key1 should have empty value");
Assert.AreEqual(string.Empty, props["key2"], "key2 should have empty value");
Assert.IsTrue(props.ContainsKey("key3"));
Assert.IsNull(props["key3"]);
}
[Test]
public void Continuation()
{