commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From scolebou...@apache.org
Subject cvs commit: jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang Strings.java
Date Thu, 04 Jul 2002 20:28:15 GMT
scolebourne    2002/07/04 13:28:15

  Modified:    lang/src/java/org/apache/commons/lang Strings.java
  Log:
  Complete grouping of methods in source file
  Add isAlphanumericSpace/isNumericSpace
  Add extra null handling
  Add javadoc
  
  Revision  Changes    Path
  1.12      +645 -510  jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/Strings.java
  
  Index: Strings.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/Strings.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- Strings.java	2 Jul 2002 22:00:29 -0000	1.11
  +++ Strings.java	4 Jul 2002 20:28:15 -0000	1.12
  @@ -70,13 +70,11 @@
   // CharSet
   import java.util.List;
   import java.util.LinkedList;
  -
  -
   /**
    * <p>Common <code>String</code> manipulation routines.</p>
    *
  - * <p>Originally from <a
  - * href="http://jakarta.apache.org/turbine/">Turbine</a> and the
  + * <p>Originally from 
  + * <a href="http://jakarta.apache.org/turbine/">Turbine</a> and the
    * GenerationJavaCore library.</p>
    *
    * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
  @@ -88,8 +86,8 @@
    * @author <a href="mailto:scolebourne@joda.org>Stephen Colebourne</a>
    * @version $Id$
    */
  -public class Strings
  -{
  +public class Strings {
  +
       /**
        * The size of the buffer to use when working with I/O (4 kB).
        */
  @@ -106,8 +104,7 @@
        * @param str  the string to check
        * @return the trimmed text (never <code>null</code>)
        */
  -    public static String clean(String str)
  -    {
  +    public static String clean(String str) {
           return (str == null ? "" : str.trim());
       }
   
  @@ -119,8 +116,7 @@
        * @param str  the string to check
        * @return the trimmed text (or <code>null</code>)
        */
  -    public static String trim(String str)
  -    {
  +    public static String trim(String str) {
           return (str == null ? null : str.trim());
       }
   
  @@ -130,8 +126,7 @@
        * @param str  the string to check
        * @return true if the String is non-null, and not length zero
        */
  -    public static boolean isNotEmpty(String str)
  -    {
  +    public static boolean isNotEmpty(String str) {
           return (str != null && str.length() > 0);
       }
   
  @@ -141,14 +136,13 @@
        * @param str  the string to check
        * @return true if the String is null, or length zero once trimmed
        */
  -    public static boolean isEmpty(String str)
  -    {
  +    public static boolean isEmpty(String str) {
           return (str == null || str.trim().length() == 0);
       }
   
       // Equals and IndexOf
       //--------------------------------------------------------------------------
  -    
  +
       /**
        * Compares two Strings, returning true if they are equal.
        * Nulls are handled without exceptions. Two <code>null</code>
  @@ -158,8 +152,7 @@
        * @param str2  the second string
        * @return true if the Strings are equal, case sensitive, or both null
        */
  -    public static boolean equals(String str1, String str2)
  -    {
  +    public static boolean equals(String str1, String str2) {
           return (str1 == null ? str2 == null : str1.equals(str2));
       }
   
  @@ -172,8 +165,7 @@
        * @param str2  the second string
        * @return true if the Strings are equal, case insensitive, or both null
        */
  -    public static boolean equalsIgnoreCase(String str1, String str2)
  -    {
  +    public static boolean equalsIgnoreCase(String str1, String str2) {
           return (str1 == null ? str2 == null : str1.equalsIgnoreCase(str2));
       }
   
  @@ -185,7 +177,7 @@
        * @param searchStrs  the strings to search for
        * @return the earliest index of any of the strings
        */
  -    static public int indexOfAny(String str, String[] searchStrs) {
  +    public static int indexOfAny(String str, String[] searchStrs) {
           if ((str == null) || (searchStrs == null)) {
               return -1;
           }
  @@ -217,7 +209,7 @@
        * @param searchStrs  the strings to search for
        * @return the last index of any of the strings
        */
  -    static public int lastIndexOfAny(String str, String[] searchStrs) {
  +    public static int lastIndexOfAny(String str, String[] searchStrs) {
           if ((str == null) || (searchStrs == null)) {
               return -1;
           }
  @@ -322,8 +314,7 @@
        * @return the leftmost characters
        * @throws IllegalArgumentException if len is less than zero
        */
  -    public static String left(String str, int len)
  -    {
  +    public static String left(String str, int len) {
           if (len < 0) {
               throw new IllegalArgumentException("Requested String length " + len + " is less than zero");
           }
  @@ -344,8 +335,7 @@
        * @return the leftmost characters
        * @throws IllegalArgumentException if len is less than zero
        */
  -    public static String right(String str, int len)
  -    {
  +    public static String right(String str, int len) {
           if (len < 0) {
               throw new IllegalArgumentException("Requested String length " + len + " is less than zero");
           }
  @@ -368,8 +358,7 @@
        * @throws IndexOutOfBoundsException if pos is out of bounds
        * @throws IllegalArgumentException if len is less than zero
        */
  -    public static String mid(String str, int pos, int len)
  -    {
  +    public static String mid(String str, int pos, int len) {
           if ((pos < 0) ||
               (str != null && pos > str.length())) {
               throw new StringIndexOutOfBoundsException("String index " + pos + " is out of bounds");
  @@ -617,6 +606,154 @@
           return (wrappedLine.toString());
       }
   
  +    // Word wrapping
  +    //--------------------------------------------------------------------------
  +    
  +    /**
  +     * Create a word-wrapped version of a String. Wrap at 80 characters and 
  +     * use newlines as the delimiter. If a word is over 80 characters long 
  +     * use a - sign to split it.
  +     */
  +    public static String wordWrap(String str) {
  +        return wordWrap(str, 80, "\n", "-");
  +    }
  +    /**
  +     * Create a word-wrapped version of a String. Wrap at a specified width and 
  +     * use newlines as the delimiter. If a word is over the width in lenght 
  +     * use a - sign to split it.
  +     */
  +    public static String wordWrap(String str, int width) {
  +        return wordWrap(str, width, "\n", "-");
  +    }
  +    /**
  +     * Word-wrap a string.
  +     *
  +     * @param str   String to word-wrap
  +     * @param width int to wrap at
  +     * @param delim String to use to separate lines
  +     * @param split String to use to split a word greater than width long
  +     *
  +     * @return String that has been word wrapped
  +     */
  +    public static String wordWrap(String str, int width, String delim, String split) {
  +        int sz = str.length();
  +
  +        /// shift width up one. mainly as it makes the logic easier
  +        width++;
  +
  +        // our best guess as to an initial size
  +        StringBuffer buffer = new StringBuffer(sz/width*delim.length()+sz);
  +
  +        // every line will include a delim on the end
  +        width = width - delim.length();
  +
  +        int idx = -1;
  +        String substr = null;
  +
  +        // beware: i is rolled-back inside the loop
  +        for(int i=0; i<sz; i+=width) {
  +
  +            // on the last line
  +            if(i > sz - width) {
  +                buffer.append(str.substring(i));
  +//                System.err.print("LAST-LINE: "+str.substring(i));
  +                break;
  +            }
  +
  +//            System.err.println("loop[i] is: "+i);
  +            // the current line
  +            substr = str.substring(i, i+width);
  +
  +            // is the delim already on the line
  +            idx = substr.indexOf(delim);
  +            if(idx != -1) {
  +                buffer.append(substr.substring(0,idx));
  +//                System.err.println("Substr: '"+substr.substring(0,idx)+"'");
  +                buffer.append(delim);
  +                i -= width-idx-delim.length();
  +                
  +//                System.err.println("loop[i] is now: "+i);
  +//                System.err.println("found-whitespace: '"+substr.charAt(idx+1)+"'.");
  +                // Erase a space after a delim. Is this too obscure?
  +                if(substr.charAt(idx+1) != '\n') {
  +                    if(Character.isWhitespace(substr.charAt(idx+1))) {
  +                        i++;
  +                    }
  +                }
  +//                System.err.println("i -= "+width+"-"+idx);
  +                continue;
  +            }
  +
  +            idx = -1;
  +
  +            // figure out where the last space is
  +            char[] chrs = substr.toCharArray();
  +            for(int j=width; j>0; j--) {
  +                if(Character.isWhitespace(chrs[j-1])) {
  +                    idx = j;
  +//                    System.err.println("Found whitespace: "+idx);
  +                    break;
  +                }
  +            }
  +
  +            // idx is the last whitespace on the line.
  +//            System.err.println("idx is "+idx);
  +            if(idx == -1) {
  +                for(int j=width; j>0; j--) {
  +                    if(chrs[j-1] == '-') {
  +                        idx = j;
  +//                        System.err.println("Found Dash: "+idx);
  +                        break;
  +                    }
  +                }
  +                if(idx == -1) {
  +                    buffer.append(substr);
  +                    buffer.append(delim);
  +//                    System.err.print(substr);
  +//                    System.err.print(delim);
  +                } else {
  +                    if(idx != width) {
  +                        idx++;
  +                    }
  +                    buffer.append(substr.substring(0,idx));
  +                    buffer.append(delim);
  +//                    System.err.print(substr.substring(0,idx));
  +//                    System.err.print(delim);
  +                    i -= width-idx;
  +                }
  +            } else {
  +                /*
  +                if(force) {
  +                    if(idx == width-1) {
  +                        buffer.append(substr);
  +                        buffer.append(delim);
  +                    } else {
  +                        // stick a split in.
  +                        int splitsz = split.length();
  +                        buffer.append(substr.substring(0,width-splitsz));
  +                        buffer.append(split);
  +                        buffer.append(delim);
  +                        i -= splitsz;
  +                    }
  +                } else {
  +                */
  +                    // insert spaces
  +                    buffer.append(substr.substring(0,idx));
  +                    buffer.append(repeat(" ",width-idx));
  +//                    System.err.print(substr.substring(0,idx));
  +//                    System.err.print(repeat(" ",width-idx));
  +                    buffer.append(delim);
  +//                    System.err.print(delim);
  +//                    System.err.println("i -= "+width+"-"+idx);
  +                    i -= width-idx;
  +//                }
  +            }
  +        }
  +//        System.err.println("\n*************");
  +        return buffer.toString();
  +    }
  +
  +
       // Replacing
       //--------------------------------------------------------------------------
       
  @@ -687,7 +824,7 @@
        *
        * @return String with overlayed text
        */
  -    static public String overlayString(String text, String overlay, int start, int end) {
  +    public static String overlayString(String text, String overlay, int start, int end) {
           return new StringBuffer(start + overlay.length() + text.length() - end + 1)
   			.append(text.substring(0, start))
   			.append(overlay)
  @@ -695,29 +832,9 @@
   			.toString();
       }
   
  -    /**
  -     * Repeat a string n times to form a new string.
  -     *
  -     * @param str String to repeat
  -     * @param n   int    number of times to repeat
  -     *
  -     * @return String with repeated string
  -     */
  -    static public String repeat(String str, int n) {
  -        StringBuffer buffer = new StringBuffer(n*str.length());
  -        for(int i=0; i<n; i++) {
  -            buffer.append(str);
  -        }
  -        return buffer.toString();
  -    }
  -
  -// these are not really of use in the Java world. Only if you're a C afficionado
  -//    static public String sprintf(String format, Object[] list);
  -//    static public Object[] sscanf(String str, String format);
  -//    static public String pack(String[] strs, String format);
  -//    static public String[] unpack(String str, String format);
  -
  -
  +    // Centering
  +    //--------------------------------------------------------------------------
  +    
       /**
        * Center a string in a larger string of size n.
        * Uses spaces as the value to buffer the string with..
  @@ -727,7 +844,7 @@
        *
        * @return String containing centered String
        */
  -    static public String center(String str, int n) {
  +    public static String center(String str, int n) {
           return center(str, n, " ");
       }
   
  @@ -741,7 +858,7 @@
        *
        * @return String containing centered String
        */
  -    static public String center(String str, int n, String delim) {
  +    public static String center(String str, int n, String delim) {
           int sz = str.length();
           int p = n-sz;
           if(p < 1) {
  @@ -752,6 +869,9 @@
           return str;
       }
   
  +    // Chomping
  +    //--------------------------------------------------------------------------
  +    
       /** 
        * Remove the last newline, and everything after it from a String.
        *
  @@ -759,7 +879,7 @@
        *
        * @return String without chomped newline
        */
  -    static public String chomp(String str) {
  +    public static String chomp(String str) {
           return chomp(str, "\n");
       }
       
  @@ -772,7 +892,7 @@
        *
        * @return String without chomped ending
        */
  -    static public String chomp(String str, String sep) {
  +    public static String chomp(String str, String sep) {
           int idx = str.lastIndexOf(sep);
           if(idx != -1) {
               return str.substring(0,idx);
  @@ -785,10 +905,10 @@
        * Remove a newline if and only if it is at the end 
        * of the supplied string.
        */
  -    static public String chompLast(String str) {
  +    public static String chompLast(String str) {
           return chompLast(str, "\n");
       }
  -    static public String chompLast(String str, String sep) {
  +    public static String chompLast(String str, String sep) {
           if(str.length() == 0) {
               return str;
           }
  @@ -809,7 +929,7 @@
        *
        * @return String chomped
        */
  -    static public String getChomp(String str, String sep) {
  +    public static String getChomp(String str, String sep) {
           int idx = str.lastIndexOf(sep);
           if(idx == str.length()-sep.length()) {
               return sep;
  @@ -830,7 +950,7 @@
        *
        * @return String without chomped beginning
        */
  -    static public String prechomp(String str, String sep) {
  +    public static String prechomp(String str, String sep) {
           int idx = str.indexOf(sep);
           if(idx != -1) {
               return str.substring(idx+sep.length());
  @@ -848,7 +968,7 @@
        *
        * @return String prechomped
        */
  -    static public String getPrechomp(String str, String sep) {
  +    public static String getPrechomp(String str, String sep) {
           int idx = str.indexOf(sep);
           if(idx != -1) {
               return str.substring(0,idx+sep.length());
  @@ -857,6 +977,9 @@
           }
       }
   
  +    // Chopping
  +    //--------------------------------------------------------------------------
  +    
       /**
        * Remove the last character from a String. If the String 
        * ends in \r\n, then remove both of them.
  @@ -865,7 +988,7 @@
        *
        * @return String without last character
        */
  -    static public String chop(String str) {
  +    public static String chop(String str) {
           if("".equals(str)) {
               return "";
           }
  @@ -891,7 +1014,7 @@
        *
        * @param String without newline on end
        */
  -    static public String chopNewline(String str) {
  +    public static String chopNewline(String str) {
           int lastIdx = str.length()-1;
           char last = str.charAt(lastIdx);
           if(last == '\n') {
  @@ -904,6 +1027,9 @@
           return str.substring(0,lastIdx);
       }
   
  +    // CharSet methods
  +    //--------------------------------------------------------------------------
  +    
       /**
        * Creates a CharSet object which allows a certain amount of 
        * set logic to be performed upon the following syntax:
  @@ -913,11 +1039,11 @@
        * a set in itself due to the size of that set in unicode.
        * "ej-m" implies e,j->m. e,j,k,l,m.
        */
  -    static public CharSet evaluateSet(String[] set) {
  +    public static CharSet evaluateSet(String[] set) {
           return new CharSet(set); 
       }
   
  -    static public int count(String str, String set) {
  +    public static int count(String str, String set) {
           String[] strs = new String[1];
           strs[0] = set;
           return count(str, strs);
  @@ -930,7 +1056,7 @@
        * @param str String target to count characters in
        * @param str String[] set of characters to count
        */
  -    static public int count(String str, String[] set) {
  +    public static int count(String str, String[] set) {
           CharSet chars = evaluateSet(set);
           int count = 0;
           char[] chrs = str.toCharArray();
  @@ -943,7 +1069,7 @@
           return count;
       }
   
  -    static public String delete(String str, String set) {
  +    public static String delete(String str, String set) {
           String[] strs = new String[1];
           strs[0] = set;
           return delete(str, strs);
  @@ -956,7 +1082,7 @@
        * @param str String target to delete characters from
        * @param str String[] set of characters to delete
        */
  -    static public String delete(String str, String[] set) {
  +    public static String delete(String str, String[] set) {
           CharSet chars = evaluateSet(set);
           StringBuffer buffer = new StringBuffer(str.length());
           char[] chrs = str.toCharArray();
  @@ -969,7 +1095,7 @@
           return buffer.toString();
       }
   
  -    static public String squeeze(String str, String set) {
  +    public static String squeeze(String str, String set) {
           String[] strs = new String[1];
           strs[0] = set;
           return squeeze(str, strs);
  @@ -980,7 +1106,7 @@
        *    squeeze("hello", {"el"})  => "helo"
        * See evaluateSet for set-syntax.
        */
  -    static public String squeeze(String str, String[] set) {
  +    public static String squeeze(String str, String[] set) {
           CharSet chars = evaluateSet(set);
           StringBuffer buffer = new StringBuffer(str.length());
           char[] chrs = str.toCharArray();
  @@ -1000,6 +1126,9 @@
           return buffer.toString();
       }
   
  +    // Conversion
  +    //--------------------------------------------------------------------------
  +    
       /**
        * Translate characters in a String.
        * An example is:  translate("hello", "ho", "jy") => jelly
  @@ -1011,7 +1140,7 @@
        * @param repl String to find that will be replaced
        * @param with String to put into the target String
        */
  -    static public String translate(String target, String repl, String with) {
  +    public static String translate(String target, String repl, String with) {
           StringBuffer buffer = new StringBuffer(target.length());
           char[] chrs = target.toCharArray();
           char[] withChrs = with.toCharArray();
  @@ -1042,7 +1171,7 @@
        */
       // improved with code from  cybertiger@cyberiantiger.org
       // unicode from him, and defaul for < 32's.
  -    static public String escape(String str) {
  +    public static String escape(String str) {
           int sz = str.length();
           StringBuffer buffer = new StringBuffer(2*sz);
           for(int i=0; i<sz; i++) {
  @@ -1112,9 +1241,78 @@
       }
   
       /**
  +     * Quote a string so that it may be used in a regular expression 
  +     * without any parts of the string being considered as a 
  +     * part of the regular expression's control characters.
  +     */
  +    public static String quoteRegularExpression(String str) {
  +        // replace ? + * / . ^ $ as long as they're not in character 
  +        // class. so must be done by hand
  +        char[] chrs = str.toCharArray();
  +        int sz = chrs.length;
  +        StringBuffer buffer = new StringBuffer(2*sz);
  +        for(int i=0; i<sz; i++) {
  +            switch(chrs[i]) {
  +              case '[' :
  +              case ']' :
  +              case '?' :
  +              case '+' :
  +              case '*' :
  +              case '/' :
  +              case '.' :
  +              case '^' :
  +              case '$' :
  +                buffer.append("\\");
  +              default : 
  +                buffer.append(chrs[i]);
  +            }
  +        }
  +        return buffer.toString();
  +    }
  +
  +    /**
  +     * Interpolate variables into a String using the ${} type syntax.
  +     * 
  +     * @param text  the text to interpolate into
  +     * @param map  the map of parameters to insert
  +     * @return the updated string
  +     */
  +    public static String interpolate(String text, Map map) {
  +        Iterator keys = map.keySet().iterator();
  +        while (keys.hasNext()) {
  +            String key = keys.next().toString();
  +            String value = map.get(key).toString();
  +            text = replace(text, "${"+key+"}", value);
  +            if (key.indexOf(" ") == -1) {
  +                text = replace(text, "$"+key, value);
  +            }
  +        }
  +        return text;
  +    }
  +
  +    // Padding
  +    //--------------------------------------------------------------------------
  +    
  +    /**
  +     * Repeat a string n times to form a new string.
  +     *
  +     * @param str String to repeat
  +     * @param n   int    number of times to repeat
  +     *
  +     * @return String with repeated string
  +     */
  +    public static String repeat(String str, int n) {
  +        StringBuffer buffer = new StringBuffer(n*str.length());
  +        for(int i=0; i<n; i++) {
  +            buffer.append(str);
  +        }
  +        return buffer.toString();
  +    }
  +
  +    /**
        * Right pad a String with spaces. Pad to a size of n.
        */
  -    static public String rightPad(String str, int n) {
  +    public static String rightPad(String str, int n) {
           return rightPad(str, n, " ");
       }
       /**
  @@ -1124,7 +1322,7 @@
        * @param n     int    size to pad to
        * @param delim String to pad with
        */
  -    static public String rightPad(String str, int n, String delim) {
  +    public static String rightPad(String str, int n, String delim) {
           n = (n - str.length())/delim.length();
           if(n > 0) {
               str += repeat(delim,n);
  @@ -1135,7 +1333,7 @@
       /**
        * Left pad a String with spaces. Pad to a size of n.
        */
  -    static public String leftPad(String str, int n) {
  +    public static String leftPad(String str, int n) {
           return leftPad(str, n, " ");
       }
       /**
  @@ -1145,7 +1343,7 @@
        * @param n     int    size to pad to
        * @param delim String to pad with
        */
  -    static public String leftPad(String str, int n, String delim) {
  +    public static String leftPad(String str, int n, String delim) {
           n = (n - str.length())/delim.length();
           if(n > 0) {
               str = repeat(delim,n) + str;
  @@ -1153,26 +1351,13 @@
           return str;
       }
   
  -    // faster algorithm available. unsure if usable in Java
  -    /**
  -     * Reverse a String.
  -     */
  -    static public String reverse(String str) {
  -        /*
  -        int sz = str.length();
  -        StringBuffer buffer = new StringBuffer(sz);
  -        for(int i=sz; i>0; i--) {
  -            buffer.append(str.charAt(i-1));
  -        }
  -        return buffer.toString();
  -        */
  -        return new StringBuffer(str).reverse().toString();
  -    }
  -
  +    // Stripping
  +    //--------------------------------------------------------------------------
  +    
       /**
        * Remove whitespace from the front and back of a String.
        */
  -    static public String strip(String str) {
  +    public static String strip(String str) {
           return strip(str, null);
       }
       /**
  @@ -1180,7 +1365,7 @@
        * String. If Whitespace is wanted to be removed, used the 
        * strip(String) method.
        */
  -    static public String strip(String str, String delim) {
  +    public static String strip(String str, String delim) {
           str = stripStart(str, delim);
           return stripEnd(str, delim);
       }
  @@ -1189,7 +1374,7 @@
        * Strip whitespace from the front and back of every string
        * in the array.
        */
  -    static public String[] stripAll(String[] strs) {
  +    public static String[] stripAll(String[] strs) {
           return stripAll(strs, null);
       }
    
  @@ -1197,7 +1382,7 @@
        * Strip the specified delimiter from the front and back of
        * every String in the array.
        */
  -    static public String[] stripAll(String[] strs, String delimiter) {
  +    public static String[] stripAll(String[] strs, String delimiter) {
           if( (strs == null) || (strs.length == 0) ) {
               return strs;
           }
  @@ -1210,88 +1395,9 @@
       }   
   
       /**
  -     * Uncapitalise a string. That is, convert the first character into 
  -     * lower-case.
  -     *
  -     * @param str String to uncapitalise
  -     *
  -     * @return String uncapitalised
  -     */
  -    static public String uncapitalise(String str) {
  -        return new StringBuffer(str.length())
  -            .append(Character.toLowerCase(str.charAt(0)))
  -            .append(str.substring(1))
  -            .toString();
  -    }
  -
  -    /**
  -     * Capitalise a string. That is, convert the first character into 
  -     * title-case.
  -     *
  -     * @param str String to capitalise
  -     *
  -     * @return String capitalised
  -     */
  -    static public String capitalise(String str) {
  -        return new StringBuffer(str.length())
  -            .append(Character.toTitleCase(str.charAt(0)))
  -            .append(str.substring(1))
  -            .toString();
  -    }
  -
  -    /**
  -     * Makes the first letter capital and leaves the rest as is.
  -     *
  -     * @param text The text to modify.
  -     * @return The modified text.
  -     */
  -    public static String firstLetterCaps(String text)
  -    {
  -        return (text == null ? null :
  -                text.substring(0, 1).toUpperCase() + text.substring(1));
  -    }
  -
  -    /**
  -     * Swaps the case of String. Properly looks after 
  -     * making sure the start of words are Titlecase and not 
  -     * Uppercase.
  -     */
  -    static public String swapCase(String str) {
  -        int sz = str.length();
  -        StringBuffer buffer = new StringBuffer(sz);
  -
  -        boolean whitespace = false;
  -        char ch = 0;
  -        char tmp = 0;
  -
  -        for(int i=0; i<sz; i++) {
  -            ch = str.charAt(i);
  -            if(Character.isUpperCase(ch)) {
  -                tmp = Character.toLowerCase(ch);
  -            } else
  -            if(Character.isTitleCase(ch)) {
  -                tmp = Character.toLowerCase(ch);
  -            } else
  -            if(Character.isLowerCase(ch)) {
  -                if(whitespace) {
  -                    tmp = Character.toTitleCase(ch);
  -                } else {
  -                    tmp = Character.toUpperCase(ch);
  -                }
  -            } else {
  -                tmp = ch;
  -            }
  -            buffer.append(tmp);
  -            whitespace = Character.isWhitespace(ch);
  -        }
  -        return buffer.toString();
  -    }
  -
  -
  -    /**
        * Strip any of a supplied substring from the end of a String..
        */
  -    static public String stripEnd(String str, String ch) {
  +    public static String stripEnd(String str, String ch) {
           if(str == null) {
               return null;
           }
  @@ -1312,7 +1418,7 @@
       /**
        * Strip any of a supplied substring from the start of a String..
        */
  -    static public String stripStart(String str, String ch) {
  +    public static String stripStart(String str, String ch) {
           if(str == null) {
               return null;
           }
  @@ -1334,320 +1440,230 @@
           return str.substring(start);     
       }
   
  +    // Case conversion
  +    //--------------------------------------------------------------------------
  +    
       /**
  -     * Find the Levenshtein distance between two strings.
  -     * This is the number of changes needed to change one string into 
  -     * another. Where each change is a single character modification.
  -     *
  -     * This implemmentation of the levenshtein distance algorithm 
  -     * is from http://www.merriampark.com/ld.htm
  +     * Convert a String to upper case, null string returns null.
  +     * 
  +     * @param str  the string to uppercase
  +     * @return the upper cased string
        */
  -    static public int getLevenshteinDistance(String s, String t) {
  -        int d[][]; // matrix
  -        int n; // length of s
  -        int m; // length of t
  -        int i; // iterates through s
  -        int j; // iterates through t
  -        char s_i; // ith character of s
  -        char t_j; // jth character of t
  -        int cost; // cost
  -
  -        // Step 1
  -        n = s.length ();
  -        m = t.length ();
  -        if (n == 0) {
  -            return m;
  -        }
  -        if (m == 0) {
  -            return n;
  -        }
  -        d = new int[n+1][m+1];
  -
  -        // Step 2
  -        for (i = 0; i <= n; i++) {
  -            d[i][0] = i;
  -        }
  -
  -        for (j = 0; j <= m; j++) {
  -            d[0][j] = j;
  -        }
  -
  -        // Step 3
  -        for (i = 1; i <= n; i++) {
  -            s_i = s.charAt (i - 1);
  -
  -            // Step 4
  -            for (j = 1; j <= m; j++) {
  -                t_j = t.charAt (j - 1);
  -
  -                // Step 5
  -                if (s_i == t_j) {
  -                    cost = 0;
  -                } else {
  -                    cost = 1;
  -                }
  -
  -                // Step 6
  -                d[i][j] = Numbers.minimum(d[i-1][j]+1, d[i][j-1]+1, d[i-1][j-1] + cost);
  -            }
  +    public static String upperCase(String str) {
  +        if (str == null) {
  +            return null;
           }
  -
  -        // Step 7
  -        return d[n][m];
  +        return str.toUpperCase();
       }
   
       /**
  -     * Quote a string so that it may be used in a regular expression 
  -     * without any parts of the string being considered as a 
  -     * part of the regular expression's control characters.
  +     * Convert a String to lower case, null string returns null.
  +     * 
  +     * @param str  the string to lowercase
  +     * @return the lower cased string
        */
  -    static public String quoteRegularExpression(String str) {
  -        // replace ? + * / . ^ $ as long as they're not in character 
  -        // class. so must be done by hand
  -        char[] chrs = str.toCharArray();
  -        int sz = chrs.length;
  -        StringBuffer buffer = new StringBuffer(2*sz);
  -        for(int i=0; i<sz; i++) {
  -            switch(chrs[i]) {
  -              case '[' :
  -              case ']' :
  -              case '?' :
  -              case '+' :
  -              case '*' :
  -              case '/' :
  -              case '.' :
  -              case '^' :
  -              case '$' :
  -                buffer.append("\\");
  -              default : 
  -                buffer.append(chrs[i]);
  -            }
  +    public static String lowerCase(String str) {
  +        if (str == null) {
  +            return null;
           }
  -        return buffer.toString();
  +        return str.toLowerCase();
       }
   
       /**
  -     * Capitalise all the words in a string. Uses Character.isWhitespace 
  -     * as a separator between words.
  +     * Uncapitalise a string. That is, convert the first character into 
  +     * lower-case. Null is returned as null.
  +     *
  +     * @param str  the string to uncapitalise
  +     * @return uncapitalised string
        */
  -    static public String capitaliseAllWords(String str) {
  -        int sz = str.length();
  -        StringBuffer buffer = new StringBuffer(sz);
  -        boolean space = true;
  -        for(int i=0; i<sz; i++) {
  -            char ch = str.charAt(i);
  -            if(Character.isWhitespace(ch)) {
  -                buffer.append(ch);
  -                space = true;
  -            } else
  -            if(space) {
  -                buffer.append(Character.toTitleCase(ch));
  -                space = false;
  -            } else {
  -                buffer.append(ch);
  -            }
  +    public static String uncapitalise(String str) {
  +        if (str == null) {
  +            return null;
           }
  -        return buffer.toString();
  +        return new StringBuffer(str.length())
  +            .append(Character.toLowerCase(str.charAt(0)))
  +            .append(str.substring(1))
  +            .toString();
       }
   
       /**
  -     * Create a word-wrapped version of a String. Wrap at 80 characters and 
  -     * use newlines as the delimiter. If a word is over 80 characters long 
  -     * use a - sign to split it.
  +     * Capitalise a string. That is, convert the first character into 
  +     * title-case. Null is returned as null.
  +     *
  +     * @param str  the string to capitalise
  +     * @return capitalised string
        */
  -    static public String wordWrap(String str) {
  -        return wordWrap(str, 80, "\n", "-");
  +    public static String capitalise(String str) {
  +        if (str == null) {
  +            return null;
  +        }
  +        return new StringBuffer(str.length())
  +            .append(Character.toTitleCase(str.charAt(0)))
  +            .append(str.substring(1))
  +            .toString();
       }
  +
       /**
  -     * Create a word-wrapped version of a String. Wrap at a specified width and 
  -     * use newlines as the delimiter. If a word is over the width in lenght 
  -     * use a - sign to split it.
  +     * Makes the first letter capital and leaves the rest as is.
  +     * Null is returned as null.
  +     *
  +     * @param str  the string to change the case of.
  +     * @return the modified string
        */
  -    static public String wordWrap(String str, int width) {
  -        return wordWrap(str, width, "\n", "-");
  +    public static String firstLetterCaps(String str) {
  +        if (str == null) {
  +            return null;
  +        }
  +        return str.substring(0, 1).toUpperCase() + str.substring(1);
       }
  +
       /**
  -     * Word-wrap a string.
  -     *
  -     * @param str   String to word-wrap
  -     * @param width int to wrap at
  -     * @param delim String to use to separate lines
  -     * @param split String to use to split a word greater than width long
  -     *
  -     * @return String that has been word wrapped
  +     * Swaps the case of String. Properly looks after 
  +     * making sure the start of words are Titlecase and not 
  +     * Uppercase. Null is returned as null.
  +     * 
  +     * @param str  the string to swap the case of
  +     * @return the modified string
        */
  -    static public String wordWrap(String str, int width, String delim, String split) {
  +    public static String swapCase(String str) {
  +        if (str == null) {
  +            return null;
  +        }
           int sz = str.length();
  +        StringBuffer buffer = new StringBuffer(sz);
   
  -        /// shift width up one. mainly as it makes the logic easier
  -        width++;
  -
  -        // our best guess as to an initial size
  -        StringBuffer buffer = new StringBuffer(sz/width*delim.length()+sz);
  -
  -        // every line will include a delim on the end
  -        width = width - delim.length();
  -
  -        int idx = -1;
  -        String substr = null;
  -
  -        // beware: i is rolled-back inside the loop
  -        for(int i=0; i<sz; i+=width) {
  -
  -            // on the last line
  -            if(i > sz - width) {
  -                buffer.append(str.substring(i));
  -//                System.err.print("LAST-LINE: "+str.substring(i));
  -                break;
  -            }
  -
  -//            System.err.println("loop[i] is: "+i);
  -            // the current line
  -            substr = str.substring(i, i+width);
  -
  -            // is the delim already on the line
  -            idx = substr.indexOf(delim);
  -            if(idx != -1) {
  -                buffer.append(substr.substring(0,idx));
  -//                System.err.println("Substr: '"+substr.substring(0,idx)+"'");
  -                buffer.append(delim);
  -                i -= width-idx-delim.length();
  -                
  -//                System.err.println("loop[i] is now: "+i);
  -//                System.err.println("found-whitespace: '"+substr.charAt(idx+1)+"'.");
  -                // Erase a space after a delim. Is this too obscure?
  -                if(substr.charAt(idx+1) != '\n') {
  -                    if(Character.isWhitespace(substr.charAt(idx+1))) {
  -                        i++;
  -                    }
  -                }
  -//                System.err.println("i -= "+width+"-"+idx);
  -                continue;
  -            }
  -
  -            idx = -1;
  -
  -            // figure out where the last space is
  -            char[] chrs = substr.toCharArray();
  -            for(int j=width; j>0; j--) {
  -                if(Character.isWhitespace(chrs[j-1])) {
  -                    idx = j;
  -//                    System.err.println("Found whitespace: "+idx);
  -                    break;
  -                }
  -            }
  +        boolean whitespace = false;
  +        char ch = 0;
  +        char tmp = 0;
   
  -            // idx is the last whitespace on the line.
  -//            System.err.println("idx is "+idx);
  -            if(idx == -1) {
  -                for(int j=width; j>0; j--) {
  -                    if(chrs[j-1] == '-') {
  -                        idx = j;
  -//                        System.err.println("Found Dash: "+idx);
  -                        break;
  -                    }
  -                }
  -                if(idx == -1) {
  -                    buffer.append(substr);
  -                    buffer.append(delim);
  -//                    System.err.print(substr);
  -//                    System.err.print(delim);
  +        for(int i=0; i<sz; i++) {
  +            ch = str.charAt(i);
  +            if(Character.isUpperCase(ch)) {
  +                tmp = Character.toLowerCase(ch);
  +            } else
  +            if(Character.isTitleCase(ch)) {
  +                tmp = Character.toLowerCase(ch);
  +            } else
  +            if(Character.isLowerCase(ch)) {
  +                if(whitespace) {
  +                    tmp = Character.toTitleCase(ch);
                   } else {
  -                    if(idx != width) {
  -                        idx++;
  -                    }
  -                    buffer.append(substr.substring(0,idx));
  -                    buffer.append(delim);
  -//                    System.err.print(substr.substring(0,idx));
  -//                    System.err.print(delim);
  -                    i -= width-idx;
  +                    tmp = Character.toUpperCase(ch);
                   }
               } else {
  -                /*
  -                if(force) {
  -                    if(idx == width-1) {
  -                        buffer.append(substr);
  -                        buffer.append(delim);
  -                    } else {
  -                        // stick a split in.
  -                        int splitsz = split.length();
  -                        buffer.append(substr.substring(0,width-splitsz));
  -                        buffer.append(split);
  -                        buffer.append(delim);
  -                        i -= splitsz;
  -                    }
  -                } else {
  -                */
  -                    // insert spaces
  -                    buffer.append(substr.substring(0,idx));
  -                    buffer.append(repeat(" ",width-idx));
  -//                    System.err.print(substr.substring(0,idx));
  -//                    System.err.print(repeat(" ",width-idx));
  -                    buffer.append(delim);
  -//                    System.err.print(delim);
  -//                    System.err.println("i -= "+width+"-"+idx);
  -                    i -= width-idx;
  -//                }
  +                tmp = ch;
               }
  +            buffer.append(tmp);
  +            whitespace = Character.isWhitespace(ch);
           }
  -//        System.err.println("\n*************");
           return buffer.toString();
       }
   
   
       /**
  +     * Capitalise all the words in a string. Uses Character.isWhitespace 
  +     * as a separator between words. Null will return null.
  +     *
  +     * @param str  the string to capitalise
  +     * @return capitalised string
  +     */
  +    public static String capitaliseAllWords(String str) {
  +        if (str == null) {
  +            return null;
  +        }
  +        int sz = str.length();
  +        StringBuffer buffer = new StringBuffer(sz);
  +        boolean space = true;
  +        for(int i=0; i<sz; i++) {
  +            char ch = str.charAt(i);
  +            if(Character.isWhitespace(ch)) {
  +                buffer.append(ch);
  +                space = true;
  +            } else
  +            if(space) {
  +                buffer.append(Character.toTitleCase(ch));
  +                space = false;
  +            } else {
  +                buffer.append(ch);
  +            }
  +        }
  +        return buffer.toString();
  +    }
  +
  +    // Nested extraction
  +    //--------------------------------------------------------------------------
  +    
  +    /**
        * Get the String that is nested in between two instances of the 
        * same String.
        *
  -     * @param str   String containing nested-string
  -     * @param tag  String before and after nested-string
  -     *
  -     * @return String that was nested
  +     * @param str  the string containing nested-string
  +     * @param tag  the string before and after nested-string
  +     * @return the string that was nested, or null
        */
  -    static public String getNestedString(String str, String tag) {
  +    public static String getNestedString(String str, String tag) {
           return getNestedString(str, tag, tag);
       }
  +    
       /**
        * Get the string that is nested in between two strings.
        *
  -     * @param str   String containing nested-string
  -     * @param open  String before nested-string
  -     * @param close String after nested-string
  -     *
  -     * @return String that was nested
  +     * @param str  the string containing nested-string
  +     * @param open  the string before nested-string
  +     * @param close  the string after nested-string
  +     * @return the string that was nested, or null
        */
  -    static public String getNestedString(String str, String open, String close) {
  +    public static String getNestedString(String str, String open, String close) {
  +        if (str == null) {
  +            return null;
  +        }
           int start = str.indexOf(open);
  -        if(start != -1) {
  -            int end = str.indexOf(close, start+open.length());
  -            if(end != -1) {
  -                return str.substring(start+open.length(), end);
  +        if (start != -1) {
  +            int end = str.indexOf(close, start + open.length());
  +            if (end != -1) {
  +                return str.substring(start + open.length(), end);
               }
           }
  -        return "";
  +        return null;
       }
   
  -
       /**
  -     * How mmany times is the substring in the larger string.
  +     * How many times is the substring in the larger string.
  +     * Null returns 0.
  +     * 
  +     * @param str  the string to check
  +     * @return the number of occurances, 0 if the string is null
        */
  -    static public int countMatches(String str, String sub) {
  +    public static int countMatches(String str, String sub) {
  +        if (str == null) {
  +            return 0;
  +        }
           int count = 0;
           int idx = 0;
  -        while( (idx = str.indexOf(sub, idx)) != -1) {
  +        while ((idx = str.indexOf(sub, idx)) != -1) {
               count++;
               idx += sub.length();
           }
           return count;
       }
   
  +    // Character Tests
  +    //--------------------------------------------------------------------------
  +    
       /**
  -     * Is a String a word. Contains only unicode letters.
  +     * Checks if the string contains only unicode letters.
  +     * Null will return null.
  +     * 
  +     * @param str  the string to check
  +     * @return true if only contains letters, and is non-null
        */
  -    static public boolean isWord(String str) {
  +    public static boolean isAlpha(String str) {
  +        if (str == null) {
  +            return false;
  +        }
           int sz = str.length();
  -        for(int i=0; i<sz; i++) {
  -            if(!Character.isLetter(str.charAt(i))) {
  +        for (int i = 0; i < sz; i++) {
  +            if (Character.isLetter(str.charAt(i)) == false) {
                   return false;
               }
           }
  @@ -1655,12 +1671,19 @@
       }
   
       /**
  -     * Does a String contain only unicode letters or digits.
  +     * Checks if the string contains only unicode letters or digits.
  +     * Null will return null.
  +     * 
  +     * @param str  the string to check
  +     * @return true if only contains letters or digits, and is non-null
        */
  -    static public boolean isAlphanumeric(String str) {
  +    public static boolean isAlphanumeric(String str) {
  +        if (str == null) {
  +            return false;
  +        }
           int sz = str.length();
  -        for(int i=0; i<sz; i++) {
  -            if(!Character.isLetterOrDigit(str.charAt(i))) {
  +        for (int i = 0; i < sz; i++) {
  +            if (Character.isLetterOrDigit(str.charAt(i)) == false) {
                   return false;
               }
           }
  @@ -1668,12 +1691,61 @@
       }
   
       /**
  -     * Does a String contain only unicode digits.
  +     * Checks if the string contains only unicode letters, digits or space (' ').
  +     * Null will return null.
  +     * 
  +     * @param str  the string to check
  +     * @return true if only contains letters, digits or space, and is non-null
        */
  -    static public boolean isNumeric(String str) {
  +    public static boolean isAlphanumericSpace(String str) {
  +        if (str == null) {
  +            return false;
  +        }
           int sz = str.length();
  -        for(int i=0; i<sz; i++) {
  -            if(!Character.isDigit(str.charAt(i))) {
  +        for (int i = 0; i < sz; i++) {
  +            if ((Character.isLetterOrDigit(str.charAt(i)) == false) &&
  +                (str.charAt(i) != ' ')) {
  +                return false;
  +            }
  +        }
  +        return true;
  +    }
  +
  +    /**
  +     * Checks if the string contains only unicode digits.
  +     * Null will return null.
  +     * 
  +     * @param str  the string to check
  +     * @return true if only contains digits, and is non-null
  +     */
  +    public static boolean isNumeric(String str) {
  +        if (str == null) {
  +            return false;
  +        }
  +        int sz = str.length();
  +        for (int i = 0; i < sz; i++) {
  +            if (Character.isDigit(str.charAt(i)) == false) {
  +                return false;
  +            }
  +        }
  +        return true;
  +    }
  +
  +    /**
  +     * Checks if the string contains only unicode digits or space (' ').
  +     * Null will return null.
  +     * 
  +     * @param str  the string to check
  +     * @return true if only contains digits or space, and is non-null
  +     */
  +    public static boolean isNumericSpace(String str) {
  +        if (str == null) {
  +            return false;
  +        }
  +        int sz = str.length();
  +        for (int i = 0; i < sz; i++) {
  +            if ((Character.isDigit(str.charAt(i)) == false) &&
  +                (str.charAt(i) != ' ')) {
                   return false;
               }
           }
  @@ -1683,32 +1755,37 @@
       /**
        * Is a String a line, containing only letters, digits or 
        * whitespace, and ending with an optional newline.
  -     * NB: Punctuation not allowed.
  +     * Punctuation is not allowed. Null returns false.
  +     * 
  +     * @param str  the string to check
  +     * @return true if only contains digits or space, and is non-null
        */
  -    static public boolean isLine(String str) {
  +    public static boolean isLine(String str) {
  +        if (str == null) {
  +            return false;
  +        }
           char ch = 0;
           char[] chrs = str.toCharArray();
  -        int sz = chrs.length-1;
  -        for(int i=0; i<sz-2; i++) {
  -            if(!Character.isLetterOrDigit(chrs[i])) {
  -                if(!Character.isWhitespace(chrs[i])) {
  +        int sz = chrs.length - 1;
  +        for (int i = 0; i < sz - 2; i++) {
  +            if (Character.isLetterOrDigit(chrs[i]) == false) {
  +                if (Character.isWhitespace(chrs[i]) == false) {
                       return false;
                   }
               }
           }
  -        if(!Character.isLetterOrDigit(chrs[sz-1])) {
  -            if(!Character.isWhitespace(chrs[sz-1])) {
  -                if(chrs[sz-1] != '\r') {
  +        if (Character.isLetterOrDigit(chrs[sz - 1]) == false) {
  +            if (Character.isWhitespace(chrs[sz - 1]) == false) {
  +                if (chrs[sz - 1] != '\r') {
                       return false;
  -                } else 
  -                if(chrs[sz] != '\n') {
  +                } else if (chrs[sz] != '\n') {
                       return false;
                   }
               }
           }
  -        if(!Character.isLetterOrDigit(chrs[sz])) {
  -            if(!Character.isWhitespace(chrs[sz])) {
  -                if(chrs[sz] != '\n') {
  +        if (Character.isLetterOrDigit(chrs[sz]) == false) {
  +            if (Character.isWhitespace(chrs[sz]) == false) {
  +                if (chrs[sz] != '\n') {
                       return false;
                   }
               }
  @@ -1716,70 +1793,75 @@
           return true;
       }
   
  -    /*
  -    // needs to handle punctuation
  -    static public boolean isText(String str) {
  -        int sz = str.length();
  -        char ch = 0;
  -        for(int i=0; i<sz; i++) {
  -            ch = str.charAt(i);
  -            if(!Character.isLetterOrDigit(ch)) {
  -                if(!Character.isWhitespace(ch)) {
  -                    if( (ch != '\n') && (ch != '\r') ) {
  -                        return false;
  -                    }
  -                }
  -            }
  -        }
  -        return true;
  -    }
  -    */
  -
  +    // Defaults
  +    //--------------------------------------------------------------------------
  +    
       /**
        * Return either the passed in String, or if it is null, 
        * then an empty String.
  +     * 
  +     * @param str  the string to check
  +     * @return the passed in string, or blank if it was null
        */
  -    static public String defaultString(String str) {
  -        return defaultString(str,"");
  +    public static String defaultString(String str) {
  +        return defaultString(str, "");
       }
   
       /**
        * Return either the passed in String, or if it is null, 
        * then a passed in default String.
  +     * 
  +     * @param str  the string to check
  +     * @param defaultString  the default string to return is str is null
  +     * @return the passed in string, or the default if it was null
        */
  -    static public String defaultString(String str, String def) {
  -        return (str == null)?def:str;
  -    }
  -
  -    static public String upperCase(String str) {
  -        return str.toUpperCase();
  +    public static String defaultString(String str, String defaultString) {
  +        return (str == null) ? defaultString : str;
       }
   
  -    static public String lowerCase(String str) {
  -        return str.toLowerCase();
  -    }
  +    // Reversing
  +    //--------------------------------------------------------------------------
   
  -    static public String reverseDottedName(String text) {
  -        return reverseDelimitedString(text, ".");
  +    /**
  +     * Reverse a String, null string returns null.
  +     * 
  +     * @param str  the string to reverse
  +     * @return the reversed string
  +     */
  +    public static String reverse(String str) {
  +        if (str == null) {
  +            return null;
  +        }
  +        return new StringBuffer(str).reverse().toString();
       }
   
  -    static public String reverseDelimitedString(String text, String delimiter) {
  +    /**
  +     * Reverses a string that is delimited by a specific character.
  +     * The strings between the delimiters are not reversed.
  +     * Thus java.lang.String becomes String.lang.java (if the delimiter is '.').
  +     * 
  +     * @param str  the string to reverse
  +     * @param delimiter  the delimiter to use
  +     * @return the reversed string
  +     */
  +    public static String reverseDelimitedString(String str, String delimiter) {
           // could implement manually, but simple way is to reuse other, 
           // probably slower, methods.
  -        String[] strs = split(text, delimiter);
  -//        CollectionsUtils.reverseArray(strs);
  -// call private method instead for the moment.
  +        String[] strs = split(str, delimiter);
           reverseArray(strs);
           return join(strs, delimiter);
       }
   
  -/// TAKEN FROM CollectionsUtils. Need to find a solution.
  -    static private void reverseArray(Object[] array) {
  +    /**
  +     * Reverses an array. 
  +     * TAKEN FROM CollectionsUtils.
  +     */
  +    private static void reverseArray(Object[] array) {
           int i = 0;
           int j = array.length - 1;
           Object tmp;
   
  -        while(j>i) {
  +        while (j > i) {
               tmp = array[j];
               array[j] = array[i];
               array[i] = tmp;
  @@ -1789,22 +1871,9 @@
       }
   
   
  -    /**
  -     * Interpolate variables into a String.
  -     */
  -    static public String interpolate(String text, Map map) {
  -        Iterator keys = map.keySet().iterator();
  -        while(keys.hasNext()) {
  -            String key = keys.next().toString();
  -            String value = map.get(key).toString();
  -            text = replace(text, "${"+key+"}", value);
  -            if(key.indexOf(" ") == -1) {
  -                text = replace(text, "$"+key, value);
  -            }
  -        }
  -        return text;
  -    }
  -
  +    // Misc
  +    //--------------------------------------------------------------------------
  +    
       /**
        * Get the stack trace from a Throwable as a String.
        * <p>
  @@ -1814,8 +1883,7 @@
        * @param throwable  the throwable to extract a stack trace from
        * @return the extracted stack trace, or null if an error occurs
        */
  -    public static String stackTrace(Throwable throwable)
  -    {
  +    public static String stackTrace(Throwable throwable) {
           String trace = null;
           try {
               // And show the Error Screen.
  @@ -1830,6 +1898,68 @@
       }
   
       /**
  +     * Find the Levenshtein distance between two strings.
  +     * This is the number of changes needed to change one string into 
  +     * another. Where each change is a single character modification.
  +     *
  +     * This implemmentation of the levenshtein distance algorithm 
  +     * is from http://www.merriampark.com/ld.htm
  +     */
  +    public static int getLevenshteinDistance(String s, String t) {
  +        int d[][]; // matrix
  +        int n; // length of s
  +        int m; // length of t
  +        int i; // iterates through s
  +        int j; // iterates through t
  +        char s_i; // ith character of s
  +        char t_j; // jth character of t
  +        int cost; // cost
  +
  +        // Step 1
  +        n = s.length ();
  +        m = t.length ();
  +        if (n == 0) {
  +            return m;
  +        }
  +        if (m == 0) {
  +            return n;
  +        }
  +        d = new int[n+1][m+1];
  +
  +        // Step 2
  +        for (i = 0; i <= n; i++) {
  +            d[i][0] = i;
  +        }
  +
  +        for (j = 0; j <= m; j++) {
  +            d[0][j] = j;
  +        }
  +
  +        // Step 3
  +        for (i = 1; i <= n; i++) {
  +            s_i = s.charAt (i - 1);
  +
  +            // Step 4
  +            for (j = 1; j <= m; j++) {
  +                t_j = t.charAt (j - 1);
  +
  +                // Step 5
  +                if (s_i == t_j) {
  +                    cost = 0;
  +                } else {
  +                    cost = 1;
  +                }
  +
  +                // Step 6
  +                d[i][j] = Numbers.minimum(d[i-1][j]+1, d[i][j-1]+1, d[i-1][j-1] + cost);
  +            }
  +        }
  +
  +        // Step 7
  +        return d[n][m];
  +    }
  +
  +    /**
        * Convert a string from unicode to bytes in a native encoding.
        * The string must be in unicode (as Java always expects this);
        * {@link #convertNativeToUnicode(String, String)} will convert
  @@ -1845,8 +1975,7 @@
        * @see #convertNativeToUnicode(String, String)
        */
       public static String convertUnicodeToNative(String source, String charset)
  -        throws IOException
  -    {
  +            throws IOException {
           ByteArrayOutputStream baos = new ByteArrayOutputStream();
           OutputStreamWriter out = new OutputStreamWriter(baos, charset);
           out.write(source);
  @@ -1866,8 +1995,7 @@
        * specified native encoding.
        */
       public static String convertNativeToUnicode(String input, String charset)
  -        throws IOException
  -    {
  +            throws IOException {
           InputStreamReader in = new InputStreamReader
               (new ByteArrayInputStream(input.getBytes()), charset);
           StringBuffer output = new StringBuffer();
  @@ -1880,6 +2008,13 @@
           in.close();
           return output.toString();
       }
  +    
  +// these are not really of use in the Java world. Only if you're a C afficionado
  +//    public static String sprintf(String format, Object[] list);
  +//    public static Object[] sscanf(String str, String format);
  +//    public static String pack(String[] strs, String format);
  +//    public static String[] unpack(String str, String format);
  +
   }
   
   
  
  
  

--
To unsubscribe, e-mail:   <mailto:commons-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:commons-dev-help@jakarta.apache.org>


Mime
View raw message