commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bay...@apache.org
Subject cvs commit: jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang ClassUtils.java NumberUtils.java ObjectUtils.java RandomStringUtils.java SerializationUtils.java StringUtils.java Classes.java Numbers.java Objects.java RandomStrings.java Serialization.java Strings.java
Date Tue, 16 Jul 2002 02:00:28 GMT
bayard      2002/07/15 19:00:28

  Added:       lang/src/java/org/apache/commons/lang ClassUtils.java
                        NumberUtils.java ObjectUtils.java
                        RandomStringUtils.java SerializationUtils.java
                        StringUtils.java
  Removed:     lang/src/java/org/apache/commons/lang Classes.java
                        Numbers.java Objects.java RandomStrings.java
                        Serialization.java Strings.java
  Log:
  The plural naming convention changed to the xxxUtils convention.
  
  Revision  Changes    Path
  1.1                  jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/ClassUtils.java
  
  Index: ClassUtils.java
  ===================================================================
  package org.apache.commons.lang;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /**
   * A set of static utilities for use with ClassUtils.
   *
   * @author  bayard@generationjava.com
   * @version $Id: ClassUtils.java,v 1.1 2002/07/16 02:00:28 bayard Exp $
   */
  final public class ClassUtils {
  
      /**
       * Create an object from the classname. Must have an empty constructor.
       *
       * @param classname String name of the class
       *
       * @return Object instance of the class or null
       */
      static public Object createObject(String classname) {
          Class tmpClass = null;
  
          tmpClass = getClass(classname);
  
          return createObject(tmpClass);
      }
  
      /**
       * Create an object from a class. 
       *
       * @param clss Class object to instantiate
       *
       * @return Object instance of the class or null
       */
      static public Object createObject(Class clss) {
  
          try {
              return clss.newInstance();
          } catch (IllegalAccessException  iae) {
              System.err.println("Cant instantiate " + clss.getName() + " because " +
                     iae.getMessage());
          } catch (InstantiationException  ie) {
              System.err.println("Cant instantiate " + clss.getName() + " because " +
                     ie.getMessage());
          }
  
          return null;
      }
  
      /**
       * Is this Class in the CLASSPATH
       *
       * @param classname String of the class
       *
       * @return boolean exists or not.
       */
      static public boolean classExists(String classname) {
          Class tmpClass = null;
  
          /* try and load class */
          try {
              tmpClass = Class.forName(classname);
          } catch (ClassNotFoundException cnfe) {
              return false;
          } catch (IllegalArgumentException iae) {
              return false;
          }
       
          return true;   
      }
  
      /**
       * Get the Class object for a classname.
       *
       * @param classname String of the class
       *
       * @return Class instance for the class.
       */
      static public Class getClass(String classname) {
          Class tmpClass = null;
  
          /* try an load class */
          try {
              tmpClass = Class.forName(classname);
          } catch (ClassNotFoundException cnfe) {
              System.out.println("Can't resolve classname " + classname);
          } catch (IllegalArgumentException iae) {
              System.err.println("Cant resolve " + tmpClass.getName() + " because " + iae.getMessage());
          }
       
          return tmpClass;   
      }
  
      /**
       * Is this Class object an instance of the class with this name.
       *
       * @param clss Class instance
       * @param inst String name of potential supertype
       *
       * @return boolean was it an instanceof
       */
      static public boolean classInstanceOf(Class clss, String inst) {
          if(classImplements(clss,inst)) {
              return true;
          } else
          if(classExtends(clss,inst)) {
              return true;
          } else {
              return false;
          }
      }
  
      /**
       * Does this Class implement an interface with this name.
       *
       * @param clss Class instance
       * @param exts String name of potential interface
       *
       * @return boolean was it an implementor
       */
      static public boolean classImplements(Class clss, String exts) {
  
        Class sprcls = clss;
        Class excls  = getClass(exts);
  
        while(sprcls != null) {
          Class[] interfaces = sprcls.getInterfaces();
  
          for(int i=0;i<interfaces.length;i++) {
              if(interfaces[i].equals(excls)) {
                  return true;
              }
          }
  
          sprcls = sprcls.getSuperclass();
        }
  
        return false;
      }
  
      /**
       * Does this Class extend a superclass with this name.
       *
       * @param clss Class instance
       * @param exts String name of potential superclass
       *
       * @return boolean was it a superclass
       */
      static public boolean classExtends(Class clss, String exts) {
          if(clss == null) {
              return false;
          }
          if(clss.getName().equals(exts)) {
              return true;
          }
          Class sprcls = clss.getSuperclass();
          Class excls = getClass(exts);
  
  //        while(! sprcls.equals(sprcls.getSuperclass()) ) {
          while( sprcls != null ) {
              if(sprcls.equals(excls)) {
                  return true;
              }
              sprcls = sprcls.getSuperclass();
          }
          return false;
      }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/NumberUtils.java
  
  Index: NumberUtils.java
  ===================================================================
  package org.apache.commons.lang;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.math.BigInteger;
  import java.math.BigDecimal;
  /**
   * Provides extra functionality for java Number classes.
   *
   * @author <a href="mailto:bayard@generationjava.com">Henri Yandell</a>
   * @author <a href="mailto:rand_mcneely@yahoo.com">Rand McNeely</a>
   * @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
   * @version $Id: NumberUtils.java,v 1.1 2002/07/16 02:00:28 bayard Exp $
   */
  public final class NumberUtils {
  
      /**
       * Convert a String to an int, returning zero if the conversion fails
       * 
       * @param str  the string to convert
       * @return the int represented by the string, or zero if conversion fails
       */
      public static int stringToInt(String str) {
          return stringToInt(str, 0);
      }
  
      /**
       * Convert a String to an Int, returning a default value if the 
       * conversion fails.
       * 
       * @param str  the string to convert
       * @param defaultValue  the default value
       * @return the int represented by the string, or the default if conversion fails
       */
      public static int stringToInt(String str, int defaultValue) {
          try {
              return Integer.parseInt(str);
          } catch (NumberFormatException nfe) {
              return defaultValue;
          }
      }
  
      // must handle Long, Float, Integer, Float, Short,
      //                  BigDecimal, BigInteger and Byte
      // useful methods:
      // Byte.decode(String)
      // Byte.valueOf(String,int radix)
      // Byte.valueOf(String)
      // Double.valueOf(String)
      // Float.valueOf(String)
      // new Float(String)
      // Integer.valueOf(String,int radix)
      // Integer.valueOf(String)
      // Integer.decode(String)
      // Integer.getInteger(String)
      // Integer.getInteger(String,int val)
      // Integer.getInteger(String,Integer val)
      // new Integer(String)
      // new Double(String)
      // new Byte(String)
      // new Long(String)
      // Long.getLong(String)
      // Long.getLong(String,int)
      // Long.getLong(String,Integer)
      // Long.valueOf(String,int)
      // Long.valueOf(String)
      // new Short(String)
      // Short.decode(String)
      // Short.valueOf(String,int)
      // Short.valueOf(String)
      // new BigDecimal(String)
      // new BigInteger(String)
      // new BigInteger(String,int radix)
      // Possible inputs:
      // 45 45.5 45E7 4.5E7 Hex Oct Binary xxxF xxxD xxxf xxxd
      // plus minus everything. Prolly more. A lot are not separable.
  
      /**
       * <p>
       * Turns a string value into a java.lang.Number.
       * First, the value is examined for a type qualifier on the end 
       * (<code>'f','F','d','D','l','L'</code>).  If it is found, it starts 
       * trying to create succissively larger types from the type specified
       * until one is found that can hold the value.
       * </p>
       * <p>
       * If a type specifier is not found, it will check for a decimal point
       * and then try successively larger types from Integer to BigInteger 
       * and from Float to BigDecimal.
       * </p>
       * <p>
       * If the string starts with "0x" or "-0x", it will be interpreted as a 
       * hexadecimal integer.  Values with leading 0's will not be interpreted 
       * as octal.
       * </p>
       * 
       * @param val String containing a number
       * @return Number created from the string
       * @throws NumberFormatException if the value cannot be converted
       */
      public static Number createNumber(String val) throws NumberFormatException {
          if (val == null) {
              return null;
          }
          if (val.length() == 0) {
              throw new NumberFormatException("\"\" is not a valid number.");
          }
          if (val.startsWith("--")) {
              // this is protection for poorness in java.lang.BigDecimal.
              // it accepts this as a legal value, but it does not appear 
              // to be in specification of class. OS X Java parses it to 
              // a wrong value.
              return null;
          }
          if (val.startsWith("0x") || val.startsWith("-0x")) {
              return createInteger(val);
          }   
          char lastChar = val.charAt(val.length() - 1);
          String mant;
          String dec;
          String exp;
          int decPos = val.indexOf('.');
          int expPos = val.indexOf('e') + val.indexOf('E') + 1;
  
          if (decPos > -1) {
  
              if (expPos > -1) {
                  if (expPos < decPos) {
                      throw new NumberFormatException(val + " is not a valid number.");
                  }
                  dec = val.substring(decPos + 1, expPos);
              } else {
                  dec = val.substring(decPos + 1);
              }
              mant = val.substring(0, decPos);
          } else {
              if (expPos > -1) {
                  mant = val.substring(0, expPos);
              } else {
                  mant = val;
              }
              dec = null;
          }
          if (!Character.isDigit(lastChar)) {
              if (expPos > -1 && expPos < val.length() - 1) {
                  exp = val.substring(expPos + 1, val.length() - 1);
              } else {
                  exp = null;
              }
              //Requesting a specific type..
              String numeric = val.substring(0, val.length() - 1);
              boolean allZeros = isAllZeros(mant) && isAllZeros(exp);
              switch (lastChar) {
                  case 'l' :
                  case 'L' :
                      if (dec == null
                          && exp == null
                          && isDigits(numeric.substring(1))
                          && (numeric.charAt(0) == '-' || Character.isDigit(numeric.charAt(0)))) {
                          try {
                              return createLong(numeric);
                          } catch (NumberFormatException nfe) {
                              //Too big for a long
                          }
                          return createBigInteger(numeric);
  
                      }
                      throw new NumberFormatException(val + " is not a valid number.");
                  case 'f' :
                  case 'F' :
                      try {
                          Float f = NumberUtils.createFloat(numeric);
                          if (!(f.isInfinite() || (f.floatValue() == 0.0F && !allZeros))) {
                              //If it's too big for a float or the float value = 0 and the string
                              //has non-zeros in it, then float doens't have the presision we want
                              return f;
                          }
  
                      } catch (NumberFormatException nfe) {
                      }
                      //Fall through
                  case 'd' :
                  case 'D' :
                      try {
                          Double d = NumberUtils.createDouble(numeric);
                          if (!(d.isInfinite() || (d.floatValue() == 0.0D && !allZeros))) {
                              return d;
                          }
                      } catch (NumberFormatException nfe) {
                      }
                      try {
                          return createBigDecimal(numeric);
                      } catch (NumberFormatException e) {
                      }
                      //Fall through
                  default :
                      throw new NumberFormatException(val + " is not a valid number.");
  
              }
          } else {
              //User doesn't have a preference on the return type, so let's start
              //small and go from there...
              if (expPos > -1 && expPos < val.length() - 1) {
                  exp = val.substring(expPos + 1, val.length());
              } else {
                  exp = null;
              }
              if (dec == null && exp == null) {
                  //Must be an int,long,bigint
                  try {
                      return createInteger(val);
                  } catch (NumberFormatException nfe) {
                  }
                  try {
                      return createLong(val);
                  } catch (NumberFormatException nfe) {
                  }
                  return createBigInteger(val);
  
              } else {
                  //Must be a float,double,BigDec
                  boolean allZeros = isAllZeros(mant) && isAllZeros(exp);
                  try {
                      Float f = createFloat(val);
                      if (!(f.isInfinite() || (f.floatValue() == 0.0F && !allZeros))) {
                          return f;
                      }
                  } catch (NumberFormatException nfe) {
                  }
                  try {
                      Double d = createDouble(val);
                      if (!(d.isInfinite() || (d.doubleValue() == 0.0D && !allZeros))) {
                          return d;
                      }
                  } catch (NumberFormatException nfe) {
                  }
  
                  return createBigDecimal(val);
  
              }
  
          }
      }
  
      /**
       * Utility method for createNumber.  Returns true if s is null
       * 
       * @param s the String to check
       * @return if it is all zeros or null
       */
      private static boolean isAllZeros(String s) {
          if (s == null) {
              return true;
          }
          for (int i = s.length() - 1; i >= 0; i--) {
              if (s.charAt(i) != '0') {
                  return false;
              }
          }
          return s.length() > 0;
      }
  
      /**
       * Convert a String to a Float
       * 
       * @param val  a String to convert
       * @return converted Float
       */
      public static Float createFloat(String val) {
          return Float.valueOf(val);
      }
  
      /**
       * Convert a String to a Double
       * 
       * @param val  a String to convert
       * @return converted Double
       */
      public static Double createDouble(String val) {
          return Double.valueOf(val);
      }
  
      /**
       * Convert a String to a Integer, handling hex and
       * octal notations.
       * 
       * @param val  a String to convert
       * @return converted Integer
       */
      public static Integer createInteger(String val) {
          // decode() handles 0xAABD and 0777 (hex and octal) as well.
          return Integer.decode(val);
      }
  
      /**
       * Convert a String to a Long
       * 
       * @param val  a String to convert
       * @return converted Long
       */
      public static Long createLong(String val) {
          return Long.valueOf(val);
      }
  
      /**
       * Convert a String to a BigInteger
       * 
       * @param val  a String to convert
       * @return converted BigInteger
       */
      public static BigInteger createBigInteger(String val) {
          BigInteger bi = new BigInteger(val);
          return bi;
      }
  
      /**
       * Convert a String to a BigDecimal
       * 
       * @param val  a String to convert
       * @return converted BigDecimal
       */
      public static BigDecimal createBigDecimal(String val) {
          BigDecimal bd = new BigDecimal(val);
          return bd;
      }
  
      /**
       * Get the minimum of three values.
       */
      public static int minimum(int a, int b, int c) {
          if (b < a) {
              a = b;
          }
          if (c < a) {
              a = c;
          }
          return a;
      }
  
      /**
       * Get the maximum of three values.
       */
      public static int maximum(int a, int b, int c) {
          if (b > a) {
              a = b;
          }
          if (c > a) {
              a = c;
          }
          return a;
      }
  
      /**
       * Checks whether the String contains only digit characters.
       * Null and blank string will return false.
       *
       * @param str  the string to check
       * @return boolean contains only unicode numeric
       */
      public static boolean isDigits(String str) {
          if ((str == null) || (str.length() == 0)) {
              return false;
          }
          for (int i = 0; i < str.length(); i++) {
              if (!Character.isDigit(str.charAt(i))) {
                  return false;
              }
          }
          return true;
      }
  
      /**
       * <p>
       * Checks whether the String a valid Java number.
       * Valid numbers include hexadecimal marked with the "0x" qualifier,
       * scientific notation and numbers marked with a type qualifier (e.g. 123L).
       * </p>
       * <p>
       * Null and blank string will return false.
       * </p>
       * 
       * @param str  the string to check
       * @return true if the string is a correctly formatted number
       */
      public static boolean isNumber(String str) {
          if ((str == null) || (str.length() == 0)) {
              return false;
          }
          char[] chars = str.toCharArray();
          int sz = chars.length;
          boolean hasExp = false;
          boolean hasDecPoint = false;
          boolean allowSigns = false;
          boolean foundDigit = false;
          //Deal with any possible sign up front
          int start = (chars[0] == '-') ? 1 : 0;
          if (sz > start + 1) {
              if (chars[start] == '0' && chars[start + 1] == 'x') {
                  int i = start + 2;
                  if (i == sz) {
                      return false; // str == "0x"
                  }
                  //Checking hex (it can't be anything else)
                  for (; i < chars.length; i++) {
                      if ((chars[i] < '0' || chars[i] > '9')
                          && (chars[i] < 'a' || chars[i] > 'f')
                          && (chars[i] < 'A' || chars[i] > 'F')) {
                          return false;
                      }
                  }
                  return true;
              }
          }
          sz--; //Don't want to loop to the last char, check it afterwords
                //for type qualifiers
          int i = start;
          //Loop to the next to last char or to the last char if we need another digit to
          //make a valid number (e.g. chars[0..5] = "1234E")
          while (i < sz || (i < sz + 1 && allowSigns && !foundDigit)) {
              if (chars[i] >= '0' && chars[i] <= '9') {
                  foundDigit = true;
                  allowSigns = false;
  
              } else if (chars[i] == '.') {
                  if (hasDecPoint || hasExp) {
                      //Two decimal points or dec in exponent   
                      return false;
                  }
                  hasDecPoint = true;
              } else if (chars[i] == 'e' || chars[i] == 'E') {
                  //We've already taken care of hex.
                  if (hasExp) {
                      //Two E's
                      return false;
                  }
                  if (!foundDigit) {
                      return false;
                  }
                  hasExp = true;
                  allowSigns = true;
              } else if (chars[i] == '+' || chars[i] == '-') {
                  if (!allowSigns) {
                      return false;
                  }
                  allowSigns = false;
                  foundDigit = false; //We need a digit after the E
              } else {
                  return false;
              }
              i++;
          }
          if (i < chars.length) {
              if (chars[i] >= '0' && chars[i] <= '9') {
                  //No type qualifier, OK
                  return true;
              }
              if (chars[i] == 'e' || chars[i] == 'E') {
                  //Can't have an E at the last byte
                  return false;
              }
              if (!allowSigns
                  && (chars[i] == 'd'
                      || chars[i] == 'D'
                      || chars[i] == 'f'
                      || chars[i] == 'F')) {
                  return foundDigit;
              }
              if (chars[i] == 'l'
                  || chars[i] == 'L') {
                  //Not allowing L with an exponoent
                  return foundDigit && !hasExp;
              }
          }
          //allowSigns is true iff the val ends in 'E'
          //Found digit it to make sure weird stuff like '.' and '1E-' doesn't pass
          return !allowSigns && foundDigit;
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/ObjectUtils.java
  
  Index: ObjectUtils.java
  ===================================================================
  package org.apache.commons.lang;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /**
   * Common <code>Object</code> manipulation routines.
   *
   * @author <a href="mailto:nissim@nksystems.com">Nissim Karpenstein</a>
   * @author <a href="mailto:janekdb@yahoo.co.uk">Janek Bogucki</a>
   * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
   * @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
   * @version $Id: ObjectUtils.java,v 1.1 2002/07/16 02:00:28 bayard Exp $
   */
  public class ObjectUtils {
      
      /**
       * Returns a default value if the object passed is null.
       *
       * @param object  the object to test.
       * @param defaultValue  the default value to return.
       * @return object if it is not null, defaultValue otherwise.
       */
      public static Object defaultIfNull(Object object, Object defaultValue) {
          return (object != null ? object : defaultValue);
      }
  
      /**
       * Compares two objects for equality, where either one or both
       * objects may be <code>null</code>.
       *
       * @param object1  the first object.
       * @param object2  the second object.
       * @return True if the values of both objects are the same.
       */
      public static boolean equals(Object object1, Object object2) {
          if (object1 == null) {
              return (object2 == null);
          } else if (object2 == null) {
              // object1 is not null
              return false;
          } else {
              return object1.equals(object2);
          }
      }
      
  }
  
  
  
  1.1                  jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/RandomStringUtils.java
  
  Index: RandomStringUtils.java
  ===================================================================
  package org.apache.commons.lang;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.util.Random;
  /**
   * <p>Common random <code>String</code> manipulation routines.</p>
   *
   * <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>
   * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
   * @author <a href="mailto:gcoladonato@yahoo.com">Greg Coladonato</a>
   * @author <a href="mailto:bayard@generationjava.com">Bayard</a>
   * @author <a href="mailto:ed@apache.org">Ed Korthof</a>
   * @author <a href="mailto:steven@caswell.name">Steven Caswell</a>
   * @version $Id: RandomStringUtils.java,v 1.1 2002/07/16 02:00:28 bayard Exp $
   */
  public class RandomStringUtils
  {
  
      /**
       * Random object used by random method. This has to be not local 
       * to the random method so as to not return the same value in the 
       * same millisecond. 
       */
      private static Random RANDOM = new Random();
  
      /**
       * Prevent construction of RandomStringUtils instances
       */
      private RandomStringUtils() {
      }
  
      /**
       * Creates a random string whose length is the number of characters
       * specified. Characters will be chosen from the set of all characters.
       *
       * @param count length of random string to create
       * @return the random string
       */
      public static String random(int count) {
          return random(count, false, false);
      }
  
      /**
       * Creates a random string whose length is the number of characters
       * specified. Characters will be chosen from the set of characters whose
       * ASCII value is between 32 and 127 .
       *
       * @param count length of random string to create
       * @return the random string
       */
      public static String randomAscii(int count) {
          return random(count, 32, 127, false, false);
      }
      
      /**
       * Creates a random string whose length is the number of characters
       * specified. Characters will be chosen from the set of alphabetic
       * characters.
       *
       * @param count length of random string to create
       * @return the random string
       */
      public static String randomAlphabetic(int count) {
          return random(count, true, false);
      }
      
      /**
       * Creates a random string whose length is the number of characters
       * specified. Characters will be chosen from the set of alpha-numeric
       * characters.
       *
       * @param count length of random string to create
       * @return the random string
       */
      public static String randomAlphanumeric(int count) {
          return random(count, true, true);
      }
      
      /**
       * Creates a random string whose length is the number of characters
       * specified. Characters will be chosen from the set of numeric
       * characters.
       *
       * @param count length of random string to create
       * @return the random string
       */
      public static String randomNumeric(int count) {
          return random(count, false, true);
      }
  
      /**
       * Creates a random string whose length is the number of characters
       * specified. Characters will be chosen from the set of alpha-numeric
       * characters as indicated by the arguments.
       *
       * @param count length of random string to create
       * @param letters if <code>true</code>, generated string will include
       * alphabetic characters
       * @param numbers if <code>true</code>, generatd string will include
       * numeric characters
       * @return the random string
       */
      public static String random(int count, boolean letters, boolean numbers) {
          return random(count, 0, 0, letters, numbers);
      }
      
      /**
       * Creates a random string whose length is the number of characters
       * specified. Characters will be chosen from the set of alpha-numeric
       * characters as indicated by the arguments.
       *
       * @param count length of random string to create
       * @param start int position in set of chars to start at
       * @param end int position in set of chars to end before
       * @param letters if <code>true</code>, generated string will include
       * alphabetic characters
       * @param numbers if <code>true</code>, generatd string will include
       * numeric characters
       * @return the random string
       */
      public static String random(int count, int start, int end, boolean letters, boolean numbers) {
          return random(count, start, end, letters, numbers, null);
      }
      
      /**
       * Creates a random string based on a variety of options.
       *
       * @param count int length of random string to create
       * @param start int position in set of chars to start at
       * @param end int position in set of chars to end before
       * @param letters boolean only allow letters?
       * @param numbers boolean only allow numbers?
       * @param set char[] set of chars to choose randoms from.
       *        If null, then it will use the set of all chars.
       * @return the random string
       */
      public static String random(int count, int start, int end, boolean letters, boolean numbers, char[] set) {
          if( (start == 0) && (end == 0) ) {
              end = (int)'z';
              start = (int)' ';
              if(!letters && !numbers) {
                  start = 0;
                  end = Integer.MAX_VALUE;
              }
          }
  
          StringBuffer buffer = new StringBuffer();
          int gap = end - start;
  
          while(count-- != 0) {
              char ch;
              if(set == null) {
                  ch = (char)(RANDOM.nextInt(gap) + start);
              } else {
                  ch = set[RANDOM.nextInt(gap) + start];
              }
              if( (letters && numbers && Character.isLetterOrDigit(ch)) ||
                  (letters && Character.isLetter(ch)) ||
                  (numbers && Character.isDigit(ch)) ||
                  (!letters && !numbers)
                ) 
              {
                  buffer.append( ch );
              } else {
                  count++;
              }
          }
          return buffer.toString();
      }
  
      /**
       * Creates a random string whose length is the number of characters
       * specified. Characters will be chosen from the set of characters
       * specified.
       *
       * @param count int length of random string to create
       * @param set String containing the set of characters to use
       * @return the random string
       */
      public static String random(int count, String set) {
          return random(count, set.toCharArray());
      }
  
      /**
       * Creates a random string whose length is the number of characters
       * specified. Characters will be chosen from the set of characters
       * specified.
       *
       * @param count int length of random string to create
       * @param set character array containing the set of characters to use
       * @return the random string
       */
      public static String random(int count, char[] set) {
          return random(count,0,set.length-1,false,false,set);
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/SerializationUtils.java
  
  Index: SerializationUtils.java
  ===================================================================
  package org.apache.commons.lang;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.ByteArrayInputStream;
  import java.io.ByteArrayOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.ObjectInputStream;
  import java.io.ObjectOutputStream;
  import java.io.OutputStream;
  import java.io.Serializable;
  
  /**
   * Methods that assist with the serialization process, or perform
   * additional functionality based on serialization.
   * <ul>
   * <li>Deep clone using serialization
   * <li>Serialize managing finally and IOException
   * <li>Deserialize managing finally and IOException
   * </ul>
   *
   * @author <a href="mailto:nissim@nksystems.com">Nissim Karpenstein</a>
   * @author <a href="mailto:janekdb@yahoo.co.uk">Janek Bogucki</a>
   * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
   * @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
   * @version $Id: SerializationUtils.java,v 1.1 2002/07/16 02:00:28 bayard Exp $
   */
  public class SerializationUtils {
      
      /**
       * Constructor for SerializationUtils is private
       */
      private SerializationUtils() {
          super();
      }
  
      /**
       * Deep clone an object using serialization.
       * <p>
       * This is many times slower than writing clone methods by hand
       * on all objects in your object graph. However, for complex object
       * graphs, or for those that don't support deep cloning this can
       * be a simple alternative implementation. Of course all the objects
       * must be <code>Serializable</code>.
       * 
       * @param object  the <code>Serializable</code> object to clone
       * @return the cloned object
       * @throws SerializationException (runtime) if the serialization fails
       */
      public static Object clone(Serializable object) {
          return deserialize( serialize(object) );
      }
      
      /**
       * Serializes an object to the specified stream. The stream will
       * be closed once the object is written. This avoids the need for
       * a finally clause, and maybe also exception handling, in the
       * application code.
       *
       * @param obj  the object to serialize to bytes
       * @param outputStream  the stream to write to
       * @throws SerializationException (runtime) if the serialization fails
       */
      public static void serialize(Serializable obj, OutputStream outputStream) {
          ObjectOutputStream out = null;
          try {
              // stream closed in the finally
              out = new ObjectOutputStream(outputStream);
              out.writeObject(obj);
              
          } catch (IOException ex) {
              throw new SerializationException(ex);
          } finally {
              try {
                  if (out != null) {
                      out.close();
                  }
              } catch (IOException ex) {
                  // ignore;
              }
          }
      }
  
      /**
       * Serializes an object to a byte array for storage/serialization.
       *
       * @param obj  the object to serialize to bytes
       * @return a byte[] with the converted Serializable.
       * @throws SerializationException (runtime) if the serialization fails
       */
      public static byte[] serialize(Serializable obj) {
          ByteArrayOutputStream baos = new ByteArrayOutputStream();
          serialize(obj, baos);
          return baos.toByteArray();
      }
  
      /**
       * Deserializes an object from the specified stream. The stream will
       * be closed once the object is written. This avoids the need for
       * a finally clause, and maybe also exception handling, in the
       * application code.
       *
       * @param objectData  the serialized object.
       * @return the deserialized object
       * @throws SerializationException (runtime) if the serialization fails
       */
      public static Object deserialize(InputStream inputStream) {
          ObjectInputStream in = null;
          try {
              // stream closed in the finally
              in = new ObjectInputStream(inputStream);
              return in.readObject();
              
          } catch (ClassNotFoundException ex) {
              throw new SerializationException(ex);
          } catch (IOException ex) {
              throw new SerializationException(ex);
          } finally {
              try {
                  if (in != null) {
                      in.close();
                  }
              } catch (IOException ex) {
                  // ignore
              }
          }
      }
  
      /**
       * Deserializes a single object from an array of bytes.
       *
       * @param objectData  the serialized object.
       * @return the deserialized object
       * @throws SerializationException (runtime) if the serialization fails
       */
      public static Object deserialize(byte[] objectData) {
          ByteArrayInputStream bais = new ByteArrayInputStream(objectData);
          return deserialize(bais);
      }
      
  }
  
  
  
  1.1                  jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/StringUtils.java
  
  Index: StringUtils.java
  ===================================================================
  package org.apache.commons.lang;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.ByteArrayInputStream;
  import java.io.ByteArrayOutputStream;
  import java.io.InputStreamReader;
  import java.io.OutputStreamWriter;
  import java.io.OutputStream;
  import java.io.PrintWriter;
  import java.io.IOException;
  import java.util.NoSuchElementException;
  import java.util.StringTokenizer;
  
  import java.util.Iterator;
  
  /**
   * <p>Common <code>String</code> manipulation routines.</p>
   *
   * <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>
   * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
   * @author <a href="mailto:gcoladonato@yahoo.com">Greg Coladonato</a>
   * @author <a href="mailto:bayard@generationjava.com">Bayard</a>
   * @author <a href="mailto:ed@apache.org">Ed Korthof</a>
   * @author <a href="mailto:rand_mcneely@yahoo.com>Rand McNeely</a>
   * @author <a href="mailto:scolebourne@joda.org>Stephen Colebourne</a>
   * @version $Id: StringUtils.java,v 1.1 2002/07/16 02:00:28 bayard Exp $
   */
  public class StringUtils {
  
      /**
       * The size of the buffer to use when working with I/O (4 kB).
       */
      public static int CHAR_BUFFER_SIZE = 4 * 1024;
      
      // Empty
      //--------------------------------------------------------------------------
  
      /**
       * Removes white space from both ends of this string, handling null
       * by returning an empty string.
       *
       * @see java.lang.String#trim()
       * @param str  the string to check
       * @return the trimmed text (never <code>null</code>)
       */
      public static String clean(String str) {
          return (str == null ? "" : str.trim());
      }
  
      /**
       * Removes white space from both ends of this string, handling null
       * by returning null.
       *
       * @see java.lang.String#trim()
       * @param str  the string to check
       * @return the trimmed text (or <code>null</code>)
       */
      public static String trim(String str) {
          return (str == null ? null : str.trim());
      }
  
      /**
       * Checks if a String is non null and is not empty (length > 0).
       *
       * @param str  the string to check
       * @return true if the String is non-null, and not length zero
       */
      public static boolean isNotEmpty(String str) {
          return (str != null && str.length() > 0);
      }
  
      /**
       * Checks if a (trimmed) String is null or empty.
       *
       * @param str  the string to check
       * @return true if the String is null, or length zero once trimmed
       */
      public static boolean isEmpty(String str) {
          return (str == null || str.trim().length() == 0);
      }
  
      // Equals and IndexOf
      //--------------------------------------------------------------------------
  
      /**
       * Compares two StringUtils, returning true if they are equal.
       * Nulls are handled without exceptions. Two <code>null</code>
       * references are considered equal. Comparison is case sensitive.
       *
       * @param str1  the first string
       * @param str2  the second string
       * @return true if the StringUtils are equal, case sensitive, or both null
       */
      public static boolean equals(String str1, String str2) {
          return (str1 == null ? str2 == null : str1.equals(str2));
      }
  
      /**
       * Compares two StringUtils, returning true if they are equal ignoring case.
       * Nulls are handled without exceptions. Two <code>null</code>
       * references are considered equal. Comparison is case insensitive.
       *
       * @param str1  the first string
       * @param str2  the second string
       * @return true if the StringUtils are equal, case insensitive, or both null
       */
      public static boolean equalsIgnoreCase(String str1, String str2) {
          return (str1 == null ? str2 == null : str1.equalsIgnoreCase(str2));
      }
  
      /**
       * Find the earliest index of any of a set of potential substrings.
       * Null string will return -1.
       * 
       * @param str  the string to check
       * @param searchStrs  the strings to search for
       * @return the earliest index of any of the strings
       */
      public static int indexOfAny(String str, String[] searchStrs) {
          if ((str == null) || (searchStrs == null)) {
              return -1;
          }
          int sz = searchStrs.length;
  
          // String's can't have a MAX_VALUEth index.
          int ret = Integer.MAX_VALUE;
  
          int tmp = 0;
          for (int i = 0; i < sz; i++) {
              tmp = str.indexOf(searchStrs[i]);
              if (tmp == -1) {
                  continue;
              }
  
              if (tmp < ret) {
                  ret = tmp;
              }
          }
  
          return (ret == Integer.MAX_VALUE) ? -1 : ret;
      }
  
      /**
       * Find the latest index of any of a set of potential substrings.
       * Null string will return -1.
       * 
       * @param str  the string to check
       * @param searchStrs  the strings to search for
       * @return the last index of any of the strings
       */
      public static int lastIndexOfAny(String str, String[] searchStrs) {
          if ((str == null) || (searchStrs == null)) {
              return -1;
          }
          int sz = searchStrs.length;
          int ret = -1;
          int tmp = 0;
          for (int i = 0; i < sz; i++) {
              tmp = str.lastIndexOf(searchStrs[i]);
              if (tmp > ret) {
                  ret = tmp;
              }
          }
          return ret;
      }
  
      // Substring
      //--------------------------------------------------------------------------
      
      /**
       * Gets a substring of the specified string avoiding exceptions.
       * A negative start position can be used to start n characters from
       * the end of the string.
       * 
       * @param str  the string to get the substring from
       * @param start  the position to start from,  negative means 
       * count back from the end of the string by this many characters
       * @return substring from start position
       */
      public static String substring(String str, int start) {
          if (str == null) {
              return null;
          }
  
          // handle negatives, which means last n characters
          if (start < 0) {
              start = str.length() + start; // remember start is negative
          }
  
          if (start < 0) {
              start = 0;
          }
          if (start > str.length()) {
              return "";
          }
  
          return str.substring(start);
      }
      
      /**
       * Gets a substring of the specified string avoiding exceptions.
       * A negative start position can be used to start/end n characters
       * from the end of the string.
       * 
       * @param str  the string to get the substring from
       * @param start  the position to start from, negative means 
       * count back from the end of the string by this many characters
       * @param end  the position to end at (exclusive),  negative means 
       * count back from the end of the string by this many characters
       * @return substring from start position to end positon
       */
      public static String substring(String str, int start, int end) {
          if (str == null) {
              return null;
          }
  
          // handle negatives
          if (end < 0) {
              end = str.length() + end; // remember end is negative
          }
          if (start < 0) {
              start = str.length() + start; // remember start is negative
          }
  
          // check length next
          if (end > str.length()) {
              // check this works.
              end = str.length();
          }
  
          // if start is greater than end, return ""
          if (start > end) {
              return "";
          }
  
          if (start < 0) {
              start = 0;
          }
          if (end < 0) {
              end = 0;
          }
  
          return str.substring(start, end);
      }
  
      /**
       * Gets the leftmost n characters of a string. If n characters are not 
       * available, or the string is null, the string will be returned 
       * without an exception.
       *
       * @param str  the string to get the leftmost characters from
       * @param len  the length of the required string
       * @return the leftmost characters
       * @throws IllegalArgumentException if len is less than zero
       */
      public static String left(String str, int len) {
          if (len < 0) {
              throw new IllegalArgumentException("Requested String length " + len + " is less than zero");
          }
          if ((str == null) || (str.length() <= len)) {
              return str;
          } else {
              return str.substring(0, len);
          }
      }
  
      /**
       * Gets the rightmost n characters of a string. If n characters are not 
       * available, or the string is null, the string will be returned 
       * without an exception.
       *
       * @param str  the string to get the rightmost characters from
       * @param len  the length of the required string
       * @return the leftmost characters
       * @throws IllegalArgumentException if len is less than zero
       */
      public static String right(String str, int len) {
          if (len < 0) {
              throw new IllegalArgumentException("Requested String length " + len + " is less than zero");
          }
          if ((str == null) || (str.length() <= len)) {
              return str;
          } else {
              return str.substring(str.length() - len);
          }
      }
  
      /**
       * Gets n characters from the middle of a string. If n characters are 
       * not available, the remainder of the string will be returned 
       * without an exception. If the string is null, null will be returned.
       *
       * @param str  the string to get the characters from
       * @param pos  the position to start from
       * @param len  the length of the required string
       * @return the leftmost characters
       * @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) {
          if ((pos < 0) ||
              (str != null && pos > str.length())) {
              throw new StringIndexOutOfBoundsException("String index " + pos + " is out of bounds");
          }
          if (len < 0) {
              throw new IllegalArgumentException("Requested String length " + len + " is less than zero");
          }
          if (str == null) {
              return null;
          }
          if (str.length() <= (pos + len)) {
              return str.substring(pos);
          } else {
              return str.substring(pos, pos + len);
          }
      }
  
      // Splitting
      //--------------------------------------------------------------------------
      
      /**
       * Splits the provided text into a list, using whitespace as the separator.
       * The separator is not included in the returned String array.
       *
       * @param str  the string to parse
       * @return an array of parsed StringUtils 
       */
      public static String[] split(String text)
      {
          return split(text, null, -1);
      }
  
      /**
       * Splits the provided text into a list, based on a given separator.
       * The separator is not included in the returned String array.
       * A null separator will cause parsing to be on whitespace.
       *
       * @param str  the string to parse
       * @param separator  The separator character. If <code>null</code>, splits
       *  on whitespace.
       * @return an array of parsed StringUtils 
       */
      public static String[] split(String text, String separator)
      {
          return split(text, separator, -1);
      }
  
      /**
       * Splits the provided text into a list, based on a given separator.
       * The separator is not included in the returned String array.
       * The maximum number of splits to perfom can be controlled.
       * A null separator will cause parsing to be on whitespace.
       *
       * @param str  the string to parse
       * @param separator  The separator character. If <code>null</code>, splits
       *  on whitespace.
       * @param max  The maximum number of elements to include in the
       *  list.  A zero or negative value implies no limit.
       * @return an array of parsed StringUtils 
       */
      public static String[] split(String text, String separator, int max)
      {
          StringTokenizer tok = null;
          if (separator == null) {
              // Null separator means we're using StringTokenizer's default
              // delimiter, which comprises all whitespace characters.
              tok = new StringTokenizer(text);
          } else {
              tok = new StringTokenizer(text, separator);
          }
  
          int listSize = tok.countTokens();
          if (max > 0 && listSize > max) {
              listSize = max;
          }
  
          String[] list = new String[listSize];
          int i = 0;
          while (tok.hasMoreTokens()) {
              if (max > 0 && i == listSize - 1) {
                  // In the situation where we hit the max yet have
                  // tokens left over in our input, the last list
                  // element gets all remaining text.
                  StringBuffer buf = new StringBuffer((int) 1.2 * text.length() * (listSize - i) / listSize);
                  while (tok.hasMoreTokens()) {
                      buf.append(tok.nextToken());
                      if (tok.hasMoreTokens()) {
                          buf.append(separator);
                      }
                  }
                  list[i] = buf.toString();
                  break;
              } else {
                  list[i] = tok.nextToken();
              }
              i++;
          }
          return list;
      }
  
      // Joining
      //--------------------------------------------------------------------------
      
      /**
       * Joins the elements of the provided array into a single string
       * containing the provided list of elements. 
       * No delimiter is added before or after the list.
       * A null separator is the same as a blank String.
       *
       * @param array  the array of values to join together
       * @param separator  the separator character to use
       * @return the joined String
       */
      public static String join(Object[] array, String separator)
      {
          if (separator == null) {
              separator = "";
          }
          int arraySize = array.length;
          int bufSize = (arraySize == 0 ? 0 : (array[0].toString().length() +
                                   separator.length()) * arraySize);
          StringBuffer buf = new StringBuffer(bufSize);
  
          for (int i = 0; i < arraySize; i++) {
              if (i > 0) {
                  buf.append(separator);
              }
              buf.append(array[i]);
          }
          return buf.toString();
      }
  
      /**
       * Joins the elements of the provided iterator into a single string
       * containing the provided elements.
       * No delimiter is added before or after the list.
       * A null separator is the same as a blank String.
       *
       * @param iterator  the iterator of values to join together
       * @param separator  the separator character to use
       * @return the joined String
       */
      public static String join(Iterator iterator, String separator)
      {
          if (separator == null) {
              separator = "";
          }
          StringBuffer buf = new StringBuffer(256);  // Java default is 16, probably too small
          while (iterator.hasNext()) {
              buf.append(iterator.next());
              if (iterator.hasNext()) {
                  buf.append(separator);
              }
          }
          return buf.toString();
      }
  
  
  
      // Replacing
      //--------------------------------------------------------------------------
      
      /**
       * Replace a string with another string inside a larger string, once.
       *
       * @see #replace(String text, String repl, String with, int max)
       */
      public static String replaceOnce(String text, String repl, String with)
      {
          return replace(text, repl, with, 1);
      }
  
      /**
       * @see #replace(String text, String repl, String with, int max)
       */
      public static String replace(String text, String repl, String with)
      {
          return replace(text, repl, with, -1);
      }
  
      /**
       * Replace a string with another string inside a larger string,
       * for the first <code>max</code> values of the search string.  A
       * <code>null</code> reference is passed to this method is a
       * no-op.
       *
       * @param text Text to search and replace in.
       * @param repl String to search for
       * @param with String to replace with
       * @param max Maximum number of values to replace, or
       * <code>-1</code> if no maximum.
       * @return The text with any replacements processed.
       */
      public static String replace(String text, String repl, String with,
                                   int max)
      {
          if (text == null)
          {
              return null;
          }
  
          StringBuffer buf = new StringBuffer(text.length());
          int start = 0, end = 0;
          while ( (end = text.indexOf(repl, start)) != -1 )
          {
              //System.err.println("end=" + end);
              buf.append(text.substring(start, end)).append(with);
              start = end + repl.length();
              //System.err.println("new start=" + start);
  
              if (--max == 0)
              {
                  break;
              }
          }
          buf.append(text.substring(start));
          return buf.toString();
      }
  
      /**
       * Overlay a part of a string with another string.
       *
       * @param text String to do overlaying in
       * @param overlay String to overlay
       * @param start int to start overlaying at
       * @param end   int to stop overlaying before
       *
       * @return String with overlayed text
       */
      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)
  			.append(text.substring(end))
  			.toString();
      }
  
      // Centering
      //--------------------------------------------------------------------------
      
      /**
       * Center a string in a larger string of size n.
       * Uses spaces as the value to buffer the string with..
       *
       * @param str String to center
       * @param n   int    size of new String
       *
       * @return String containing centered String
       */
      public static String center(String str, int n) {
          return center(str, n, " ");
      }
  
      /**
       * Center a string in a larger string of size n.
       * Uses a supplied String as the value to buffer the string with..
       *
       * @param str String to center
       * @param n   int    size of new String
       * @param delim String to buffer the new String with
       *
       * @return String containing centered String
       */
      public static String center(String str, int n, String delim) {
          int sz = str.length();
          int p = n-sz;
          if(p < 1) {
              return str;
          }
          str = leftPad(str,sz+p/2, delim);
          str = rightPad(str, n, delim);
          return str;
      }
  
      // Chomping
      //--------------------------------------------------------------------------
      
      /** 
       * Remove the last newline, and everything after it from a String.
       *
       * @param str String to chomp the newline from
       *
       * @return String without chomped newline
       */
      public static String chomp(String str) {
          return chomp(str, "\n");
      }
      
      /** 
       * Remove the last value of a supplied String, and everything after it 
       * from a String.
       *
       * @param str String to chomp from
       * @param sep String to chomp
       *
       * @return String without chomped ending
       */
      public static String chomp(String str, String sep) {
          int idx = str.lastIndexOf(sep);
          if(idx != -1) {
              return str.substring(0,idx);
          } else {
              return str;
          }
      }
      
      /**
       * Remove a newline if and only if it is at the end 
       * of the supplied string.
       */
      public static String chompLast(String str) {
          return chompLast(str, "\n");
      }
      public static String chompLast(String str, String sep) {
          if(str.length() == 0) {
              return str;
          }
          String sub = str.substring(str.length() - sep.length());
          if(sep.equals(sub)) {
              return str.substring(0,str.length()-sep.length());
          } else {
              return str;
          }
      }
  
      /** 
       * Remove everything and return the last value of a supplied String, and 
       * everything after it from a String.
       *
       * @param str String to chomp from
       * @param sep String to chomp
       *
       * @return String chomped
       */
      public static String getChomp(String str, String sep) {
          int idx = str.lastIndexOf(sep);
          if(idx == str.length()-sep.length()) {
              return sep;
          } else
          if(idx != -1) {
              return str.substring(idx);
          } else {
              return "";
          }
      }
  
      /** 
       * Remove the first value of a supplied String, and everything before it 
       * from a String.
       *
       * @param str String to chomp from
       * @param sep String to chomp
       *
       * @return String without chomped beginning
       */
      public static String prechomp(String str, String sep) {
          int idx = str.indexOf(sep);
          if(idx != -1) {
              return str.substring(idx+sep.length());
          } else {
              return str;
          }
      }
  
      /** 
       * Remove and return everything before the first value of a 
       * supplied String from another String.
       *
       * @param str String to chomp from
       * @param sep String to chomp
       *
       * @return String prechomped
       */
      public static String getPrechomp(String str, String sep) {
          int idx = str.indexOf(sep);
          if(idx != -1) {
              return str.substring(0,idx+sep.length());
          } else {
              return "";
          }
      }
  
      // Chopping
      //--------------------------------------------------------------------------
      
      /**
       * Remove the last character from a String. If the String 
       * ends in \r\n, then remove both of them.
       *
       * @param str String to chop last character from
       *
       * @return String without last character
       */
      public static String chop(String str) {
          if("".equals(str)) {
              return "";
          }
          if(str.length() == 1) {
              return "";
          }
          int lastIdx = str.length()-1;
          String ret = str.substring(0,lastIdx);
          char last = str.charAt(lastIdx);
          if(last == '\n') {
              if(ret.charAt(lastIdx-1) == '\r') {
                  return ret.substring(0,lastIdx-1);
              }
          }
          return ret;
      }
  
      /**
       * Remove \n from end of a String if it's there.
       * If a \r precedes it, then remove that too.
       *
       * @param str String to chop a newline from
       *
       * @param String without newline on end
       */
      public static String chopNewline(String str) {
          int lastIdx = str.length()-1;
          char last = str.charAt(lastIdx);
          if(last == '\n') {
              if(str.charAt(lastIdx-1) == '\r') {
                  lastIdx --;
              }
          } else {
              lastIdx++;
          }
          return str.substring(0,lastIdx);
      }
  
  
      // Conversion
      //--------------------------------------------------------------------------
      
      // spec 3.10.6
      /**
       * Escapes any values it finds into their String form.
       * So a tab becomes the characters '\\' and 't'.
       *
       * @param str String to escape values in
       *
       * @return String with escaped values
       */
      // improved with code from  cybertiger@cyberiantiger.org
      // unicode from him, and defaul for < 32's.
      public static String escape(String str) {
          int sz = str.length();
          StringBuffer buffer = new StringBuffer(2*sz);
          for(int i=0; i<sz; i++) {
              char ch = str.charAt(i);
  
              // handle unicode
              if(ch > 0xfff) {
                  buffer.append("\\u"+Integer.toHexString(ch));
              } else 
              if(ch > 0xff) {
                  buffer.append("\\u0"+Integer.toHexString(ch));
              } else 
              if(ch > 0x7f) {
                  buffer.append("\\u00"+Integer.toHexString(ch));
              } else 
              if(ch < 32) {
                  switch(ch) {
                      case '\b' : 
                          buffer.append('\\');
                          buffer.append('b');
                          break;
                      case '\n' : 
                          buffer.append('\\');
                          buffer.append('n');
                          break;
                      case '\t' : 
                          buffer.append('\\');
                          buffer.append('t');
                          break;
                      case '\f' : 
                          buffer.append('\\');
                          buffer.append('f');
                          break;
                      case '\r' : 
                          buffer.append('\\');
                          buffer.append('r');
                          break;
                      default :
                          if( ch > 0xf ) {
                              buffer.append("\\u00"+Integer.toHexString(ch));
                          } else {
                              buffer.append("\\u000"+Integer.toHexString(ch));
                          }
                          break;
                  }
              } else {
                  switch(ch) {
                      case '\'' : 
                          buffer.append('\\');
                          buffer.append('\'');
                          break;
                      case '"' : 
                          buffer.append('\\');
                          buffer.append('"');
                          break;
                      case '\\' : 
                          buffer.append('\\');
                          buffer.append('\\');
                          break;
                      default :
                          buffer.append(ch);
                          break;
                  }
              }
          }
          return buffer.toString();
      }
  
      // 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.
       */
      public static String rightPad(String str, int n) {
          return rightPad(str, n, " ");
      }
      /**
       * Right pad a String with a specified string. Pad to a size of n.
       *
       * @param str   String to pad out
       * @param n     int    size to pad to
       * @param delim String to pad with
       */
      public static String rightPad(String str, int n, String delim) {
          n = (n - str.length())/delim.length();
          if(n > 0) {
              str += repeat(delim,n);
          }
          return str;
      }
  
      /**
       * Left pad a String with spaces. Pad to a size of n.
       */
      public static String leftPad(String str, int n) {
          return leftPad(str, n, " ");
      }
      /**
       * Left pad a String with a specified string. Pad to a size of n.
       *
       * @param str   String to pad out
       * @param n     int    size to pad to
       * @param delim String to pad with
       */
      public static String leftPad(String str, int n, String delim) {
          n = (n - str.length())/delim.length();
          if(n > 0) {
              str = repeat(delim,n) + str;
          }
          return str;
      }
  
      // Stripping
      //--------------------------------------------------------------------------
      
      /**
       * Remove whitespace from the front and back of a String.
       */
      public static String strip(String str) {
          return strip(str, null);
      }
      /**
       * Remove a specified String from the front and back of a 
       * String. If Whitespace is wanted to be removed, used the 
       * strip(String) method.
       */
      public static String strip(String str, String delim) {
          str = stripStart(str, delim);
          return stripEnd(str, delim);
      }
  
      /**
       * Strip whitespace from the front and back of every string
       * in the array.
       */
      public static String[] stripAll(String[] strs) {
          return stripAll(strs, null);
      }
   
      /**
       * Strip the specified delimiter from the front and back of
       * every String in the array.
       */
      public static String[] stripAll(String[] strs, String delimiter) {
          if( (strs == null) || (strs.length == 0) ) {
              return strs;
          }
          int sz = strs.length;
          String[] newArr = new String[sz];
          for(int i=0; i<sz; i++) {
              newArr[i] = strip(strs[i], delimiter);
          }
          return newArr;
      }   
  
      /**
       * Strip any of a supplied substring from the end of a String..
       */
      public static String stripEnd(String str, String ch) {
          if(str == null) {
              return null;
          }
          int end = str.length();
   
          if(ch == null) {
              while( (end != 0) && Character.isWhitespace( str.charAt(end-1) ) ) {                end--;
              }
          } else {
              char chr = ch.charAt(0);
              while( (end != 0) && (str.charAt(end-1) == chr) ) {
                  end--;
              }
          }      
          return str.substring(0, end);
      }
  
      /**
       * Strip any of a supplied substring from the start of a String..
       */
      public static String stripStart(String str, String ch) {
          if(str == null) {
              return null;
          }
   
          int start = 0;
   
          int sz = str.length();
   
          if(ch == null) {
              while( (start != sz) && Character.isWhitespace( str.charAt(start) ) ) {
                  start++;
              }
          } else {
              char chr = ch.charAt(0);
              while( (start != sz) && (str.charAt(start) == chr ) ) {
                  start++;
              }
          }
          return str.substring(start);     
      }
  
      // Case conversion
      //--------------------------------------------------------------------------
      
      /**
       * Convert a String to upper case, null string returns null.
       * 
       * @param str  the string to uppercase
       * @return the upper cased string
       */
      public static String upperCase(String str) {
          if (str == null) {
              return null;
          }
          return str.toUpperCase();
      }
  
      /**
       * Convert a String to lower case, null string returns null.
       * 
       * @param str  the string to lowercase
       * @return the lower cased string
       */
      public static String lowerCase(String str) {
          if (str == null) {
              return null;
          }
          return str.toLowerCase();
      }
  
      /**
       * 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
       */
      public static String uncapitalise(String str) {
          if (str == null) {
              return null;
          }
          if (str.length() == 0) {
              return "";
          }
          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. Null is returned as null.
       *
       * @param str  the string to capitalise
       * @return capitalised string
       */
      public static String capitalise(String str) {
          if (str == null) {
              return null;
          }
          if (str.length() == 0) {
              return "";
          }
          return new StringBuffer(str.length())
              .append(Character.toTitleCase(str.charAt(0)))
              .append(str.substring(1))
              .toString();
      }
  
      /**
       * 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
       */
      public static String swapCase(String str) {
          if (str == null) {
              return null;
          }
          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();
      }
  
  
      /**
       * 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  the string containing nested-string
       * @param tag  the string before and after nested-string
       * @return the string that was nested, or null
       */
      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  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
       */
      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);
              }
          }
          return null;
      }
  
      /**
       * 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
       */
      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) {
              count++;
              idx += sub.length();
          }
          return count;
      }
  
      // Character Tests
      //--------------------------------------------------------------------------
      
      /**
       * 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
       */
      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)) == false) {
                  return false;
              }
          }
          return true;
      }
  
      /**
       * Checks if the string contains only unicode letters and space (' ').
       * Null will return null.
       * 
       * @param str  the string to check
       * @return true if only contains letters and space, and is non-null
       */
      public static boolean isAlphaSpace(String str) {
          if (str == null) {
              return false;
          }
          int sz = str.length();
          for (int i = 0; i < sz; i++) {
              if ((Character.isLetter(str.charAt(i)) == false) &&
                  (str.charAt(i) != ' ')) {
                  return false;
              }
          }
          return true;
      }
  
      /**
       * 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
       */
      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)) == false) {
                  return false;
              }
          }
          return true;
      }
  
      /**
       * 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
       */
      public static boolean isAlphanumericSpace(String str) {
          if (str == null) {
              return false;
          }
          int sz = str.length();
          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;
              }
          }
          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
       */
      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
       */
      public static String defaultString(String str, String defaultString) {
          return (str == null) ? defaultString : str;
      }
  
      // Reversing
      //--------------------------------------------------------------------------
  
      /**
       * 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();
      }
  
      /**
       * 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(str, delimiter);
          reverseArray(strs);
          return join(strs, delimiter);
      }
  
      /**
       * 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) {
              tmp = array[j];
              array[j] = array[i];
              array[i] = tmp;
              j--;
              i++;
          }
      }
  
  
      // Misc
      //--------------------------------------------------------------------------
      
      /**
       * Get the stack trace from a Throwable as a String.
       * <p>
       * This method uses printStackTrace() internally to obtain the stack trace.
       *
       * @see java.lang.Throwable#printStackTrace()
       * @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) {
          String trace = null;
          try {
              // And show the Error Screen.
              ByteArrayOutputStream buf = new ByteArrayOutputStream();
              throwable.printStackTrace( new PrintWriter(buf, true) );
              trace = buf.toString();
              
          } catch (Exception ex) {
              // ignore
          }
          return trace;
      }
  
      /**
       * 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
       * strings in native encodings into unicode.  This method is
       * generally used to create a <code>String</code> for use as
       * output, and is useful when dealing with I18N.
       *
       * @param source String the unicode string to convert
       * @param charset String the name of the charset into which to
       * convert.
       * @return The string given represented in the native encoding
       * specified.
       * @see #convertNativeToUnicode(String, String)
       */
      public static String convertUnicodeToNative(String source, String charset)
              throws IOException {
          ByteArrayOutputStream baos = new ByteArrayOutputStream();
          OutputStreamWriter out = new OutputStreamWriter(baos, charset);
          out.write(source);
          out.close();
          return baos.toString();
      }
  
      /**
       * Convert a string from a native encoding to unicode.  This
       * method is generally used to create a <code>String</code> for
       * use as input, and is useful when dealing with I18N.
       *
       * @param input String the input to convert from native encoding
       * to unicode.
       * @param charset String the charset from which to convert.
       * @return The string given represented in unicode rather than the
       * specified native encoding.
       */
      public static String convertNativeToUnicode(String input, String charset)
              throws IOException {
          InputStreamReader in = new InputStreamReader
              (new ByteArrayInputStream(input.getBytes()), charset);
          StringBuffer output = new StringBuffer();
          char[] buf = new char[CHAR_BUFFER_SIZE];
          int count = 0;
          while ((count = in.read(buf, 0, CHAR_BUFFER_SIZE)) > 0)
          {
              output.append(buf, 0, count);
          }
          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