Index: framework/src/test/org/apache/hivemind/util/TestStringUtils.java =================================================================== --- framework/src/test/org/apache/hivemind/util/TestStringUtils.java (revisión: 387550) +++ framework/src/test/org/apache/hivemind/util/TestStringUtils.java (copia de trabajo) @@ -89,4 +89,66 @@ { assertEquals(null, StringUtils.join(new String[0], ',')); } + + public void testEscapedSplit() + { + assertListsEqual( + new String[] { "alpha", "beta" }, + StringUtils.escapedSplit("alpha,beta", ',')); + } + + public void testEscapedSplitEscapes() + { + assertListsEqual( + new String[] { "alpha,beta", "gamma" }, + StringUtils.escapedSplit("alpha\\,beta,gamma", ',')); + } + + public void testEscapedSplitEscapesNoDelim() + { + assertListsEqual( + new String[] { "alpha\\", "beta", "gamma" }, + StringUtils.escapedSplit("alpha\\\\,beta,gamma", ',')); + } + + public void testEscapedSplitSingle() + { + assertListsEqual( + new String[] { "alpha" }, + StringUtils.escapedSplit("alpha", ',')); + } + + public void testEscapedSplitSingleEscapes() + { + // Trailing single "\" is ignored. + assertListsEqual( + new String[] { "alpha" }, + StringUtils.escapedSplit("alpha\\", ',')); + } + + public void testEscapedSplitSingleEscapesDouble() + { + // Trailing double "\" is included. + assertListsEqual( + new String[] { "alpha\\" }, + StringUtils.escapedSplit("alpha\\\\", ',')); + } + + public void testEscapedSplitNull() + { + assertListsEqual(new String[0], StringUtils.escapedSplit(null, ',')); + } + + public void testEscapedSplitEmpty() + { + assertListsEqual(new String[0], StringUtils.escapedSplit("", ',')); + } + + public void testEscapedSplitTrailingComma() + { + assertListsEqual( + new String[] { "fred", "barney", "wilma" }, + StringUtils.escapedSplit("fred,barney,wilma,", ',')); + } + } \ No newline at end of file Index: framework/src/java/org/apache/hivemind/util/ClassAdaptor.java =================================================================== --- framework/src/java/org/apache/hivemind/util/ClassAdaptor.java (revisión: 387550) +++ framework/src/java/org/apache/hivemind/util/ClassAdaptor.java (copia de trabajo) @@ -20,14 +20,13 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.StringTokenizer; import org.apache.hivemind.ApplicationRuntimeException; /** * Provides access to an object (of a particular class) as a set of individual property that may be * read or updated. - * + * * @author Howard Lewis Ship */ class ClassAdaptor @@ -49,7 +48,7 @@ /** * Updates the property of the target object. - * + * * @param target * the object to update * @param value @@ -65,7 +64,7 @@ /** * An improved version of {@link #write(Object, String, Object)} that can convert a string value * to an appropriate property type value. - * + * * @since 1.1 */ @@ -78,7 +77,7 @@ /** * Reads the property of the target object. - * + * * @param target * the object to read * @param propertyName @@ -93,7 +92,7 @@ /** * Returns the type of the named property. - * + * * @param target * the object to examine * @param propertyName @@ -182,17 +181,16 @@ /** * Does the grunt work for * {@link org.apache.hivemind.util.PropertyUtils#configureProperties(Object, String)}. - * + * * @since 1.1 */ public void configureProperties(Object target, String initializer) { - StringTokenizer tokenizer = new StringTokenizer(initializer, ","); - - while (tokenizer.hasMoreTokens()) - { - configurePropertyFromToken(target, tokenizer.nextToken()); + String [] tokens = StringUtils.escapedSplit(initializer, ','); + for(int i = 0; i < tokens.length; i++) { + String token = tokens[i]; + configurePropertyFromToken(target, token); } } @@ -204,7 +202,7 @@ *
  • !propertyName
  • * * The later two are for boolean properties (true and false, respectively). - * + * * @since 1.1 */ private void configurePropertyFromToken(Object target, String token) Index: framework/src/java/org/apache/hivemind/util/StringUtils.java =================================================================== --- framework/src/java/org/apache/hivemind/util/StringUtils.java (revisión: 387550) +++ framework/src/java/org/apache/hivemind/util/StringUtils.java (copia de trabajo) @@ -29,7 +29,7 @@ /** * Splits an input string into a an array of strings, seperating * at commas. - * + * * @param input the string to split, possibly null or empty * @return an array of the strings split at commas */ @@ -64,7 +64,7 @@ /** * Converts a string such that the first character is upper case. - * + * * @param input the input string (possibly empty) * @return the string with the first character converted from lowercase to upper case (may * return the string unchanged if already capitalized) @@ -118,8 +118,49 @@ pos = index + patternLength; } sbuf.append(string.substring(pos)); - + return sbuf.toString(); } - + + /** + * Splits the string, using delim as delimiter. Escaping the delimiter + * it's allowed, using the character '\'. + * @param string the string to escape. + * @param delim the delimiter. + * @return An array of tokens. + */ + public static String[] escapedSplit(String string, char delim) { + if(string == null || string.trim().length() == 0) { + return new String[0]; + } + + boolean skippedLast = false; + StringBuffer sb = new StringBuffer(); + List tokens = new ArrayList(); + + for(int i = 0; i < string.length(); i++) { + char ch = string.charAt(i); + + if(ch == '\\' && !skippedLast) { + skippedLast = true; + } + else { + if(ch == delim && !skippedLast) { + tokens.add(sb.toString()); + sb = new StringBuffer(); + } + else { + sb.append(ch); + } + skippedLast = false; + } + } + + String lastToken = sb.toString(); + if(lastToken.length() > 0) { + tokens.add(lastToken); + } + return (String []) tokens.toArray(new String[] {}); + } + }