Added deNull() widened.

git-svn-id: https://samskivert.googlecode.com/svn/trunk@2054 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
samskivert@gmail.com
2007-02-19 18:17:45 +00:00
parent 513d469816
commit 028d9ebfe8
+191 -273
View File
@@ -53,6 +53,27 @@ import java.util.regex.Pattern;
*/ */
public class StringUtil public class StringUtil
{ {
/**
* Used to format objects in {@link #listToString(Object,StringUtil.Formatter)}.
*/
public static class Formatter
{
/** Formats the supplied object into a string. */
public String toString (Object object) {
return object == null ? "null" : object.toString();
}
/** Returns the string that will be prepended to a formatted list. */
public String getOpenBox () {
return "(";
}
/** Returns the string that will be appended to a formatted list. */
public String getCloseBox () {
return ")";
}
}
/** /**
* @return true if the string is null or empty, false otherwise. * @return true if the string is null or empty, false otherwise.
* *
@@ -72,6 +93,14 @@ public class StringUtil
return (value == null || value.trim().length() == 0); return (value == null || value.trim().length() == 0);
} }
/**
* @return the supplied string if it is non-null, "" if it is null.
*/
public static String deNull (String value)
{
return (value == null) ? "" : value;
}
/** /**
* Truncate the specified String if it is longer than maxLength. * Truncate the specified String if it is longer than maxLength.
*/ */
@@ -81,12 +110,11 @@ public class StringUtil
} }
/** /**
* Truncate the specified String if it is longer than maxLength. * Truncate the specified String if it is longer than maxLength. The string will be truncated
* The string will be truncated at a position such that it is * at a position such that it is maxLength chars long after the addition of the 'append'
* maxLength chars long after the addition of the 'append' String. * String.
* *
* @param append a String to add to the truncated String only after * @param append a String to add to the truncated String only after truncation.
* truncation.
*/ */
public static String truncate (String s, int maxLength, String append) public static String truncate (String s, int maxLength, String append)
{ {
@@ -98,8 +126,7 @@ public class StringUtil
} }
/** /**
* Returns a version of the supplied string with the first letter * Returns a version of the supplied string with the first letter capitalized.
* capitalized.
*/ */
public static String capitalize (String s) public static String capitalize (String s)
{ {
@@ -142,8 +169,8 @@ public class StringUtil
} }
/** /**
* Sanitize the specified String such that each character must match * Sanitize the specified String such that each character must match against the regex
* against the regex specified. * specified.
*/ */
public static String sanitize (String source, String charRegex) public static String sanitize (String source, String charRegex)
{ {
@@ -158,8 +185,8 @@ public class StringUtil
} }
/** /**
* Returns a new string based on <code>source</code> with all * Returns a new string based on <code>source</code> with all instances of <code>before</code>
* instances of <code>before</code> replaced with <code>after</code>. * replaced with <code>after</code>.
*/ */
public static String replace (String source, String before, String after) public static String replace (String source, String before, String after)
{ {
@@ -184,40 +211,34 @@ public class StringUtil
} }
/** /**
* Pads the supplied string to the requested string width by appending * Pads the supplied string to the requested string width by appending spaces to the end of the
* spaces to the end of the returned string. If the original string is * returned string. If the original string is wider than the requested width, it is returned
* wider than the requested width, it is returned unmodified. * unmodified.
*/ */
public static String pad (String value, int width) public static String pad (String value, int width)
{ {
// sanity check // sanity check
if (width <= 0) { if (width <= 0) {
String errmsg = "Pad width must be greater than zero."; throw new IllegalArgumentException("Pad width must be greater than zero.");
throw new IllegalArgumentException(errmsg);
} else if (value.length() >= width) { } else if (value.length() >= width) {
return value; return value;
} else { } else {
return value + spaces(width-value.length()); return value + spaces(width-value.length());
} }
} }
/** /**
* Pads the supplied string to the requested string width by prepending * Pads the supplied string to the requested string width by prepending spaces to the end of
* spaces to the end of the returned string. If the original string is * the returned string. If the original string is wider than the requested width, it is
* wider than the requested width, it is returned unmodified. * returned unmodified.
*/ */
public static String prepad (String value, int width) public static String prepad (String value, int width)
{ {
// sanity check // sanity check
if (width <= 0) { if (width <= 0) {
String errmsg = "Pad width must be greater than zero."; throw new IllegalArgumentException("Pad width must be greater than zero.");
throw new IllegalArgumentException(errmsg);
} else if (value.length() >= width) { } else if (value.length() >= width) {
return value; return value;
} else { } else {
return spaces(width-value.length()) + value; return spaces(width-value.length()) + value;
} }
@@ -232,8 +253,7 @@ public class StringUtil
} }
/** /**
* Returns a string containing the specified character repeated the * Returns a string containing the specified character repeated the specified number of times.
* specified number of times.
*/ */
public static String fill (char c, int count) public static String fill (char c, int count)
{ {
@@ -243,8 +263,8 @@ public class StringUtil
} }
/** /**
* Returns whether the supplied string represents an integer value by * Returns whether the supplied string represents an integer value by attempting to parse it
* attempting to parse it with {@link Integer#parseInt}. * with {@link Integer#parseInt}.
*/ */
public static boolean isInteger (String value) public static boolean isInteger (String value)
{ {
@@ -258,9 +278,8 @@ public class StringUtil
} }
/** /**
* Formats a floating point value with useful default rules; * Formats a floating point value with useful default rules; ie. always display a digit to the
* ie. always display a digit to the left of the decimal and display * left of the decimal and display only two digits to the right of the decimal (rounding as
* only two digits to the right of the decimal (rounding as
* necessary). * necessary).
*/ */
public static String format (float value) public static String format (float value)
@@ -269,9 +288,8 @@ public class StringUtil
} }
/** /**
* Formats a floating point value with useful default rules; * Formats a floating point value with useful default rules; ie. always display a digit to the
* ie. always display a digit to the left of the decimal and display * left of the decimal and display only two digits to the right of the decimal (rounding as
* only two digits to the right of the decimal (rounding as
* necessary). * necessary).
*/ */
public static String format (double value) public static String format (double value)
@@ -280,25 +298,21 @@ public class StringUtil
} }
/** /**
* Converts the supplied object to a string. Normally this is * Converts the supplied object to a string. Normally this is accomplished via the object's
* accomplished via the object's built in <code>toString()</code> * built in <code>toString()</code> method, but in the case of arrays, <code>toString()</code>
* method, but in the case of arrays, <code>toString()</code> is * is called on each element and the contents are listed like so:
* called on each element and the contents are listed like so:
* *
* <pre> * <pre>
* (value, value, value) * (value, value, value)
* </pre> * </pre>
* *
* Arrays of ints, longs, floats and doubles are also handled for * Arrays of ints, longs, floats and doubles are also handled for convenience.
* convenience.
* *
* <p> Additionally, <code>Enumeration</code> or <code>Iterator</code> * <p> Additionally, <code>Enumeration</code> or <code>Iterator</code> objects can be passed
* objects can be passed and they will be enumerated and output in a * and they will be enumerated and output in a similar manner to arrays. Bear in mind that this
* similar manner to arrays. Bear in mind that this uses up the * uses up the enumeration or iterator in question.
* enumeration or iterator in question.
* *
* <p> Also note that passing null will result in the string "null" * <p> Also note that passing null will result in the string "null" being returned.
* being returned.
*/ */
public static String toString (Object val) public static String toString (Object val)
{ {
@@ -308,11 +322,9 @@ public class StringUtil
} }
/** /**
* Like the single argument {@link #toString(Object)} with the * Like the single argument {@link #toString(Object)} with the additional function of
* additional function of specifying the characters that are used to * specifying the characters that are used to box in list and array types. For example, if "["
* box in list and array types. For example, if "[" and "]" were * and "]" were supplied, an int array might be formatted like so: <code>[1, 3, 5]</code>.
* supplied, an int array might be formatted like so: <code>[1, 3,
* 5]</code>.
*/ */
public static String toString ( public static String toString (
Object val, String openBox, String closeBox) Object val, String openBox, String closeBox)
@@ -323,9 +335,8 @@ public class StringUtil
} }
/** /**
* Converts the supplied value to a string and appends it to the * Converts the supplied value to a string and appends it to the supplied string buffer. See
* supplied string buffer. See the single argument version for more * the single argument version for more information.
* information.
* *
* @param buf the string buffer to which we will append the string. * @param buf the string buffer to which we will append the string.
* @param val the value from which to generate the string. * @param val the value from which to generate the string.
@@ -336,29 +347,24 @@ public class StringUtil
} }
/** /**
* Converts the supplied value to a string and appends it to the * Converts the supplied value to a string and appends it to the supplied string buffer. The
* supplied string buffer. The specified boxing characters are used to * specified boxing characters are used to enclose list and array types. For example, if "["
* enclose list and array types. For example, if "[" and "]" were * and "]" were supplied, an int array might be formatted like so: <code>[1, 3, 5]</code>.
* supplied, an int array might be formatted like so: <code>[1, 3,
* 5]</code>.
* *
* @param buf the string buffer to which we will append the string. * @param buf the string buffer to which we will append the string.
* @param val the value from which to generate the string. * @param val the value from which to generate the string.
* @param openBox the opening box character. * @param openBox the opening box character.
* @param closeBox the closing box character. * @param closeBox the closing box character.
*/ */
public static void toString ( public static void toString (StringBuilder buf, Object val, String openBox, String closeBox)
StringBuilder buf, Object val, String openBox, String closeBox)
{ {
toString(buf, val, openBox, closeBox, ", "); toString(buf, val, openBox, closeBox, ", ");
} }
/** /**
* Converts the supplied value to a string and appends it to the * Converts the supplied value to a string and appends it to the supplied string buffer. The
* supplied string buffer. The specified boxing characters are used to * specified boxing characters are used to enclose list and array types. For example, if "["
* enclose list and array types. For example, if "[" and "]" were * and "]" were supplied, an int array might be formatted like so: <code>[1, 3, 5]</code>.
* supplied, an int array might be formatted like so: <code>[1, 3,
* 5]</code>.
* *
* @param buf the string buffer to which we will append the string. * @param buf the string buffer to which we will append the string.
* @param val the value from which to generate the string. * @param val the value from which to generate the string.
@@ -366,8 +372,8 @@ public class StringUtil
* @param closeBox the closing box character. * @param closeBox the closing box character.
* @param sep the separator string. * @param sep the separator string.
*/ */
public static void toString (StringBuilder buf, Object val, public static void toString (
String openBox, String closeBox, String sep) StringBuilder buf, Object val, String openBox, String closeBox, String sep)
{ {
if (val instanceof byte[]) { if (val instanceof byte[]) {
buf.append(openBox); buf.append(openBox);
@@ -507,43 +513,11 @@ public class StringUtil
} }
/** /**
* Used to format objects in {@link * Formats a collection of elements (either an array of objects, an {@link Iterator}, an {@link
* #listToString(Object,StringUtil.Formatter)}. * Enumeration} or a {@link Collection}) using the supplied formatter on each element. Note
*/ * that if you simply wish to format a collection of elements by calling {@link
public static class Formatter * Object#toString} on each element, you can just pass the list to the {@link
{ * #toString(Object)} method which will do just that.
/**
* Formats the supplied object into a string.
*/
public String toString (Object object)
{
return object == null ? "null" : object.toString();
}
/**
* Returns the string that will be prepended to a formatted list.
*/
public String getOpenBox ()
{
return "(";
}
/**
* Returns the string that will be appended to a formatted list.
*/
public String getCloseBox ()
{
return ")";
}
}
/**
* Formats a collection of elements (either an array of objects, an
* {@link Iterator}, an {@link Enumeration} or a {@link Collection})
* using the supplied formatter on each element. Note that if you
* simply wish to format a collection of elements by calling {@link
* Object#toString} on each element, you can just pass the list to the
* {@link #toString(Object)} method which will do just that.
*/ */
public static String listToString (Object val, Formatter formatter) public static String listToString (Object val, Formatter formatter)
{ {
@@ -553,12 +527,10 @@ public class StringUtil
} }
/** /**
* Formats the supplied collection into the supplied string buffer * Formats the supplied collection into the supplied string buffer using the supplied
* using the supplied formatter. See {@link * formatter. See {@link #listToString(Object,StringUtil.Formatter)} for more details.
* #listToString(Object,StringUtil.Formatter)} for more details.
*/ */
public static void listToString ( public static void listToString (StringBuilder buf, Object val, Formatter formatter)
StringBuilder buf, Object val, Formatter formatter)
{ {
// get an iterator if this is a collection // get an iterator if this is a collection
if (val instanceof Iterable) { if (val instanceof Iterable) {
@@ -608,9 +580,8 @@ public class StringUtil
} }
/** /**
* Generates a string representation of the supplied object by calling * Generates a string representation of the supplied object by calling {@link #toString} on the
* {@link #toString} on the contents of its public fields and * contents of its public fields and prefixing that by the name of the fields. For example:
* prefixing that by the name of the fields. For example:
* *
* <p><code>[itemId=25, itemName=Elvis, itemCoords=(14, 25)]</code> * <p><code>[itemId=25, itemName=Elvis, itemCoords=(14, 25)]</code>
*/ */
@@ -620,8 +591,8 @@ public class StringUtil
} }
/** /**
* Like {@link #fieldsToString(Object)} except that the supplied * Like {@link #fieldsToString(Object)} except that the supplied separator string will be used
* separator string will be used between fields. * between fields.
*/ */
public static String fieldsToString (Object object, String sep) public static String fieldsToString (Object object, String sep)
{ {
@@ -631,15 +602,14 @@ public class StringUtil
} }
/** /**
* Appends to the supplied string buffer a representation of the * Appends to the supplied string buffer a representation of the supplied object by calling
* supplied object by calling {@link #toString} on the contents of its * {@link #toString} on the contents of its public fields and prefixing that by the name of the
* public fields and prefixing that by the name of the fields. For * fields. For example:
* example:
* *
* <p><code>itemId=25, itemName=Elvis, itemCoords=(14, 25)</code> * <p><code>itemId=25, itemName=Elvis, itemCoords=(14, 25)</code>
* *
* <p>Note: unlike the version of this method that returns a string, * <p>Note: unlike the version of this method that returns a string, enclosing brackets are not
* enclosing brackets are not included in the output of this method. * included in the output of this method.
*/ */
public static void fieldsToString (StringBuilder buf, Object object) public static void fieldsToString (StringBuilder buf, Object object)
{ {
@@ -647,8 +617,8 @@ public class StringUtil
} }
/** /**
* Like {@link #fieldsToString(StringBuilder,Object)} except that the * Like {@link #fieldsToString(StringBuilder,Object)} except that the supplied separator will
* supplied separator will be used between fields. * be used between fields.
*/ */
public static void fieldsToString ( public static void fieldsToString (
StringBuilder buf, Object object, String sep) StringBuilder buf, Object object, String sep)
@@ -660,8 +630,7 @@ public class StringUtil
// we only want non-static fields // we only want non-static fields
for (int i = 0; i < fields.length; i++) { for (int i = 0; i < fields.length; i++) {
int mods = fields[i].getModifiers(); int mods = fields[i].getModifiers();
if ((mods & Modifier.PUBLIC) == 0 || if ((mods & Modifier.PUBLIC) == 0 || (mods & Modifier.STATIC) != 0) {
(mods & Modifier.STATIC) != 0) {
continue; continue;
} }
@@ -673,8 +642,7 @@ public class StringUtil
buf.append(fields[i].getName()).append("="); buf.append(fields[i].getName()).append("=");
try { try {
try { try {
Method meth = clazz.getMethod( Method meth = clazz.getMethod(fields[i].getName() + "ToString", new Class[0]);
fields[i].getName() + "ToString", new Class[0]);
buf.append(meth.invoke(object, (Object[]) null)); buf.append(meth.invoke(object, (Object[]) null));
} catch (NoSuchMethodException nsme) { } catch (NoSuchMethodException nsme) {
toString(buf, fields[i].get(object)); toString(buf, fields[i].get(object));
@@ -687,9 +655,8 @@ public class StringUtil
} }
/** /**
* Formats a pair of coordinates such that positive values are * Formats a pair of coordinates such that positive values are rendered with a plus prefix and
* rendered with a plus prefix and negative values with a minus * negative values with a minus prefix. Examples would look like: <code>+3+4</code>
* prefix. Examples would look like: <code>+3+4</code>
* <code>-5+7</code>, etc. * <code>-5+7</code>, etc.
*/ */
public static String coordsToString (int x, int y) public static String coordsToString (int x, int y)
@@ -700,9 +667,8 @@ public class StringUtil
} }
/** /**
* Formats a pair of coordinates such that positive values are * Formats a pair of coordinates such that positive values are rendered with a plus prefix and
* rendered with a plus prefix and negative values with a minus * negative values with a minus prefix. Examples would look like: <code>+3+4</code>
* prefix. Examples would look like: <code>+3+4</code>
* <code>-5+7</code>, etc. * <code>-5+7</code>, etc.
*/ */
public static void coordsToString (StringBuilder buf, int x, int y) public static void coordsToString (StringBuilder buf, int x, int y)
@@ -718,11 +684,10 @@ public class StringUtil
} }
/** /**
* Attempts to generate a string representation of the object using * Attempts to generate a string representation of the object using {@link Object#toString},
* <code>object.toString()</code>, but catches any exceptions that are * but catches any exceptions that are thrown and reports them in the returned string
* thrown and reports them in the returned string instead. Useful for * instead. Useful for situations where you can't trust the rat bastards that implemented the
* situations where you can't trust the rat bastards that implemented * object you're toString()ing.
* the object you're toString()ing.
*/ */
public static String safeToString (Object object) public static String safeToString (Object object)
{ {
@@ -758,13 +723,12 @@ public class StringUtil
} }
/** /**
* Generates a string from the supplied bytes that is the HEX encoded * Generates a string from the supplied bytes that is the HEX encoded representation of those
* representation of those bytes. Returns the empty string for a * bytes. Returns the empty string for a <code>null</code> or empty byte array.
* <code>null</code> or empty byte array.
* *
* @param bytes the bytes for which we want a string representation. * @param bytes the bytes for which we want a string representation.
* @param count the number of bytes to stop at (which will be coerced * @param count the number of bytes to stop at (which will be coerced into being <= the length
* into being <= the length of the array). * of the array).
*/ */
public static String hexlate (byte[] bytes, int count) public static String hexlate (byte[] bytes, int count)
{ {
@@ -788,8 +752,8 @@ public class StringUtil
} }
/** /**
* Generates a string from the supplied bytes that is the HEX encoded * Generates a string from the supplied bytes that is the HEX encoded representation of those
* representation of those bytes. * bytes.
*/ */
public static String hexlate (byte[] bytes) public static String hexlate (byte[] bytes)
{ {
@@ -805,14 +769,13 @@ public class StringUtil
return null; return null;
} }
// if for some reason we are given a hex string that wasn't made // if for some reason we are given a hex string that wasn't made by hexlate, convert to
// by hexlate, convert to lowercase so things work. // lowercase so things work.
hex = hex.toLowerCase(); hex = hex.toLowerCase();
byte[] data = new byte[hex.length()/2]; byte[] data = new byte[hex.length()/2];
for (int ii = 0; ii < hex.length(); ii+=2) { for (int ii = 0; ii < hex.length(); ii+=2) {
int value = (byte)(XLATE.indexOf(hex.charAt(ii)) << 4); int value = (byte)(XLATE.indexOf(hex.charAt(ii)) << 4);
value += XLATE.indexOf(hex.charAt(ii+1)); value += XLATE.indexOf(hex.charAt(ii+1));
// values over 127 are wrapped around, restoring negative bytes // values over 127 are wrapped around, restoring negative bytes
data[ii/2] = (byte)value; data[ii/2] = (byte)value;
} }
@@ -823,8 +786,7 @@ public class StringUtil
/** /**
* Returns a hex string representing the MD5 encoded source. * Returns a hex string representing the MD5 encoded source.
* *
* @exception RuntimeException thrown if the MD5 codec was not * @exception RuntimeException thrown if the MD5 codec was not available in this JVM.
* available in this JVM.
*/ */
public static String md5hex (String source) public static String md5hex (String source)
{ {
@@ -837,16 +799,12 @@ public class StringUtil
} }
/** /**
* Parses an array of signed byte-sized integers from their string * Parses an array of signed byte-sized integers from their string representation. The array
* representation. The array should be represented as a bare list of * should be represented as a bare list of numbers separated by commas, for example:
* numbers separated by commas, for example:
* *
* <pre> * <pre>25, 17, 21, 99</pre>
* 25, 17, 21, 99
* </pre>
* *
* Any inability to parse the short array will result in the function * Any inability to parse the short array will result in the function returning null.
* returning null.
*/ */
public static byte[] parseByteArray (String source) public static byte[] parseByteArray (String source)
{ {
@@ -855,8 +813,7 @@ public class StringUtil
for (int i = 0; tok.hasMoreTokens(); i++) { for (int i = 0; tok.hasMoreTokens(); i++) {
try { try {
// trim the whitespace from the token // trim the whitespace from the token
String token = tok.nextToken().trim(); vals[i] = Byte.parseByte(tok.nextToken().trim());
vals[i] = Byte.parseByte(token);
} catch (NumberFormatException nfe) { } catch (NumberFormatException nfe) {
return null; return null;
} }
@@ -865,16 +822,12 @@ public class StringUtil
} }
/** /**
* Parses an array of short integers from their string representation. * Parses an array of short integers from their string representation. The array should be
* The array should be represented as a bare list of numbers separated * represented as a bare list of numbers separated by commas, for example:
* by commas, for example:
* *
* <pre> * <pre>25, 17, 21, 99</pre>
* 25, 17, 21, 99
* </pre>
* *
* Any inability to parse the short array will result in the function * Any inability to parse the short array will result in the function returning null.
* returning null.
*/ */
public static short[] parseShortArray (String source) public static short[] parseShortArray (String source)
{ {
@@ -883,8 +836,7 @@ public class StringUtil
for (int i = 0; tok.hasMoreTokens(); i++) { for (int i = 0; tok.hasMoreTokens(); i++) {
try { try {
// trim the whitespace from the token // trim the whitespace from the token
String token = tok.nextToken().trim(); vals[i] = Short.parseShort(tok.nextToken().trim());
vals[i] = Short.parseShort(token);
} catch (NumberFormatException nfe) { } catch (NumberFormatException nfe) {
return null; return null;
} }
@@ -893,16 +845,12 @@ public class StringUtil
} }
/** /**
* Parses an array of integers from it's string representation. The * Parses an array of integers from it's string representation. The array should be represented
* array should be represented as a bare list of numbers separated by * as a bare list of numbers separated by commas, for example:
* commas, for example:
* *
* <pre> * <pre>25, 17, 21, 99</pre>
* 25, 17, 21, 99
* </pre>
* *
* Any inability to parse the int array will result in the function * Any inability to parse the int array will result in the function returning null.
* returning null.
*/ */
public static int[] parseIntArray (String source) public static int[] parseIntArray (String source)
{ {
@@ -911,8 +859,7 @@ public class StringUtil
for (int i = 0; tok.hasMoreTokens(); i++) { for (int i = 0; tok.hasMoreTokens(); i++) {
try { try {
// trim the whitespace from the token // trim the whitespace from the token
String token = tok.nextToken().trim(); vals[i] = Integer.parseInt(tok.nextToken().trim());
vals[i] = Integer.parseInt(token);
} catch (NumberFormatException nfe) { } catch (NumberFormatException nfe) {
return null; return null;
} }
@@ -921,16 +868,12 @@ public class StringUtil
} }
/** /**
* Parses an array of longs from it's string representation. The * Parses an array of longs from it's string representation. The array should be represented as
* array should be represented as a bare list of numbers separated by * a bare list of numbers separated by commas, for example:
* commas, for example:
* *
* <pre> * <pre>25, 17125141422, 21, 99</pre>
* 25, 17125141422, 21, 99
* </pre>
* *
* Any inability to parse the long array will result in the function * Any inability to parse the long array will result in the function returning null.
* returning null.
*/ */
public static long[] parseLongArray (String source) public static long[] parseLongArray (String source)
{ {
@@ -939,8 +882,7 @@ public class StringUtil
for (int i = 0; tok.hasMoreTokens(); i++) { for (int i = 0; tok.hasMoreTokens(); i++) {
try { try {
// trim the whitespace from the token // trim the whitespace from the token
String token = tok.nextToken().trim(); vals[i] = Long.parseLong(tok.nextToken().trim());
vals[i] = Long.parseLong(token);
} catch (NumberFormatException nfe) { } catch (NumberFormatException nfe) {
return null; return null;
} }
@@ -949,16 +891,12 @@ public class StringUtil
} }
/** /**
* Parses an array of floats from it's string representation. The * Parses an array of floats from it's string representation. The array should be represented
* array should be represented as a bare list of numbers separated by * as a bare list of numbers separated by commas, for example:
* commas, for example:
* *
* <pre> * <pre>25.0, .5, 1, 0.99</pre>
* 25.0, .5, 1, 0.99
* </pre>
* *
* Any inability to parse the array will result in the function * Any inability to parse the array will result in the function returning null.
* returning null.
*/ */
public static float[] parseFloatArray (String source) public static float[] parseFloatArray (String source)
{ {
@@ -967,8 +905,7 @@ public class StringUtil
for (int i = 0; tok.hasMoreTokens(); i++) { for (int i = 0; tok.hasMoreTokens(); i++) {
try { try {
// trim the whitespace from the token // trim the whitespace from the token
String token = tok.nextToken().trim(); vals[i] = Float.parseFloat(tok.nextToken().trim());
vals[i] = Float.parseFloat(token);
} catch (NumberFormatException nfe) { } catch (NumberFormatException nfe) {
return null; return null;
} }
@@ -977,17 +914,13 @@ public class StringUtil
} }
/** /**
* Parses an array of strings from a single string. The array should * Parses an array of strings from a single string. The array should be represented as a bare
* be represented as a bare list of strings separated by commas, for * list of strings separated by commas, for example:
* example:
* *
* <pre> * <pre>mary, had, a, little, lamb, and, an, escaped, comma,,</pre>
* mary, had, a, little, lamb, and, an, escaped, comma,,
* </pre>
* *
* If a comma is desired in one of the strings, it should be escaped * If a comma is desired in one of the strings, it should be escaped by putting two commas in a
* by putting two commas in a row. Any inability to parse the string * row. Any inability to parse the string array will result in the function returning null.
* array will result in the function returning null.
*/ */
public static String[] parseStringArray (String source) public static String[] parseStringArray (String source)
{ {
@@ -995,9 +928,8 @@ public class StringUtil
} }
/** /**
* Like {@link #parseStringArray(String)} but can be instructed to * Like {@link #parseStringArray(String)} but can be instructed to invoke {@link String#intern}
* invoke {@link String#intern} on the strings being parsed into the * on the strings being parsed into the array.
* array.
*/ */
public static String[] parseStringArray (String source, boolean intern) public static String[] parseStringArray (String source, boolean intern)
{ {
@@ -1038,8 +970,8 @@ public class StringUtil
} }
/** /**
* Joins an array of strings (or objects which will be converted to * Joins an array of strings (or objects which will be converted to strings) into a single
* strings) into a single string separated by commas. * string separated by commas.
*/ */
public static String join (Object[] values) public static String join (Object[] values)
{ {
@@ -1047,12 +979,10 @@ public class StringUtil
} }
/** /**
* Joins an array of strings into a single string, separated by * Joins an array of strings into a single string, separated by commas, and optionally escaping
* commas, and optionally escaping commas that occur in the individual * commas that occur in the individual string values such that a subsequent call to {@link
* string values such that a subsequent call to {@link * #parseStringArray} would recreate the string array properly. Any elements in the values
* #parseStringArray} would recreate the string array properly. Any * array that are null will be treated as an empty string.
* elements in the values array that are null will be treated as an
* empty string.
*/ */
public static String join (Object[] values, boolean escape) public static String join (Object[] values, boolean escape)
{ {
@@ -1060,8 +990,8 @@ public class StringUtil
} }
/** /**
* Joins the supplied array of strings into a single string separated * Joins the supplied array of strings into a single string separated by the supplied
* by the supplied separator. * separator.
*/ */
public static String join (Object[] values, String separator) public static String join (Object[] values, String separator)
{ {
@@ -1071,8 +1001,7 @@ public class StringUtil
/** /**
* Helper function for the various <code>join</code> methods. * Helper function for the various <code>join</code> methods.
*/ */
protected static String join ( protected static String join (Object[] values, String separator, boolean escape)
Object[] values, String separator, boolean escape)
{ {
StringBuilder buf = new StringBuilder(); StringBuilder buf = new StringBuilder();
int vlength = values.length; int vlength = values.length;
@@ -1087,11 +1016,10 @@ public class StringUtil
} }
/** /**
* Joins an array of strings into a single string, separated by * Joins an array of strings into a single string, separated by commas, and escaping commas
* commas, and escaping commas that occur in the individual string * that occur in the individual string values such that a subsequent call to {@link
* values such that a subsequent call to {@link #parseStringArray} * #parseStringArray} would recreate the string array properly. Any elements in the values
* would recreate the string array properly. Any elements in the * array that are null will be treated as an empty string.
* values array that are null will be treated as an empty string.
*/ */
public static String joinEscaped (String[] values) public static String joinEscaped (String[] values)
{ {
@@ -1099,8 +1027,7 @@ public class StringUtil
} }
/** /**
* Splits the supplied string into components based on the specified * Splits the supplied string into components based on the specified separator string.
* separator string.
*/ */
public static String[] split (String source, String sep) public static String[] split (String source, String sep)
{ {
@@ -1133,11 +1060,10 @@ public class StringUtil
} }
/** /**
* Returns an array containing the values in the supplied array * Returns an array containing the values in the supplied array converted into a table of
* converted into a table of values wrapped at the specified column * values wrapped at the specified column count and fit into the specified field width. For
* count and fit into the specified field width. For example, a call * example, a call like <code>toWrappedString(values, 5, 3)</code> might result in output like
* like <code>toWrappedString(values, 5, 3)</code> might result in * so:
* output like so:
* *
* <pre> * <pre>
* 12 1 9 10 3 * 12 1 9 10 3
@@ -1165,8 +1091,8 @@ public class StringUtil
// append the value itself // append the value itself
buf.append(valbuf); buf.append(valbuf);
// if we're at the end of a row but not the end of the whole // if we're at the end of a row but not the end of the whole integer list, append a
// integer list, append a newline // newline
if (i % colCount == (colCount-1) && if (i % colCount == (colCount-1) &&
i != values.length-1) { i != values.length-1) {
buf.append("\n"); buf.append("\n");
@@ -1177,8 +1103,8 @@ public class StringUtil
} }
/** /**
* Used to convert a time interval to a more easily human readable * Used to convert a time interval to a more easily human readable string of the form: <code>1d
* string of the form: <code>1d 15h 4m 15s 987m</code>. * 15h 4m 15s 987m</code>.
*/ */
public static String intervalToString (long millis) public static String intervalToString (long millis)
{ {
@@ -1212,11 +1138,9 @@ public class StringUtil
} }
/** /**
* Returns the class name of the supplied object, truncated to one * Returns the class name of the supplied object, truncated to one package prior to the actual
* package prior to the actual class name. For example, * class name. For example, <code>com.samskivert.util.StringUtil</code> would be reported as
* <code>com.samskivert.util.StringUtil</code> would be reported as * <code>util.StringUtil</code>. If a null object is passed in, <code>null</code> is returned.
* <code>util.StringUtil</code>. If a null object is passed in,
* <code>null</code> is returned.
*/ */
public static String shortClassName (Object object) public static String shortClassName (Object object)
{ {
@@ -1224,9 +1148,8 @@ public class StringUtil
} }
/** /**
* Returns the supplied class's name, truncated to one package prior * Returns the supplied class's name, truncated to one package prior to the actual class
* to the actual class name. For example, * name. For example, <code>com.samskivert.util.StringUtil</code> would be reported as
* <code>com.samskivert.util.StringUtil</code> would be reported as
* <code>util.StringUtil</code>. * <code>util.StringUtil</code>.
*/ */
public static String shortClassName (Class clazz) public static String shortClassName (Class clazz)
@@ -1235,9 +1158,8 @@ public class StringUtil
} }
/** /**
* Returns the supplied class name truncated to one package prior to * Returns the supplied class name truncated to one package prior to the actual class name. For
* the actual class name. For example, * example, <code>com.samskivert.util.StringUtil</code> would be reported as
* <code>com.samskivert.util.StringUtil</code> would be reported as
* <code>util.StringUtil</code>. * <code>util.StringUtil</code>.
*/ */
public static String shortClassName (String name) public static String shortClassName (String name)
@@ -1254,8 +1176,8 @@ public class StringUtil
} }
/** /**
* Converts a name of the form <code>weAreSoCool</code> to a name of * Converts a name of the form <code>weAreSoCool</code> to a name of the form
* the form <code>WE_ARE_SO_COOL</code>. * <code>WE_ARE_SO_COOL</code>.
*/ */
public static String unStudlyName (String name) public static String unStudlyName (String name)
{ {
@@ -1264,8 +1186,8 @@ public class StringUtil
int nlen = name.length(); int nlen = name.length();
for (int i = 0; i < nlen; i++) { for (int i = 0; i < nlen; i++) {
char c = name.charAt(i); char c = name.charAt(i);
// if we see an upper case character and we've seen a lower // if we see an upper case character and we've seen a lower case character since the
// case character since the last time we did so, slip in an _ // last time we did so, slip in an _
if (Character.isUpperCase(c)) { if (Character.isUpperCase(c)) {
nname.append("_"); nname.append("_");
seenLower = false; seenLower = false;
@@ -1287,22 +1209,19 @@ public class StringUtil
} }
/** /**
* Encodes (case-insensitively) a short English language string into a * Encodes (case-insensitively) a short English language string into a semi-unique
* semi-unique integer. This is done by selecting the first eight * integer. This is done by selecting the first eight characters in the string that fall into
* characters in the string that fall into the set of the 16 most * the set of the 16 most frequently used characters in the English language and converting
* frequently used characters in the English language and converting * them to a 4 bit value and storing the result into the returned integer.
* them to a 4 bit value and storing the result into the returned
* integer.
* *
* <p> This method is useful for mapping a set of string constants to * <p> This method is useful for mapping a set of string constants to a set of unique integers
* a set of unique integers (e.g. mapping an enumerated type to an * (e.g. mapping an enumerated type to an integer and back without having to require that the
* integer and back without having to require that the declaration * declaration order of the enumerated type remain constant for all time). The caller must, of
* order of the enumerated type remain constant for all time). The * course, ensure that no collisions occur.
* caller must, of course, ensure that no collisions occur.
* *
* @param value the string to be encoded. * @param value the string to be encoded.
* @param encoded if non-null, a string buffer into which the * @param encoded if non-null, a string buffer into which the characters used for the encoding
* characters used for the encoding will be recorded. * will be recorded.
*/ */
public static int stringCode (String value, StringBuilder encoded) public static int stringCode (String value, StringBuilder encoded)
{ {
@@ -1336,10 +1255,9 @@ public class StringUtil
/** Used by {@link #hexlate} and {@link #unhexlate}. */ /** Used by {@link #hexlate} and {@link #unhexlate}. */
protected static final String XLATE = "0123456789abcdef"; protected static final String XLATE = "0123456789abcdef";
/** Maps the 16 most frequent letters in the English language to a /** Maps the 16 most frequent letters in the English language to a number between 0 and
* number between 0 and 15. Used by {@link #stringCode}. */ * 15. Used by {@link #stringCode}. */
protected static final HashIntMap<Integer> _letterToBits = protected static final HashIntMap<Integer> _letterToBits = new HashIntMap<Integer>();
new HashIntMap<Integer>();
static { static {
String mostCommon = "etaoinsrhldcumfp"; String mostCommon = "etaoinsrhldcumfp";
for (int ii = mostCommon.length() - 1; ii >= 0; ii--) { for (int ii = mostCommon.length() - 1; ii >= 0; ii--) {