rem $(ProjectDir)..\..\..\build-support\tools\antlr-2.7.6\antlr-2.7.6.exe -o $(ProjectDir)Expressions\Parser $(ProjectDir)Expressions\Expression.g
+ $(ProjectDir)..\..\..\build-support\tools\antlr-2.7.6\antlr-2.7.6.exe -o $(ProjectDir)Expressions\Parser $(ProjectDir)Expressions\Expression.g
diff --git a/src/Spring/Spring.Core/Util/StringUtils.cs b/src/Spring/Spring.Core/Util/StringUtils.cs
index 279168ab..90b8232d 100644
--- a/src/Spring/Spring.Core/Util/StringUtils.cs
+++ b/src/Spring/Spring.Core/Util/StringUtils.cs
@@ -1,5 +1,5 @@
-#region License
-
+#region License
+
/*
* Copyright © 2002-2005 the original author or authors.
*
@@ -14,561 +14,685 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
-
-#endregion
-
-#region Imports
-
-using System;
-using System.Collections;
-using System.Globalization;
-using System.Text;
-
-#endregion
-
-namespace Spring.Util
-{
- ///
- /// Miscellaneous utility methods.
- ///
- ///
- ///
- /// Mainly for internal use within the framework.
- ///
- ///
- /// Rod Johnson
- /// Juergen Hoeller
- /// Keith Donald
- /// Aleksandar Seovic (.NET)
- /// Mark Pollack (.NET)
- /// Rick Evans (.NET)
- public sealed class StringUtils
- {
- ///
- /// An empty array of instances.
- ///
- public static readonly string[] EmptyStrings = new string[] {};
-
- ///
- /// The string that signals the start of an Ant-style expression.
- ///
- private const string AntExpressionPrefix = "${";
-
- ///
- /// The string that signals the end of an Ant-style expression.
- ///
- private const string AntExpressionSuffix = "}";
-
- #region Constructor (s) / Destructor
-
- // CLOVER:OFF
-
- ///
- /// Creates a new instance of the class.
- ///
- ///
- ///
- /// This is a utility class, and as such exposes no public constructors.
- ///
- ///
- private StringUtils()
- {
- }
-
- // CLOVER:ON
-
- #endregion
-
- ///
- /// Tokenize the given into a
- /// array.
- ///
- ///
- ///
- /// If is , returns an empty
- /// array.
- ///
- ///
- /// If is or the empty
- /// , returns a array with one
- /// element: itself.
- ///
- ///
- /// The to tokenize.
- ///
- /// The delimiter characters, assembled as a .
- ///
- ///
- /// Trim the tokens via .
- ///
- ///
- /// Omit empty tokens from the result array.
- /// An array of the tokens.
- public static string[] Split(
- string s, string delimiters, bool trimTokens, bool ignoreEmptyTokens)
- {
- if (s == null)
- {
- return new string[0];
- }
- if (StringUtils.IsNullOrEmpty(delimiters))
- {
- return new string[] {s};
- }
- string[] tmp = s.Split(delimiters.ToCharArray());
- // short circuit if String.Split default behavior is ok
- if (!trimTokens && !ignoreEmptyTokens)
- {
- return tmp;
- }
- else
- {
- ArrayList tokens = new ArrayList(tmp.Length);
- for (int i = 0; i < tmp.Length; ++i)
- {
- string token = (trimTokens ? tmp[i].Trim() : tmp[i]);
- if (!(ignoreEmptyTokens && token.Length == 0))
- {
- tokens.Add(token);
- }
- }
- return (string[]) tokens.ToArray(typeof (string));
- }
- }
-
- ///
- /// Convert a CSV list into an array of s.
- ///
- /// A CSV list.
- ///
- /// An array of s, or the empty array
- /// if is .
- ///
- public static string[] CommaDelimitedListToStringArray(string s)
- {
- return DelimitedListToStringArray(s, ",");
- }
-
- ///
- /// Take a which is a delimited list
- /// and convert it to a array.
- ///
- ///
- ///
- /// If the supplied is a
- /// or zero-length string, then a single element
- /// array composed of the supplied
- /// will be
- /// eturned. If the supplied
- /// is , then an empty,
- /// zero-length array will be returned.
- ///
- ///
- ///
- /// The to be parsed.
- ///
- ///
- /// The delimeter (this will not be returned). Note that only the first
- /// character of the supplied is used.
- ///
- ///
- /// An array of the tokens in the list.
- ///
- public static string[] DelimitedListToStringArray(string input, string delimiter)
- {
- if (input == null)
- {
- return new string[0];
- }
- if (!HasLength(delimiter))
- {
- return new string[] {input};
- }
- return input.Split(delimiter[0]);
- }
-
- ///
- /// Convenience method to return an
- /// as a delimited
- /// (e.g. CSV) .
- ///
- ///
- /// The to parse.
- ///
- ///
- /// The delimiter to use (probably a ',').
- ///
- /// The delimited string representation.
- public static string CollectionToDelimitedString(
- ICollection c, string delimiter)
- {
- if (c == null)
- {
- return "null";
- }
- StringBuilder sb = new StringBuilder();
- int i = 0;
- foreach (object obj in c)
- {
- if (i++ > 0)
- {
- sb.Append(delimiter);
- }
- sb.Append(obj);
- }
- return sb.ToString();
- }
-
- ///
- /// Convenience method to return an
- /// as a CSV
- /// .
- ///
- ///
- /// The to display.
- ///
- /// The delimited string representation.
- public static string CollectionToCommaDelimitedString(
- ICollection collection)
- {
- return CollectionToDelimitedString(collection, ",");
- }
-
- ///
- /// Convenience method to return an array as a CSV
- /// .
- ///
- ///
- /// The array to parse. Elements may be of any type (
- /// will be called on each
- /// element).
- ///
- public static string ArrayToCommaDelimitedString(object[] source)
- {
- return ArrayToDelimitedString(source, ",");
- }
-
- ///
- /// Convenience method to return a
- /// array as a delimited (e.g. CSV) .
- ///
- ///
- /// The array to parse. Elements may be of any type (
- /// will be called on each
- /// element).
- ///
- ///
- /// The delimiter to use (probably a ',').
- ///
- public static string ArrayToDelimitedString(
- object[] source, string delimiter)
- {
- if (source == null)
- {
- return "null";
- }
- else
- {
- return StringUtils.CollectionToDelimitedString(source, delimiter);
- }
- }
-
- /// Checks if a string has length.
- ///
- /// The string to check, may be .
- ///
- ///
- /// if the string has length and is not
- /// .
- ///
- ///
- ///
- /// StringUtils.HasLength(null) = false
- /// StringUtils.HasLength("") = false
- /// StringUtils.HasLength(" ") = true
- /// StringUtils.HasLength("Hello") = true
- ///
- ///
- public static bool HasLength(string target)
- {
- return (target != null && target.Length > 0);
- }
-
- ///
- /// Checks if a has text.
- ///
- ///
- ///
- /// More specifically, returns if the string is
- /// not , it's is >
- /// zero (0), and it has at least one non-whitespace character.
- ///
- ///
- ///
- /// The string to check, may be .
- ///
- ///
- /// if the is not
- /// ,
- /// > zero (0), and does not consist
- /// solely of whitespace.
- ///
- ///
- ///
- /// StringUtils.HasText(null) = false
- /// StringUtils.HasText("") = false
- /// StringUtils.HasText(" ") = false
- /// StringUtils.HasText("12345") = true
- /// StringUtils.HasText(" 12345 ") = true
- ///
- ///
- public static bool HasText(string target)
- {
- if (target == null)
- {
- return false;
- }
- else
- {
- return HasLength(target.Trim());
- }
- }
-
- ///
- /// Checks if a is
- /// or an empty string.
- ///
- ///
- ///
- /// More specifically, returns if the string is
- /// , it's is equal
- /// to zero (0), or it is composed entirely of whitespace
- /// characters.
- ///
- ///
- ///
- /// The string to check, may (obviously) be .
- ///
- ///
- /// if the is
- /// , has a length equal to zero (0), or
- /// is composed entirely of whitespace characters.
- ///
- ///
- ///
- /// StringUtils.IsNullOrEmpty(null) = true
- /// StringUtils.IsNullOrEmpty("") = true
- /// StringUtils.IsNullOrEmpty(" ") = true
- /// StringUtils.IsNullOrEmpty("12345") = false
- /// StringUtils.IsNullOrEmpty(" 12345 ") = false
- ///
- ///
- public static bool IsNullOrEmpty(string target)
- {
- return !HasText(target);
- }
-
- ///
- /// Strips first and last character off the string.
- ///
- /// The string to strip.
- /// The stripped string.
- public static string StripFirstAndLastCharacter(string text)
- {
- if (text != null
- && text.Length > 2)
- {
- return text.Substring(1, text.Length - 2);
- }
- else
- {
- return String.Empty;
- }
- }
-
- ///
- /// Returns a list of Ant-style expressions from the specified text.
- ///
- /// The text to inspect.
- ///
- /// A list of expressions that exist in the specified text.
- ///
- ///
- /// If any of the expressions in the supplied
- /// is empty (${}).
- ///
- public static IList GetAntExpressions(string text)
- {
- IList expressions = new ArrayList();
- if (StringUtils.HasText(text))
- {
- int start = text.IndexOf(AntExpressionPrefix);
- while (start >= 0)
- {
- int end = text.IndexOf(AntExpressionSuffix, start + 2);
- if (end == -1)
- {
- // terminator character not found, so let's quit...
- start = -1;
- }
- else
- {
- string exp = text.Substring(start + 2, end - start - 2);
- if(StringUtils.IsNullOrEmpty(exp))
- {
- throw new FormatException(
- string.Format("Empty {0}{1} value found in text : '{2}'.",
- AntExpressionPrefix,
- AntExpressionSuffix,
- text));
- }
- if (expressions.IndexOf(exp) < 0)
- {
- expressions.Add(exp);
- }
- start = text.IndexOf(AntExpressionPrefix, end);
- }
- }
- }
- return expressions;
- }
-
- ///
- /// Replaces Ant-style expression placeholder with expression value.
- ///
- ///
- ///
- ///
- ///
- ///
- /// The string to set the value in.
- /// The name of the expression to set.
- /// The expression value.
- ///
- /// A new string with the expression value set; the
- /// value if the supplied
- /// is , has a length
- /// equal to zero (0), or is composed entirely of whitespace
- /// characters.
- ///
- public static string SetAntExpression(string text, string expression, object expValue)
- {
- if (StringUtils.IsNullOrEmpty(text))
- {
- return String.Empty;
- }
- if (expValue == null)
- {
- expValue = String.Empty;
- }
- return text.Replace(
- StringUtils.Surround(AntExpressionPrefix, expression, AntExpressionSuffix), expValue.ToString());
- }
-
- ///
- /// Surrounds (prepends and appends) the string value of the supplied
- /// to the supplied .
- ///
- ///
- ///
- /// The return value of this method call is always guaranteed to be non
- /// . If every value passed as a parameter to this method is
- /// , the string will be returned.
- ///
- ///
- ///
- /// The prefix and suffix that respectively will be prepended and
- /// appended to the target . If this value
- /// is not a value, it's attendant
- /// value will be used.
- ///
- ///
- /// The target that is to be surrounded. If this value is not a
- /// value, it's attendant
- /// value will be used.
- ///
- /// The surrounded string.
- public static string Surround(object fix, object target)
- {
- return StringUtils.Surround(fix, target, fix);
- }
-
- ///
- /// Surrounds (prepends and appends) the string values of the supplied
- /// and to the supplied
- /// .
- ///
- ///
- ///
- /// The return value of this method call is always guaranteed to be non
- /// . If every value passed as a parameter to this method is
- /// , the string will be returned.
- ///
- ///
- ///
- /// The value that will be prepended to the . If this value
- /// is not a value, it's attendant
- /// value will be used.
- ///
- ///
- /// The target that is to be surrounded. If this value is not a
- /// value, it's attendant
- /// value will be used.
- ///
- ///
- /// The value that will be appended to the . If this value
- /// is not a value, it's attendant
- /// value will be used.
- ///
- /// The surrounded string.
- public static string Surround(object prefix, object target, object suffix)
- {
- return string.Format(
- CultureInfo.InvariantCulture, "{0}{1}{2}", prefix, target, suffix);
- }
-
- ///
- /// Converts escaped characters (for example "\t") within a string
- /// to their real character.
- ///
- /// The string to convert.
- /// The converted string.
- public static string ConvertEscapedCharacters( string inputString )
- {
- StringBuilder sb = new StringBuilder(inputString.Length);
- for (int i = 0 ; i < inputString.Length ; i++)
- {
- if (inputString[i].Equals('\\'))
- {
- i++;
- if (inputString[i].Equals('t'))
- {
- sb.Append('\t');
- }
- else if (inputString[i].Equals('r'))
- {
- sb.Append('\r');
- }
- else if (inputString[i].Equals('n'))
- {
- sb.Append('\n');
- }
- else if (inputString[i].Equals('\\'))
- {
- sb.Append('\\');
- }
- else
- {
- sb.Append("\\" + inputString[i]);
- }
- }
- else
- {
- sb.Append(inputString[i]);
- }
- }
- return sb.ToString();
- }
- }
+ */
+
+#endregion
+
+#region Imports
+
+using System;
+using System.Collections;
+using System.Globalization;
+using System.Text;
+
+#endregion
+
+namespace Spring.Util
+{
+ ///
+ /// Miscellaneous utility methods.
+ ///
+ ///
+ ///
+ /// Mainly for internal use within the framework.
+ ///
+ ///
+ /// Rod Johnson
+ /// Juergen Hoeller
+ /// Keith Donald
+ /// Aleksandar Seovic (.NET)
+ /// Mark Pollack (.NET)
+ /// Rick Evans (.NET)
+ /// Erich Eichinger (.NET)
+ public sealed class StringUtils
+ {
+ ///
+ /// An empty array of instances.
+ ///
+ public static readonly string[] EmptyStrings = new string[] { };
+
+ ///
+ /// The string that signals the start of an Ant-style expression.
+ ///
+ private const string AntExpressionPrefix = "${";
+
+ ///
+ /// The string that signals the end of an Ant-style expression.
+ ///
+ private const string AntExpressionSuffix = "}";
+
+ #region Constructor (s) / Destructor
+
+ // CLOVER:OFF
+
+ ///
+ /// Creates a new instance of the class.
+ ///
+ ///
+ ///
+ /// This is a utility class, and as such exposes no public constructors.
+ ///
+ ///
+ private StringUtils()
+ {
+ }
+
+ // CLOVER:ON
+
+ #endregion
+
+ ///
+ /// Tokenize the given into a
+ /// array.
+ ///
+ ///
+ ///
+ /// If is , returns an empty
+ /// array.
+ ///
+ ///
+ /// If is or the empty
+ /// , returns a array with one
+ /// element: itself.
+ ///
+ ///
+ /// The to tokenize.
+ ///
+ /// The delimiter characters, assembled as a .
+ ///
+ ///
+ /// Trim the tokens via .
+ ///
+ ///
+ /// Omit empty tokens from the result array.
+ /// An array of the tokens.
+ public static string[] Split(
+ string s, string delimiters, bool trimTokens, bool ignoreEmptyTokens)
+ {
+ return Split(s, delimiters, trimTokens, ignoreEmptyTokens, null);
+ }
+
+ ///
+ /// Tokenize the given into a
+ /// array.
+ ///
+ ///
+ ///
+ /// If is , returns an empty
+ /// array.
+ ///
+ ///
+ /// If is or the empty
+ /// , returns a array with one
+ /// element: itself.
+ ///
+ ///
+ /// The to tokenize.
+ ///
+ /// The delimiter characters, assembled as a .
+ ///
+ ///
+ /// Trim the tokens via .
+ ///
+ ///
+ /// Omit empty tokens from the result array.
+ ///
+ ///
+ /// Pairs of quote characters. within a pair of quotes are ignored
+ ///
+ /// An array of the tokens.
+ public static string[] Split(
+ string s, string delimiters, bool trimTokens, bool ignoreEmptyTokens, string quoteChars)
+ {
+ if (s == null)
+ {
+ return new string[0];
+ }
+ if (delimiters==null || delimiters.Length==0)
+ {
+ return new string[] { s };
+ }
+ if (quoteChars == null)
+ {
+ quoteChars = string.Empty;
+ }
+ AssertUtils.IsTrue( quoteChars.Length % 2 == 0, "the number of quote characters must be even" );
+
+ char[] delimiterChars = delimiters.ToCharArray();
+
+ // scan separator positions
+ int[] delimiterPositions = new int[s.Length];
+ int count = MakeDelimiterPositionList(s, delimiterChars, quoteChars, delimiterPositions);
+
+ ArrayList tokens = new ArrayList(count+1);
+ int startIndex = 0;
+ for (int ixSep = 0; ixSep < count; ixSep++)
+ {
+ string token = s.Substring(startIndex, delimiterPositions[ixSep] - startIndex);
+ if (trimTokens)
+ {
+ token = token.Trim();
+ }
+ if (!(ignoreEmptyTokens && token.Length == 0))
+ {
+ tokens.Add(token);
+ }
+ startIndex = delimiterPositions[ixSep] + 1;
+ }
+ // add remainder
+ if (startIndex < s.Length)
+ {
+ string token = s.Substring(startIndex);
+ if (trimTokens)
+ {
+ token = token.Trim();
+ }
+ if (!(ignoreEmptyTokens && token.Length == 0))
+ {
+ tokens.Add(token);
+ }
+ }
+ else if (startIndex == s.Length)
+ {
+ if (!(ignoreEmptyTokens))
+ {
+ tokens.Add(string.Empty);
+ }
+ }
+
+ return (string[])tokens.ToArray(typeof(string));
+ }
+
+ private static int MakeDelimiterPositionList(string s, char[] delimiters, string quoteChars, int[] delimiterPositions)
+ {
+ int count = 0;
+ int quoteNestingDepth = 0;
+ char expectedQuoteOpenChar = '\0';
+ char expectedQuoteCloseChar = '\0';
+
+ for (int ixCurChar = 0; ixCurChar < s.Length; ixCurChar++)
+ {
+ char curChar = s[ixCurChar];
+
+ for (int ixCurDelim = 0; ixCurDelim < delimiters.Length; ixCurDelim++)
+ {
+ if (delimiters[ixCurDelim] == curChar)
+ {
+ if (quoteNestingDepth == 0)
+ {
+ delimiterPositions[count] = ixCurChar;
+ count++;
+ break;
+ }
+ }
+
+ if (quoteNestingDepth == 0)
+ {
+ // check, if we're facing an opening char
+ for (int ixCurQuoteChar = 0; ixCurQuoteChar < quoteChars.Length; ixCurQuoteChar+=2)
+ {
+ if (quoteChars[ixCurQuoteChar] == curChar)
+ {
+ quoteNestingDepth++;
+ expectedQuoteOpenChar = curChar;
+ expectedQuoteCloseChar = quoteChars[ixCurQuoteChar + 1];
+ break;
+ }
+ }
+ }
+ else
+ {
+ // check if we're facing an expected open or close char
+ if (curChar == expectedQuoteOpenChar)
+ {
+ quoteNestingDepth++;
+ }
+ else if (curChar == expectedQuoteCloseChar)
+ {
+ quoteNestingDepth--;
+ }
+ }
+ }
+ }
+ return count;
+ }
+
+ ///
+ /// Convert a CSV list into an array of s.
+ ///
+ ///
+ /// Values may also be quoted using doublequotes.
+ ///
+ /// A CSV list.
+ ///
+ /// An array of s, or the empty array
+ /// if is .
+ ///
+ public static string[] CommaDelimitedListToStringArray(string s)
+ {
+ return Split(s, ",", false, false, "\"\"");
+ }
+
+ ///
+ /// Take a which is a delimited list
+ /// and convert it to a array.
+ ///
+ ///
+ ///
+ /// If the supplied is a
+ /// or zero-length string, then a single element
+ /// array composed of the supplied
+ /// will be
+ /// eturned. If the supplied
+ /// is , then an empty,
+ /// zero-length array will be returned.
+ ///
+ ///
+ ///
+ /// The to be parsed.
+ ///
+ ///
+ /// The delimeter (this will not be returned). Note that only the first
+ /// character of the supplied is used.
+ ///
+ ///
+ /// An array of the tokens in the list.
+ ///
+ public static string[] DelimitedListToStringArray(string input, string delimiter)
+ {
+ if (input == null)
+ {
+ return new string[0];
+ }
+ if (!HasLength(delimiter))
+ {
+ return new string[] { input };
+ }
+ // return input.Split(delimiter[0]);
+ return Split(input, delimiter, false, false, null);
+ }
+
+ ///
+ /// Convenience method to return an
+ /// as a delimited
+ /// (e.g. CSV) .
+ ///
+ ///
+ /// The to parse.
+ ///
+ ///
+ /// The delimiter to use (probably a ',').
+ ///
+ /// The delimited string representation.
+ public static string CollectionToDelimitedString(
+ ICollection c, string delimiter)
+ {
+ if (c == null)
+ {
+ return "null";
+ }
+ StringBuilder sb = new StringBuilder();
+ int i = 0;
+ foreach (object obj in c)
+ {
+ if (i++ > 0)
+ {
+ sb.Append(delimiter);
+ }
+ sb.Append(obj);
+ }
+ return sb.ToString();
+ }
+
+ ///
+ /// Convenience method to return an
+ /// as a CSV
+ /// .
+ ///
+ ///
+ /// The to display.
+ ///
+ /// The delimited string representation.
+ public static string CollectionToCommaDelimitedString(
+ ICollection collection)
+ {
+ return CollectionToDelimitedString(collection, ",");
+ }
+
+ ///
+ /// Convenience method to return an array as a CSV
+ /// .
+ ///
+ ///
+ /// The array to parse. Elements may be of any type (
+ /// will be called on each
+ /// element).
+ ///
+ public static string ArrayToCommaDelimitedString(object[] source)
+ {
+ return ArrayToDelimitedString(source, ",");
+ }
+
+ ///
+ /// Convenience method to return a
+ /// array as a delimited (e.g. CSV) .
+ ///
+ ///
+ /// The array to parse. Elements may be of any type (
+ /// will be called on each
+ /// element).
+ ///
+ ///
+ /// The delimiter to use (probably a ',').
+ ///
+ public static string ArrayToDelimitedString(
+ object[] source, string delimiter)
+ {
+ if (source == null)
+ {
+ return "null";
+ }
+ else
+ {
+ return StringUtils.CollectionToDelimitedString(source, delimiter);
+ }
+ }
+
+ /// Checks if a string has length.
+ ///
+ /// The string to check, may be .
+ ///
+ ///
+ /// if the string has length and is not
+ /// .
+ ///
+ ///
+ ///
+ /// StringUtils.HasLength(null) = false
+ /// StringUtils.HasLength("") = false
+ /// StringUtils.HasLength(" ") = true
+ /// StringUtils.HasLength("Hello") = true
+ ///
+ ///
+ public static bool HasLength(string target)
+ {
+ return (target != null && target.Length > 0);
+ }
+
+ ///
+ /// Checks if a has text.
+ ///
+ ///
+ ///
+ /// More specifically, returns if the string is
+ /// not , it's is >
+ /// zero (0), and it has at least one non-whitespace character.
+ ///
+ ///
+ ///
+ /// The string to check, may be .
+ ///
+ ///
+ /// if the is not
+ /// ,
+ /// > zero (0), and does not consist
+ /// solely of whitespace.
+ ///
+ ///
+ ///
+ /// StringUtils.HasText(null) = false
+ /// StringUtils.HasText("") = false
+ /// StringUtils.HasText(" ") = false
+ /// StringUtils.HasText("12345") = true
+ /// StringUtils.HasText(" 12345 ") = true
+ ///
+ ///
+ public static bool HasText(string target)
+ {
+ if (target == null)
+ {
+ return false;
+ }
+ else
+ {
+ return HasLength(target.Trim());
+ }
+ }
+
+ ///
+ /// Checks if a is
+ /// or an empty string.
+ ///
+ ///
+ ///
+ /// More specifically, returns if the string is
+ /// , it's is equal
+ /// to zero (0), or it is composed entirely of whitespace
+ /// characters.
+ ///
+ ///
+ ///
+ /// The string to check, may (obviously) be .
+ ///
+ ///
+ /// if the is
+ /// , has a length equal to zero (0), or
+ /// is composed entirely of whitespace characters.
+ ///
+ ///
+ ///
+ /// StringUtils.IsNullOrEmpty(null) = true
+ /// StringUtils.IsNullOrEmpty("") = true
+ /// StringUtils.IsNullOrEmpty(" ") = true
+ /// StringUtils.IsNullOrEmpty("12345") = false
+ /// StringUtils.IsNullOrEmpty(" 12345 ") = false
+ ///
+ ///
+ public static bool IsNullOrEmpty(string target)
+ {
+ return !HasText(target);
+ }
+
+ ///
+ /// Strips first and last character off the string.
+ ///
+ /// The string to strip.
+ /// The stripped string.
+ public static string StripFirstAndLastCharacter(string text)
+ {
+ if (text != null
+ && text.Length > 2)
+ {
+ return text.Substring(1, text.Length - 2);
+ }
+ else
+ {
+ return String.Empty;
+ }
+ }
+
+ ///
+ /// Returns a list of Ant-style expressions from the specified text.
+ ///
+ /// The text to inspect.
+ ///
+ /// A list of expressions that exist in the specified text.
+ ///
+ ///
+ /// If any of the expressions in the supplied
+ /// is empty (${}).
+ ///
+ public static IList GetAntExpressions(string text)
+ {
+ IList expressions = new ArrayList();
+ if (StringUtils.HasText(text))
+ {
+ int start = text.IndexOf(AntExpressionPrefix);
+ while (start >= 0)
+ {
+ int end = text.IndexOf(AntExpressionSuffix, start + 2);
+ if (end == -1)
+ {
+ // terminator character not found, so let's quit...
+ start = -1;
+ }
+ else
+ {
+ string exp = text.Substring(start + 2, end - start - 2);
+ if (StringUtils.IsNullOrEmpty(exp))
+ {
+ throw new FormatException(
+ string.Format("Empty {0}{1} value found in text : '{2}'.",
+ AntExpressionPrefix,
+ AntExpressionSuffix,
+ text));
+ }
+ if (expressions.IndexOf(exp) < 0)
+ {
+ expressions.Add(exp);
+ }
+ start = text.IndexOf(AntExpressionPrefix, end);
+ }
+ }
+ }
+ return expressions;
+ }
+
+ ///
+ /// Replaces Ant-style expression placeholder with expression value.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// The string to set the value in.
+ /// The name of the expression to set.
+ /// The expression value.
+ ///
+ /// A new string with the expression value set; the
+ /// value if the supplied
+ /// is , has a length
+ /// equal to zero (0), or is composed entirely of whitespace
+ /// characters.
+ ///
+ public static string SetAntExpression(string text, string expression, object expValue)
+ {
+ if (StringUtils.IsNullOrEmpty(text))
+ {
+ return String.Empty;
+ }
+ if (expValue == null)
+ {
+ expValue = String.Empty;
+ }
+ return text.Replace(
+ StringUtils.Surround(AntExpressionPrefix, expression, AntExpressionSuffix), expValue.ToString());
+ }
+
+ ///
+ /// Surrounds (prepends and appends) the string value of the supplied
+ /// to the supplied .
+ ///
+ ///
+ ///
+ /// The return value of this method call is always guaranteed to be non
+ /// . If every value passed as a parameter to this method is
+ /// , the string will be returned.
+ ///
+ ///
+ ///
+ /// The prefix and suffix that respectively will be prepended and
+ /// appended to the target . If this value
+ /// is not a value, it's attendant
+ /// value will be used.
+ ///
+ ///
+ /// The target that is to be surrounded. If this value is not a
+ /// value, it's attendant
+ /// value will be used.
+ ///
+ /// The surrounded string.
+ public static string Surround(object fix, object target)
+ {
+ return StringUtils.Surround(fix, target, fix);
+ }
+
+ ///
+ /// Surrounds (prepends and appends) the string values of the supplied
+ /// and to the supplied
+ /// .
+ ///
+ ///
+ ///
+ /// The return value of this method call is always guaranteed to be non
+ /// . If every value passed as a parameter to this method is
+ /// , the string will be returned.
+ ///
+ ///
+ ///
+ /// The value that will be prepended to the . If this value
+ /// is not a value, it's attendant
+ /// value will be used.
+ ///
+ ///
+ /// The target that is to be surrounded. If this value is not a
+ /// value, it's attendant
+ /// value will be used.
+ ///
+ ///
+ /// The value that will be appended to the . If this value
+ /// is not a value, it's attendant
+ /// value will be used.
+ ///
+ /// The surrounded string.
+ public static string Surround(object prefix, object target, object suffix)
+ {
+ return string.Format(
+ CultureInfo.InvariantCulture, "{0}{1}{2}", prefix, target, suffix);
+ }
+
+ ///
+ /// Converts escaped characters (for example "\t") within a string
+ /// to their real character.
+ ///
+ /// The string to convert.
+ /// The converted string.
+ public static string ConvertEscapedCharacters(string inputString)
+ {
+ StringBuilder sb = new StringBuilder(inputString.Length);
+ for (int i = 0; i < inputString.Length; i++)
+ {
+ if (inputString[i].Equals('\\'))
+ {
+ i++;
+ if (inputString[i].Equals('t'))
+ {
+ sb.Append('\t');
+ }
+ else if (inputString[i].Equals('r'))
+ {
+ sb.Append('\r');
+ }
+ else if (inputString[i].Equals('n'))
+ {
+ sb.Append('\n');
+ }
+ else if (inputString[i].Equals('\\'))
+ {
+ sb.Append('\\');
+ }
+ else
+ {
+ sb.Append("\\" + inputString[i]);
+ }
+ }
+ else
+ {
+ sb.Append(inputString[i]);
+ }
+ }
+ return sb.ToString();
+ }
+ }
}
\ No newline at end of file
diff --git a/test/Spring/Spring.Core.Tests/Core/TypeResolution/GenericTypeResolverTests.cs b/test/Spring/Spring.Core.Tests/Core/TypeResolution/GenericTypeResolverTests.cs
index 5e08da11..b57b50a9 100644
--- a/test/Spring/Spring.Core.Tests/Core/TypeResolution/GenericTypeResolverTests.cs
+++ b/test/Spring/Spring.Core.Tests/Core/TypeResolution/GenericTypeResolverTests.cs
@@ -48,7 +48,7 @@ namespace Spring.Core.TypeResolution
public void ResolveLocalAssemblyGenericType()
{
Type t = GetTypeResolver().Resolve("Spring.Objects.TestGenericObject< int, string>");
- Assert.AreEqual(typeof(TestGenericObject), t);
+ Assert.AreEqual(typeof(TestGenericObject), t);
}
[Test]
@@ -74,6 +74,26 @@ namespace Spring.Core.TypeResolution
Assert.AreEqual(typeof(System.Collections.Generic.Stack), t);
}
+ [Test]
+ public void ResolveGenericArrayType()
+ {
+ Type t = GetTypeResolver().Resolve("System.Nullable<[System.Int32, mscorlib]>[,]");
+ Assert.AreEqual(typeof(int?[,]), t);
+ t = GetTypeResolver().Resolve("System.Nullable`1[int][,]");
+ Assert.AreEqual(typeof(int?[,]), t);
+ }
+
+ [Test]
+ public void ResolveGenericArrayTypeWithAssemblyName()
+ {
+ Type t = GetTypeResolver().Resolve("System.Nullable<[System.Int32, mscorlib]>[,], mscorlib");
+ Assert.AreEqual(typeof(int?[,]), t);
+ t = GetTypeResolver().Resolve("System.Nullable<[System.Int32, mscorlib]>[,], mscorlib");
+ Assert.AreEqual(typeof(int?[,]), t);
+ t = GetTypeResolver().Resolve("System.Nullable`1[[System.Int32, mscorlib]][,], mscorlib");
+ Assert.AreEqual(typeof(int?[,]), t);
+ }
+
[Test]
[ExpectedException(typeof(TypeLoadException))]
public void ResolveAmbiguousGenericTypeWithAssemblyName()
@@ -87,6 +107,27 @@ namespace Spring.Core.TypeResolution
{
Type t = GetTypeResolver().Resolve("Spring.Objects.TestGenericObject>");
}
+
+ [Test]
+ public void ResolveNestedGenericTypeWithAssemblyName()
+ {
+ Type t = GetTypeResolver().Resolve("System.Collections.Generic.Stack< Spring.Objects.TestGenericObject >, System");
+ Assert.AreEqual(typeof(System.Collections.Generic.Stack>), t);
+ }
+
+ [Test]
+ public void ResolveClrNotationStyleGenericTypeWithAssemblyName()
+ {
+ Type t = GetTypeResolver().Resolve("System.Collections.Generic.Stack`1[ [Spring.Objects.TestGenericObject`2[int, string], Spring.Core.Tests] ], System");
+ Assert.AreEqual(typeof(System.Collections.Generic.Stack>), t);
+ }
+
+ [Test]
+ public void ResolveNestedQuotedGenericTypeWithAssemblyName()
+ {
+ Type t = GetTypeResolver().Resolve("System.Collections.Generic.Stack< [Spring.Objects.TestGenericObject, Spring.Core.Tests] >, System");
+ Assert.AreEqual(typeof(System.Collections.Generic.Stack>), t);
+ }
}
}
diff --git a/test/Spring/Spring.Core.Tests/Expressions/ExpressionEvaluatorTests.cs b/test/Spring/Spring.Core.Tests/Expressions/ExpressionEvaluatorTests.cs
index 4878e0f8..7bc4343b 100644
--- a/test/Spring/Spring.Core.Tests/Expressions/ExpressionEvaluatorTests.cs
+++ b/test/Spring/Spring.Core.Tests/Expressions/ExpressionEvaluatorTests.cs
@@ -703,12 +703,33 @@ namespace Spring.Expressions
/// Tests type node
///