You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by ba...@apache.org on 2002/02/22 06:57:15 UTC
cvs commit: jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/exception Nestable.java NestableDelegate.java NestableException.java NestableRuntimeException.java
bayard 02/02/21 21:57:15
Added: lang/src/java/org/apache/commons/lang Classes.java
Numbers.java Objects.java Strings.java
lang/src/java/org/apache/commons/lang/exception
Nestable.java NestableDelegate.java
NestableException.java
NestableRuntimeException.java
Log:
Initial commit of 'lang' classes from Commons.Utils.
Revision Changes Path
1.1 jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/Classes.java
Index: Classes.java
===================================================================
package org.apache.commons.lang;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 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
* "Apache 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",
* "Apache Turbine", 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/>.
*/
/**
* A set of static utilities for use with Classes.
*
* @author bayard@generationjava.com
* @version $Id: Classes.java,v 1.1 2002/02/22 05:57:15 bayard Exp $
*/
final public class Classes {
/**
* 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/Numbers.java
Index: Numbers.java
===================================================================
package org.apache.commons.lang;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 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
* "Apache 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",
* "Apache Turbine", 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.math.BigInteger;
import java.math.BigDecimal;
/**
* Provides extra functionality for java Number classes.
*
* @author bayard@generationjava.com
* @version $Id: Numbers.java,v 1.1 2002/02/22 05:57:15 bayard Exp $
*/
final public class Numbers {
static public int stringToInt(String str) {
return stringToInt(str,0);
}
static public int stringToInt(String str, int def) {
try {
return Integer.parseInt(str);
} catch(NumberFormatException nfe) {
return def;
}
}
// 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.
/**
* Turns a string value into a java.lang.Number.
* Strategy is to look for a decimal point. If that is seen then
* try first float and then try double.
* If this fails, then try int and then long.
* Assuming 50f fails and isn't 50, then try hexadecimal.
*
* @param val String containing a number
*
* @return Number created from the string
*/
static public Number createNumber(String val)
throws NumberFormatException
{
if (val == null) {
return null;
}
int idx = val.indexOf('.');
if ( (idx != -1) && (idx != val.length()-1) ) {
try {
return createFloat(val);
} catch (NumberFormatException nfe) {
}
try {
return createDouble(val);
} catch (NumberFormatException nfe) {
}
// look for all digits or '.' with f or F on end.
if( val.endsWith("f") || val.endsWith("F") ) {
String mant = val.substring(0,idx);
String dec = val.substring(idx+1,val.length()-1);
if(containsDigits(mant) && containsDigits(dec) ) {
try {
return createFloat(val.substring(0,val.length()-1));
} catch (NumberFormatException nfe) {
}
}
}
// look for all digits or '.' with d or D on end.
if( val.endsWith("d") || val.endsWith("D") ) {
String mant = val.substring(0,idx);
String dec = val.substring(idx+1,val.length()-1);
if(containsDigits(mant) && containsDigits(dec) ) {
try {
return createDouble(val.substring(0,val.length()-1));
} catch (NumberFormatException nfe) {
}
}
}
try {
return createBigDecimal(val);
} catch (NumberFormatException nfe) {
}
throw new NumberFormatException("Unable to convert: "+val);
}
try {
return createInteger(val);
} catch (NumberFormatException nfe) {
}
try {
return createLong(val);
} catch (NumberFormatException nfe) {
}
// look for all digits with l or L on the end.
if( val.endsWith("l") || val.endsWith("L") ) {
if(containsDigits(val.substring(0,val.length()-1))) {
try {
return createLong(val.substring(0,val.length()-1));
} catch (NumberFormatException nfe) {
}
}
}
try {
return createBigInteger(val);
} catch (NumberFormatException nfe) {
}
// try Hex.
try {
return Integer.valueOf(val,16);
} catch (NumberFormatException nfe) {
}
throw new NumberFormatException("Unable to convert: "+val);
}
/**
* Return true if the string contains only digit characters.
*
* @param val String to check is only digits
*
* @return boolean contains only unicode numeric
*/
static public boolean containsDigits(String val) {
if(val == null) {
return false; // ???
}
for(int i=0;i<val.length();i++) {
if(!Character.isDigit(val.charAt(i))) {
return false;
}
}
return true;
}
static public Float createFloat(String val) {
return Float.valueOf(val);
}
static public Double createDouble(String val) {
return Double.valueOf(val);
}
// handles 0xAABD and 0777 (hex and octal) as well.
static public Integer createInteger(String val) {
// return Integer.valueOf(val);
return Integer.decode(val);
}
static public Long createLong(String val) {
return Long.valueOf(val);
}
static public BigInteger createBigInteger(String val) {
BigInteger bi = new BigInteger(val);
return bi;
}
static public BigDecimal createBigDecimal(String val) {
BigDecimal bd = new BigDecimal(val);
return bd;
}
/**
* Get the minimum of three values.
*/
static public int minimum(int a, int b, int c) {
if(b < a) {
a = b;
}
if(c < a) {
a = c;
}
return a;
}
/**
* Is a String a valid Java number.
* Doesn't allow scientific notation.
*/
static public boolean isNumber(String str) {
char[] chrs = str.toCharArray();
int sz = chrs.length;
boolean decimal = false;
for(int i=0; i<sz; i++) {
// possibly faster as a continuous switch
if( (chrs[i] >= '0') && (chrs[i] <= '9') ) {
continue;
}
if(i==0) {
if(chrs[i] == '-') {
continue;
}
}
if(chrs[i] == '.') {
if(!decimal) {
decimal = true;
continue;
}
}
return false;
}
return true;
}
}
1.1 jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/Objects.java
Index: Objects.java
===================================================================
package org.apache.commons.lang;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 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
* "Apache Turbine" 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",
* "Apache Turbine", 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.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
/**
* 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>
* @version $Id: Objects.java,v 1.1 2002/02/22 05:57:15 bayard Exp $
*/
public class Objects
{
/**
* Returns a default value if the object passed is null.
*
* @param o The object to test.
* @param dflt The default value to return.
* @return The object o if it is not null, dflt otherwise.
*/
public static Object isNull(Object o, Object dflt)
{
return (o != null ? o : dflt);
}
/**
* Deserializes a single object from an array of bytes.
*
* @param objectData The serialized object.
* @return The deserialized object, or <code>null</code> on failure.
*/
public static Object deserialize(byte[] objectData)
{
Object object = null;
if (objectData != null)
{
ObjectInputStream in = null;
try
{
InputStream bin = new ByteArrayInputStream(objectData);
in = new ObjectInputStream(bin);
// If objectData has not been initialized, an
// exception will occur.
object = in.readObject();
}
catch (Exception returnNull)
{
}
finally
{
try
{
if (in != null)
{
in.close();
}
}
catch (IOException ignored)
{
}
}
}
return object;
}
/**
* Compares two objects for equality, where either one or both
* objects may be <code>null</code>.
*
* @param o1 The first object.
* @param o2 The second object.
* @return True if the values of both objects are the same.
*/
public static boolean equals(Object o1, Object o2)
{
if (o1 == null)
{
return (o2 == null);
}
else if (o2 == null)
{
// o1 is not null
return false;
}
else
{
return o1.equals(o2);
}
}
}
1.1 jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/Strings.java
Index: Strings.java
===================================================================
package org.apache.commons.lang;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 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
* "Apache Turbine" 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",
* "Apache Turbine", 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.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;
import java.util.Map;
import java.util.Random;
// CharSet
import java.util.List;
import java.util.LinkedList;
/**
* <p>Common <code>String</code> manipulation routines.</p>
*
* <p>Originally from <a
* href="http://jakarta.apache.org/turbine/">Turbine</a> and the
* 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>
* @version $Id: Strings.java,v 1.1 2002/02/22 05:57:15 bayard Exp $
*/
public class Strings
{
/**
* The size of the buffer to use when working with I/O (4 kB).
*/
//public static int CHAR_BUFFER_SIZE = 4 * FileUtils.ONE_KB;
public static int CHAR_BUFFER_SIZE = 4 * 1024;
/**
* Trims text safely, dealing with <code>null</code> references by
* converting them to <code>""</code> (the empty string).
*
* @param s The text to trim.
* @return The trimmed text (never <code>null</code>).
*/
public static final String clean(String s)
{
return (s == null ? "" : s.trim());
}
/**
* Trims text safely, dealing with <code>null</code> references by
* returning <code>null</code> (rather than throwing a
* NullPointerException).
*
* @param s The text to trim.
* @return The trimmed text (or <code>null</code>).
*/
public static final String trim(String s)
{
return (s == null ? null : s.trim());
}
/**
* Validates that the supplied string is neither <code>null</code>
* nor the empty string.
*
* @param text The text to check.
* @return Whether valid.
*/
public static final boolean isValid(String text)
{
return (text != null && text.length() > 0);
}
/**
* Determine whether a (trimmed) string is empty
*
* @param foo The text to check.
* @return Whether empty.
*/
public static final boolean isEmpty(String foo)
{
return (foo == null || foo.trim().length() == 0);
}
/**
* Returns the output of printStackTrace as a String.
*
* @param e The source to extract a stack trace from.
* @return The extracted stack trace.
*/
public static final String stackTrace(Throwable e)
{
String trace = null;
try
{
// And show the Error Screen.
ByteArrayOutputStream buf = new ByteArrayOutputStream();
e.printStackTrace( new PrintWriter(buf, true) );
trace = buf.toString();
}
catch (Exception ignored)
{
}
return trace;
}
/**
* Safely compares two <code>String</code> objects, returning
* whether their values are the same. Two <code>null</code>
* references are considered equal.
*
* @param s1 The first string.
* @param s2 The second string.
* @return Whether the values of both strings are the same.
*/
public static boolean equals(String s1, String s2)
{
return (s1 == null ? s2 == null : s1.equals(s2));
}
/**
* Takes a String of the form <code>substring[substring]substring</code>
* and returns the three parsed substrings.
*
* @return A three element {@link java.lang.String} array populated by
* any parsed object key components.
*/
public static String[] parseObjectKey(String s)
{
String[] objectKey = new String[3];
StringTokenizer st = new StringTokenizer(s, "[]");
int count = st.countTokens();
if (count > 1)
{
objectKey[0] = st.nextToken();
objectKey[1] = st.nextToken();
if (count == 3)
{
objectKey[2] = st.nextToken();
}
}
return objectKey;
}
/**
* Removes underscores from text.
*
* @param text The text to remove any underscores from.
* @return The underscore-less text.
* @deprecated Use replace(String, String, String) instead.
*/
public static String removeUnderScores(String text)
{
return replace(text, "_", "", -1);
}
/**
* Makes the first letter capital and leaves the rest as is.
*
* @param text The text to modify.
* @return The modified text.
*/
public static String firstLetterCaps(String text)
{
return (text == null ? null :
text.substring(0, 1).toUpperCase() + text.substring(1));
}
/**
* @see #split(String text, String separator, int max)
*/
public static String[] split(String text)
{
return split(text, " ", -1);
}
/**
* @see #split(String text, String separator, int max)
*/
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.
*
* @param text Textual list to parse.
* @param separator The separator character.
* @param max The maximum number of elements to include in the
* list. A value of <code>-1</code> implies no limit.
* @return The list of values.
*/
public static String[] split(String text, String separator, int max)
{
StringTokenizer tok = new StringTokenizer(text, separator);
int listSize = tok.countTokens();
if (max != -1 && listSize > max)
{
listSize = max;
}
String[] list = new String[listSize];
int i = 0;
while (tok.hasMoreTokens())
{
if (max != -1 && 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;
}
/**
* 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.
*
* @param list The list of values to join together.
* @param separator The separator character.
* @return The CSV text.
*/
public static String join(Object[] list, String separator)
{
int listSize = list.length;
int bufSize = (listSize == 0 ? 0 :(list[0].toString().length() +
separator.length()) * listSize);
StringBuffer buf = new StringBuffer(bufSize);
for (int i = 0; i < listSize; i++)
{
if (i > 0)
{
buf.append(separator);
}
buf.append(list[i]);
}
return buf.toString();
}
/**
* Merges the list of <code>Object</code> intances supplied by an
* <code>Iterator</code> into a single piece text. No delimiter
* is added before or after the list.
*
* @param iterator The list provider.
* @param separator String delimiter to separate list elements
* with.
* @return Text delimited list as a <code>String</code>.
*/
public static String join(Iterator iterator, String separator)
{
StringBuffer buf = new StringBuffer();
while (iterator.hasNext())
{
buf.append(iterator.next());
if (iterator.hasNext())
{
buf.append(separator);
}
}
return buf.toString();
}
/**
* Takes a block of text which might have long lines in it and wraps
* the long lines based on the supplied wrapColumn parameter. It was
* initially implemented for use by VelocityEmail. If there are tabs
* in inString, you are going to get results that are a bit strange,
* since tabs are a single character but are displayed as 4 or 8
* spaces. Remove the tabs.
*
* @param inString Text which is in need of word-wrapping.
* @param newline The characters that define a newline.
* @param wrapColumn The column to wrap the words at.
* @return The text with all the long lines word-wrapped.
*/
public static String wrapText (String inString, String newline,
int wrapColumn)
{
StringTokenizer lineTokenizer = new StringTokenizer (
inString, newline, true);
StringBuffer stringBuffer = new StringBuffer();
while (lineTokenizer.hasMoreTokens ())
{
try
{
String nextLine = lineTokenizer.nextToken();
if (nextLine.length() > wrapColumn)
{
// This line is long enough to be wrapped.
nextLine = wrapLine (nextLine, newline, wrapColumn);
}
stringBuffer.append (nextLine);
}
catch (NoSuchElementException nsee)
{
// thrown by nextToken(), but I don't know why it would
break;
}
}
return (stringBuffer.toString());
}
/**
* Wraps a single line of text. Called by wrapText(). I can't
* think of any good reason for exposing this to the public,
* since wrapText should always be used AFAIK.
*
* @param line A line which is in need of word-wrapping.
* @param newline The characters that define a newline.
* @param wrapColumn The column to wrap the words at.
* @return A line with newlines inserted.
*/
protected static String wrapLine (String line, String newline,
int wrapColumn)
{
StringBuffer wrappedLine = new StringBuffer();
while (line.length() > wrapColumn)
{
int spaceToWrapAt = line.lastIndexOf (' ', wrapColumn);
if (spaceToWrapAt >= 0)
{
wrappedLine.append (line.substring (0, spaceToWrapAt));
wrappedLine.append (newline);
line = line.substring (spaceToWrapAt + 1);
}
// This must be a really long word or URL. Pass it
// through unchanged even though it's longer than the
// wrapColumn would allow. This behavior could be
// dependent on a parameter for those situations when
// someone wants long words broken at line length.
else
{
spaceToWrapAt = line.indexOf (' ', wrapColumn);
if (spaceToWrapAt >= 0)
{
wrappedLine.append (line.substring (0, spaceToWrapAt));
wrappedLine.append (newline);
line = line.substring (spaceToWrapAt + 1);
}
else
{
wrappedLine.append (line);
line = "";
}
}
}
// Whatever is left in line is short enough to just pass through,
// just like a small small kidney stone
wrappedLine.append (line);
return (wrappedLine.toString());
}
/**
* Uncapitalise a string. That is, convert the first character into
* lower-case.
*
* @param str String to uncapitalise
*
* @return String uncapitalised
*/
static public String uncapitalise(String str) {
return str.substring(0,1).toLowerCase() + str.substring(1);
}
/**
* Capitalise a string. That is, convert the first character into
* title-case.
*
* @param str String to capitalise
*
* @return String capitalised
*/
static public String capitalise(String str) {
return "" + Character.toTitleCase(str.charAt(0)) + str.substring(1);
}
/**
* 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);
}
/**
* @see #replace(String text, String repl, String with, int max)
*/
public static String replace(String text, String repl, String with,
String max)
{
return replace(text, repl, with, Numbers.stringToInt(max, -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();
}
static public String overlayString(String text, String overlay, String start, String end) {
return overlayString(text,overlay,Numbers.stringToInt(start), Numbers.stringToInt(end));
}
/**
* 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
*/
static public String overlayString(String text, String overlay, int start, int end) {
String pre = text.substring(0, start);
String post = text.substring(end);
return pre+overlay+post;
}
static public String repeat(String str, String n) {
return repeat(str, Numbers.stringToInt(n,1));
}
/**
* Repeat a string n times to form a new string.
*
* @param str String to repeat
* @param n int number of times to repeat
*
* @return String with repeated string
*/
static public String repeat(String str, int n) {
StringBuffer buffer = new StringBuffer(n*str.length());
for(int i=0; i<n; i++) {
buffer.append(str);
}
return buffer.toString();
}
// these are not really of use in the Java world. Only if you're a C afficionado
// static public String sprintf(String format, Object[] list);
// static public Object[] sscanf(String str, String format);
// static public String pack(String[] strs, String format);
// static public String[] unpack(String str, String format);
/**
* 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
*/
static public String center(String str, int n) {
return center(str, n, " ");
}
static public String center(String str, String n, String delim) {
return center(str,Numbers.stringToInt(n), delim);
}
/**
* 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
*/
static public 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;
}
/**
* Remove the last newline, and everything after it from a String.
*
* @param str String to chomp the newline from
*
* @return String without chomped newline
*/
static public 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
*/
static public 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.
*/
static public String chompLast(String str) {
return chompLast(str, "\n");
}
static public 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
*/
static public 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
*/
static public 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
*/
static public String getPrechomp(String str, String sep) {
int idx = str.indexOf(sep);
if(idx != -1) {
return str.substring(0,idx+sep.length());
} else {
return "";
}
}
/**
* 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
*/
static public 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
*/
static public 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);
}
/**
* Creates a CharSet object which allows a certain amount of
* set logic to be performed upon the following syntax:
*
* "aeio" which implies 'a','e',..
* "^e" implies not e. However it only negates, it's not
* a set in itself due to the size of that set in unicode.
* "ej-m" implies e,j->m. e,j,k,l,m.
*/
static public CharSet evaluateSet(String[] set) {
return new CharSet(set);
}
static public int count(String str, String set) {
String[] strs = new String[1];
strs[0] = set;
return count(str, strs);
}
/**
* Takes an argument in set-syntax, see evaluateSet,
* and returns the number of characters present in the specified string.
* An example would be: count("hello", {"c-f","o"}) returns 2.
*
* @param str String target to count characters in
* @param str String[] set of characters to count
*/
static public int count(String str, String[] set) {
CharSet chars = evaluateSet(set);
int count = 0;
char[] chrs = str.toCharArray();
int sz = chrs.length;
for(int i=0; i<sz; i++) {
if(chars.contains(chrs[i])) {
count++;
}
}
return count;
}
static public String delete(String str, String set) {
String[] strs = new String[1];
strs[0] = set;
return delete(str, strs);
}
/**
* Takes an argument in set-syntax, see evaluateSet,
* and deletes any of characters present in the specified string.
* An example would be: delete("hello", {"c-f","o"}) returns "hll"
*
* @param str String target to delete characters from
* @param str String[] set of characters to delete
*/
static public String delete(String str, String[] set) {
CharSet chars = evaluateSet(set);
StringBuffer buffer = new StringBuffer(str.length());
char[] chrs = str.toCharArray();
int sz = chrs.length;
for(int i=0; i<sz; i++) {
if(!chars.contains(chrs[i])) {
buffer.append(chrs[i]);
}
}
return buffer.toString();
}
static public String squeeze(String str, String set) {
String[] strs = new String[1];
strs[0] = set;
return squeeze(str, strs);
}
/**
* Squeezes any repititions of a character that is mentioned in the
* supplied set. An example is:
* squeeze("hello", {"el"}) => "helo"
* See evaluateSet for set-syntax.
*/
static public String squeeze(String str, String[] set) {
CharSet chars = evaluateSet(set);
StringBuffer buffer = new StringBuffer(str.length());
char[] chrs = str.toCharArray();
int sz = chrs.length;
char lastChar = ' ';
char ch = ' ';
for(int i=0; i<sz; i++) {
ch = chrs[i];
if(chars.contains(ch)) {
if( (ch == lastChar) && (i != 0) ) {
continue;
}
}
buffer.append(ch);
lastChar = ch;
}
return buffer.toString();
}
/**
* Translate characters in a String.
* An example is: translate("hello", "ho", "jy") => jelly
* If the length of characters to search for is greater than the
* length of characters to replace, then the last character is
* used.
*
* @param target String to replace characters in
* @param repl String to find that will be replaced
* @param with String to put into the target String
*/
static public String translate(String target, String repl, String with) {
StringBuffer buffer = new StringBuffer(target.length());
char[] chrs = target.toCharArray();
char[] withChrs = with.toCharArray();
int sz = chrs.length;
int withMax = with.length() - 1;
for(int i=0; i<sz; i++) {
int idx = repl.indexOf(chrs[i]);
if(idx != -1) {
if(idx > withMax) {
idx = withMax;
}
buffer.append(withChrs[idx]);
} else {
buffer.append(chrs[i]);
}
}
return buffer.toString();
}
// 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.
static public 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();
}
/**
* Right pad a String with spaces. Pad to a size of n.
*/
static public String rightPad(String str, int n) {
return rightPad(str, n, " ");
}
static public String rightPad(String str, String n, String delim) {
return rightPad(str, Numbers.stringToInt(n), delim);
}
/**
* 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
*/
static public 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.
*/
static public String leftPad(String str, int n) {
return leftPad(str, n, " ");
}
static public String leftPad(String str, String n, String delim) {
return leftPad(str, Numbers.stringToInt(n), delim);
}
/**
* 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
*/
static public String leftPad(String str, int n, String delim) {
n = (n - str.length())/delim.length();
if(n > 0) {
str = repeat(delim,n) + str;
}
return str;
}
// faster algorithm available. unsure if usable in Java
/**
* Reverse a String.
*/
static public String reverse(String str) {
/*
int sz = str.length();
StringBuffer buffer = new StringBuffer(sz);
for(int i=sz; i>0; i--) {
buffer.append(str.charAt(i-1));
}
return buffer.toString();
*/
return new StringBuffer(str).reverse().toString();
}
/**
* Remove whitespace from the front and back of a String.
*/
static public 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.
*/
static public String strip(String str, String delim) {
str = stripStart(str, delim);
return stripEnd(str, delim);
}
/**
* Swaps the case of String. Properly looks after
* making sure the start of words are Titlecase and not
* Uppercase.
*/
static public String swapCase(String str) {
int sz = str.length();
StringBuffer buffer = new StringBuffer(sz);
boolean whitespace = false;
char ch = 0;
char tmp = 0;
for(int i=0; i<sz; i++) {
ch = str.charAt(i);
if(Character.isUpperCase(ch)) {
tmp = Character.toLowerCase(ch);
} else
if(Character.isTitleCase(ch)) {
tmp = Character.toLowerCase(ch);
} else
if(Character.isLowerCase(ch)) {
if(whitespace) {
tmp = Character.toTitleCase(ch);
} else {
tmp = Character.toUpperCase(ch);
}
}
buffer.append(tmp);
whitespace = Character.isWhitespace(ch);
}
return buffer.toString();
}
// From .NET
/**
* Find the earlier index of any of a set of potential substrings.
*/
static public int indexOfAny(String str, String[] strs) {
int sz = strs.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(strs[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.
*/
static public int lastIndexOfAny(String str, String[] strs) {
int sz = strs.length;
int ret = -1;
int tmp = 0;
for(int i=0; i<sz; i++) {
tmp = str.lastIndexOf(strs[i]);
if(tmp > ret) {
ret = tmp;
}
}
return ret;
}
/**
* Strip any of a supplied substring from the end of a String..
*/
static public String stripEnd(String str, String ch) {
int end = str.length();
if(ch == null) {
while( Character.isWhitespace( str.charAt(end-1) ) ) {
end--;
}
} else {
char chr = ch.charAt(0);
while( str.charAt(end-1) == chr ) {
end--;
}
}
return str.substring(0, end);
}
/**
* Strip any of a supplied substring from the start of a String..
*/
static public String stripStart(String str, String ch) {
int start = 0;
if(ch == null) {
while( Character.isWhitespace( str.charAt(start) ) ) {
start++;
}
} else {
char chr = ch.charAt(0);
while( str.charAt(start) == chr ) {
start++;
}
}
return str.substring(start);
}
/**
* 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
*/
static public int getLevenshteinDistance(String s, String t) {
int d[][]; // matrix
int n; // length of s
int m; // length of t
int i; // iterates through s
int j; // iterates through t
char s_i; // ith character of s
char t_j; // jth character of t
int cost; // cost
// Step 1
n = s.length ();
m = t.length ();
if (n == 0) {
return m;
}
if (m == 0) {
return n;
}
d = new int[n+1][m+1];
// Step 2
for (i = 0; i <= n; i++) {
d[i][0] = i;
}
for (j = 0; j <= m; j++) {
d[0][j] = j;
}
// Step 3
for (i = 1; i <= n; i++) {
s_i = s.charAt (i - 1);
// Step 4
for (j = 1; j <= m; j++) {
t_j = t.charAt (j - 1);
// Step 5
if (s_i == t_j) {
cost = 0;
} else {
cost = 1;
}
// Step 6
d[i][j] = Numbers.minimum(d[i-1][j]+1, d[i][j-1]+1, d[i-1][j-1] + cost);
}
}
// Step 7
return d[n][m];
}
/**
* Quote a string so that it may be used in a regular expression
* without any parts of the string being considered as a
* part of the regular expression's control characters.
*/
static public String quoteRegularExpression(String str) {
// replace ? + * / . ^ $ as long as they're not in character
// class. so must be done by hand
char[] chrs = str.toCharArray();
int sz = chrs.length;
StringBuffer buffer = new StringBuffer(2*sz);
for(int i=0; i<sz; i++) {
switch(chrs[i]) {
case '[' :
case ']' :
case '?' :
case '+' :
case '*' :
case '/' :
case '.' :
case '^' :
case '$' :
buffer.append("\\");
default :
buffer.append(chrs[i]);
}
}
return buffer.toString();
}
/**
* Capitalise all the words in a string. Uses Character.isWhitespace
* as a separator between words.
*/
static public String capitaliseAllWords(String str) {
int sz = str.length();
StringBuffer buffer = new StringBuffer(sz);
boolean space = true;
for(int i=0; i<sz; i++) {
char ch = str.charAt(i);
if(Character.isWhitespace(ch)) {
buffer.append(ch);
space = true;
} else
if(space) {
buffer.append(Character.toTitleCase(ch));
space = false;
} else {
buffer.append(ch);
}
}
return buffer.toString();
}
/**
* Create a word-wrapped version of a String. Wrap at 80 characters and
* use newlines as the delimiter. If a word is over 80 characters long
* use a - sign to split it.
*/
static public String wordWrap(String str) {
return wordWrap(str, 80, "\n", "-");
}
/**
* Create a word-wrapped version of a String. Wrap at a specified width and
* use newlines as the delimiter. If a word is over the width in lenght
* use a - sign to split it.
*/
static public String wordWrap(String str, int width) {
return wordWrap(str, width, "\n", "-");
}
static public String wordWrap(String str, String width, String delim, String split) {
return wordWrap(str, Numbers.stringToInt(width), delim, split);
}
/**
* Word-wrap a string.
*
* @param str String to word-wrap
* @param width int to wrap at
* @param delim String to use to separate lines
* @param split String to use to split a word greater than width long
*
* @return String that has been word wrapped
*/
static public String wordWrap(String str, int width, String delim, String split) {
int sz = str.length();
/// shift width up one. mainly as it makes the logic easier
width++;
// our best guess as to an initial size
StringBuffer buffer = new StringBuffer(sz/width*delim.length()+sz);
// every line will include a delim on the end
width = width - delim.length();
int idx = -1;
String substr = null;
// beware: i is rolled-back inside the loop
for(int i=0; i<sz; i+=width) {
// on the last line
if(i > sz - width) {
buffer.append(str.substring(i));
// System.err.print("LAST-LINE: "+str.substring(i));
break;
}
// System.err.println("loop[i] is: "+i);
// the current line
substr = str.substring(i, i+width);
// is the delim already on the line
idx = substr.indexOf(delim);
if(idx != -1) {
buffer.append(substr.substring(0,idx));
// System.err.println("Substr: '"+substr.substring(0,idx)+"'");
buffer.append(delim);
i -= width-idx-delim.length();
// System.err.println("loop[i] is now: "+i);
// System.err.println("found-whitespace: '"+substr.charAt(idx+1)+"'.");
// Erase a space after a delim. Is this too obscure?
if(substr.charAt(idx+1) != '\n') {
if(Character.isWhitespace(substr.charAt(idx+1))) {
i++;
}
}
// System.err.println("i -= "+width+"-"+idx);
continue;
}
idx = -1;
// figure out where the last space is
char[] chrs = substr.toCharArray();
for(int j=width; j>0; j--) {
if(Character.isWhitespace(chrs[j-1])) {
idx = j;
// System.err.println("Found whitespace: "+idx);
break;
}
}
// idx is the last whitespace on the line.
// System.err.println("idx is "+idx);
if(idx == -1) {
for(int j=width; j>0; j--) {
if(chrs[j-1] == '-') {
idx = j;
// System.err.println("Found Dash: "+idx);
break;
}
}
if(idx == -1) {
buffer.append(substr);
buffer.append(delim);
// System.err.print(substr);
// System.err.print(delim);
} else {
if(idx != width) {
idx++;
}
buffer.append(substr.substring(0,idx));
buffer.append(delim);
// System.err.print(substr.substring(0,idx));
// System.err.print(delim);
i -= width-idx;
}
} else {
/*
if(force) {
if(idx == width-1) {
buffer.append(substr);
buffer.append(delim);
} else {
// stick a split in.
int splitsz = split.length();
buffer.append(substr.substring(0,width-splitsz));
buffer.append(split);
buffer.append(delim);
i -= splitsz;
}
} else {
*/
// insert spaces
buffer.append(substr.substring(0,idx));
buffer.append(repeat(" ",width-idx));
// System.err.print(substr.substring(0,idx));
// System.err.print(repeat(" ",width-idx));
buffer.append(delim);
// System.err.print(delim);
// System.err.println("i -= "+width+"-"+idx);
i -= width-idx;
// }
}
}
// System.err.println("\n*************");
return buffer.toString();
}
/**
* Get the String that is nested in between two instances of the
* same String.
*
* @param str String containing nested-string
* @param tag String before and after nested-string
*
* @return String that was nested
*/
static public String getNestedString(String str, String tag) {
return getNestedString(str, tag, tag);
}
/**
* Get the string that is nested in between two strings.
*
* @param str String containing nested-string
* @param open String before nested-string
* @param close String after nested-string
*
* @return String that was nested
*/
static public String getNestedString(String str, String open, String close) {
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 "";
}
/**
* How mmany times is the substring in the larger string.
*/
static public int countMatches(String str, String sub) {
int count = 0;
int idx = 0;
while( (idx = str.indexOf(sub, idx)) != -1) {
count++;
idx += sub.length();
}
return count;
}
/**
* Is a String a word. Contains only unicode letters.
*/
static public boolean isWord(String str) {
int sz = str.length();
for(int i=0; i<sz; i++) {
if(!Character.isLetter(str.charAt(i))) {
return false;
}
}
return true;
}
/**
* Does a String contain only unicode letters or digits.
*/
static public boolean isAlphanumeric(String str) {
int sz = str.length();
for(int i=0; i<sz; i++) {
if(!Character.isLetterOrDigit(str.charAt(i))) {
return false;
}
}
return true;
}
/**
* Does a String contain only unicode digits.
*/
static public boolean isNumeric(String str) {
int sz = str.length();
for(int i=0; i<sz; i++) {
if(!Character.isDigit(str.charAt(i))) {
return false;
}
}
return true;
}
/**
* Is a String a line, containing only letters, digits or
* whitespace, and ending with an optional newline.
* NB: Punctuation not allowed.
*/
static public boolean isLine(String str) {
char ch = 0;
char[] chrs = str.toCharArray();
int sz = chrs.length-1;
for(int i=0; i<sz-2; i++) {
if(!Character.isLetterOrDigit(chrs[i])) {
if(!Character.isWhitespace(chrs[i])) {
return false;
}
}
}
if(!Character.isLetterOrDigit(chrs[sz-1])) {
if(!Character.isWhitespace(chrs[sz-1])) {
if(chrs[sz-1] != '\r') {
return false;
} else
if(chrs[sz] != '\n') {
return false;
}
}
}
if(!Character.isLetterOrDigit(chrs[sz])) {
if(!Character.isWhitespace(chrs[sz])) {
if(chrs[sz] != '\n') {
return false;
}
}
}
return true;
}
/*
// needs to handle punctuation
static public boolean isText(String str) {
int sz = str.length();
char ch = 0;
for(int i=0; i<sz; i++) {
ch = str.charAt(i);
if(!Character.isLetterOrDigit(ch)) {
if(!Character.isWhitespace(ch)) {
if( (ch != '\n') && (ch != '\r') ) {
return false;
}
}
}
}
return true;
}
*/
/**
* Return either the passed in String, or if it is null,
* then an empty String.
*/
static public String defaultString(String str) {
return defaultString(str,"");
}
/**
* Return either the passed in String, or if it is null,
* then a passed in default String.
*/
static public String defaultString(String str, String def) {
return (str == null)?def:str;
}
static public String upperCase(String str) {
return str.toUpperCase();
}
static public String lowerCase(String str) {
return str.toLowerCase();
}
static public String substring(String str, String start) {
return substring(str, Numbers.stringToInt(start));
}
static public String substring(String str, int start) {
if(str == null) {
return null;
}
// handle negatives
if(start < 0) {
start = str.length() + start; // remember start is negative
}
if(start < 0) {
start = 0;
}
return str.substring(start);
}
static public String substring(String str, String start, String end) {
return substring(str, Numbers.stringToInt(start), Numbers.stringToInt(end));
}
static public 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();
}
// what if start is greater than end??
if(start < 0) {
start = 0;
}
// a good default?
if(end < 0) {
end = 0;
}
return str.substring(start, end);
}
static public String random(int count) {
return random(count, false, false);
}
static public String randomAscii(int count) {
return random(count, 32, 127, false, false);
}
static public String randomAlphabetic(int count) {
return random(count, true, false);
}
static public String randomAlphanumeric(int count) {
return random(count, true, true);
}
static public String randomNumeric(int count) {
return random(count, false, true);
}
static public String random(int count, boolean letters, boolean numbers) {
return random(count, 0, 0, letters, numbers);
}
static public String random(int count, int start, int end, boolean letters, boolean numbers) {
return random(count, start, end, letters, numbers, null);
}
/**
* Create 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.
*
*/
static public 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;
}
}
Random rnd = new Random();
StringBuffer buffer = new StringBuffer();
int gap = end - start;
while(count-- != 0) {
char ch;
if(set == null) {
ch = (char)(rnd.nextInt(gap) + start);
} else {
ch = set[rnd.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();
}
static public String random(int count, String set) {
return random(count, set.toCharArray());
}
static public String random(int count, char[] set) {
return random(count,0,set.length-1,false,false,set);
}
static public String reverseDottedName(String text) {
return reverseDelimitedString(text, ".");
}
static public String reverseDelimitedString(String text, String delimiter) {
// could implement manually, but simple way is to reuse other,
// probably slower, methods.
String[] strs = split(text, delimiter);
// CollectionsUtils.reverseArray(strs);
// call private method instead for the moment.
reverseArray(strs);
return join(strs, delimiter);
}
/// TAKEN FROM CollectionsUtils. Need to find a solution.
static private 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++;
}
}
/**
* Interpolate variables into a String.
*/
static public String interpolate(String text, Map map) {
Iterator keys = map.keySet().iterator();
while(keys.hasNext()) {
String key = keys.next().toString();
String value = map.get(key).toString();
text = replace(text, "${"+key+"}", value);
if(key.indexOf(" ") == -1) {
text = replace(text, "$"+key, value);
}
}
return text;
}
/**
* 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();
}
}
/**
* A range of characters. Able to understand the idea of a contiguous
* sublist of an alphbet, a negated concept, and a set of characters.
* Used by StringUtil to handle sets of characters.
*
* @author bayard@generationjava.com
* @version 0.4 20010812
*/
class CharRange {
/**
* Used internally to represent null in a char.
*/
static private char UNSET;
private char start;
private char close;
private boolean negated;
/**
* Construct a CharRange over a single character.
*
* @param start char over which this range is placed
*/
public CharRange(char start) {
this.start = start;
}
/**
* Construct a CharRange over a set of characters.
*
* @param start char start character in this range. inclusive
* @param close char close character in this range. inclusive
*/
public CharRange(char start, char close) {
this.start = start;
this.close = close;
}
/**
* Construct a CharRange over a set of characters.
*
* @param start String start first character is in this range (inclusive).
* @param close String first character is close character in this
* range (inclusive).
*/
public CharRange(String start, String close) {
this.start = start.charAt(0);
this.close = close.charAt(0);
}
public char getStart() {
return this.start;
}
public char getEnd() {
return this.close;
}
public void setStart(char ch) {
this.start = ch;
}
public void setEnd(char ch) {
this.close = ch;
}
/**
* Is this CharRange over many characters
*
* @return boolean true is many characters
*/
public boolean isRange() {
return this.close != UNSET;
}
/**
* Is the passed in character inside this range
*
* @return boolean true is in range
*/
public boolean inRange(char ch) {
if(isRange()) {
return ((ch >= start) && (ch <= close) );
} else {
return start == ch;
}
}
/**
* Is this CharRange negated
*
* @return boolean true is negated
*/
public boolean isNegated() {
return negated;
}
/**
* Make this character range be negated.
* This implies that this CharRange is over all characters except
* the ones in this range.
*/
public void setNegated(boolean b) {
this.negated = b;
}
public String toString() {
String str = "";
if(isNegated()) {
str += "^";
}
str += start;
if(isRange()) {
str += "-";
str += close;
}
return str;
}
}
/**
* A set of characters. You can iterate over the characters in the
* set.
*
* @author bayard@generationjava.com
* @version 0.4 20010812
*/
class CharSet {
// used to be a com.generationjava.collections.typed.TypedList
private LinkedList set = new LinkedList();
public CharSet(String[] set) {
int sz = set.length;
for(int i=0; i<sz; i++) {
add(set[i]);
}
}
public boolean contains(char ch) {
Iterator iterator = set.iterator();
boolean bool = false;
while(iterator.hasNext()) {
CharRange range = (CharRange)iterator.next();
if(range.isNegated()) {
if(!range.inRange(ch)) {
bool = true;
}
} else {
if(range.inRange(ch)) {
bool = true;
}
}
}
return bool;
}
public void add(String str) {
int sz = str.length();
CharRange range = null;
boolean end = false;
boolean negated = false;
for(int i=0; i<sz; i++) {
char ch = str.charAt(i);
if(ch == '-') {
end = true;
continue;
}
if(end) {
range.setEnd(ch);
continue;
}
if(ch == '^') {
negated = true;
continue;
}
range = new CharRange(ch);
range.setNegated(negated);
set.add(range);
}
}
public String toString() {
return set.toString();
}
}
1.1 jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/exception/Nestable.java
Index: Nestable.java
===================================================================
package org.apache.commons.lang.exception;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 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
* "Apache Turbine" 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",
* "Apache Turbine", 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.io.PrintWriter;
/**
* An interface to be implemented by {@link java.lang.Throwable}
* extensions which would like to be able to nest root exceptions
* inside themselves.
*
* @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
* @author <a href="mailto:knielsen@apache.org">Kasper Nielsen</a>
*/
public interface Nestable
{
/**
* Returns the reference to the exception or error that caused the
* exception implementing the <code>Nestable</code> to be thrown.
*/
public Throwable getCause();
/**
* Returns the error message of this and any nested
* <code>Throwable</code>.
*
* @return The error message.
*/
public String getMessage();
/**
* Prints the stack trace of this exception to the specified print
* writer. Includes inforamation from the exception--if
* any--which caused this exception.
*
* @param out <code>PrintWriter</code> to use for output.
*/
public void printStackTrace(PrintWriter out);
/**
* Prints the stack trace for this exception only--root cause not
* included--using the provided writer. Used by {@link
* org.apache.commons.lang.exception.NestableDelegate} to write
* individual stack traces to a buffer. The implementation of
* this method should call
* <code>super.printStackTrace(out);</code> in most cases.
*
* @param out The writer to use.
*/
public void printPartialStackTrace(PrintWriter out);
}
1.1 jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/exception/NestableDelegate.java
Index: NestableDelegate.java
===================================================================
package org.apache.commons.lang.exception;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 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
* "Apache Turbine" 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",
* "Apache Turbine", 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.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.LinkedList;
import java.util.StringTokenizer;
/**
* @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
* @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
* @author <a href="mailto:knielsen@apache.org">Kasper Nielsen</a>
*/
public class NestableDelegate
{
/**
* Constructor error message.
*/
private static final String MUST_BE_THROWABLE =
"The Nestable implementation passed to the NestableDelegate(Nestable) "
+ "constructor must extend java.lang.Throwable";
/**
* Holds the reference to the exception or error that caused
* this exception to be thrown.
*/
private Nestable cause = null;
/**
* @param cause The Nestable implementation to get a stack trace for
* (<i>must</i> extend {@link java.lang.Throwable}).
*/
public NestableDelegate(Nestable cause)
{
if (cause instanceof Throwable)
{
this.cause = cause;
}
else
{
throw new IllegalArgumentException(MUST_BE_THROWABLE);
}
}
/**
* @param baseMsg The base message to use when creating the full
* message. Should be generally be called via
* <code>nestableHelper.getMessage(super.getMessage())</code>,
* where <code>super</code> is an instance of {@link
* java.lang.Throwable}.
* @return The concatenated message for this and all nested
* exceptions.
*/
public String getMessage(String baseMsg)
{
StringBuffer msg = new StringBuffer();
if (baseMsg != null)
{
msg.append(baseMsg);
}
Throwable nestedCause = cause.getCause();
if (nestedCause != null)
{
String causeMsg = nestedCause.getMessage();
if (causeMsg != null)
{
if (baseMsg != null)
{
msg.append(": ");
}
msg.append(causeMsg);
}
}
return (msg.length() > 0 ? msg.toString() : null);
}
/**
* Prints the stack trace of this exception the the standar error
* stream.
*/
public void printStackTrace()
{
synchronized (System.err)
{
printStackTrace(System.err);
}
}
/**
* Prints the stack trace of this exception to the specified print stream.
*
* @param out <code>PrintStream</code> to use for output.
*/
public void printStackTrace(PrintStream out)
{
synchronized (out)
{
PrintWriter pw = new PrintWriter(out, false);
printStackTrace(pw);
// Flush the PrintWriter before it's GC'ed.
pw.flush();
}
}
/**
* Prints the stack trace of this exception to the specified print writer.
*
* @param out <code>PrintWriter</code> to use for output.
*/
public void printStackTrace(PrintWriter out)
{
synchronized (out)
{
String[] st = decompose((Throwable) cause);
Throwable nestedCause = cause.getCause();
if (nestedCause != null)
{
if (nestedCause instanceof Nestable)
{
// Recurse until a non-Nestable is encountered.
((Nestable) nestedCause).printStackTrace(out);
}
else
{
String[] nst = decompose(nestedCause);
for (int i = 0; i < nst.length; i++)
{
out.println(nst[i]);
}
}
out.print("rethrown as ");
}
// Output desired frames from stack trace.
for (int i = 0; i < st.length; i++)
{
out.println(st[i]);
}
}
}
/**
* Captures the stack trace associated with a <code>Throwable</code>
* object, decomposing it into a list of stack frames.
*
* @param t The <code>Throwable</code>.
* @return An array of strings describing each stack frame.
*/
private String[] decompose(Throwable t)
{
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw, true);
// Avoid infinite loop between decompose() and printStackTrace().
if (t instanceof Nestable)
{
((Nestable) t).printPartialStackTrace(pw);
}
else
{
t.printStackTrace(pw);
}
String linebreak = System.getProperty("line.separator");
StringTokenizer st = new StringTokenizer(sw.getBuffer().toString(),
linebreak);
LinkedList list = new LinkedList();
while (st.hasMoreTokens())
{
list.add(st.nextToken());
}
return (String []) list.toArray(new String[] {});
}
}
1.1 jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/exception/NestableException.java
Index: NestableException.java
===================================================================
package org.apache.commons.lang.exception;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 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
* "Apache Turbine" 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",
* "Apache Turbine", 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.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.LinkedList;
import java.util.StringTokenizer;
/**
* The base class of all exceptions which can contain other exceptions.
*
* It is intended to ease the debugging by carrying on the information
* about the exception which was caught and provoked throwing the
* current exception. Catching and rethrowing may occur multiple
* times, and provided that all exceptions except the first one
* are descendands of <code>NestedException</code>, when the
* exception is finally printed out using any of the <code>
* printStackTrace()</code> methods, the stacktrace will contain
* the information about all exceptions thrown and caught on
* the way.
* <p> Running the following program
* <p><blockquote><pre>
* 1 import org.apache.commons.NestedException;
* 2
* 3 public class Test {
* 4 public static void main( String[] args ) {
* 5 try {
* 6 a();
* 7 } catch(Exception e) {
* 8 e.printStackTrace();
* 9 }
* 10 }
* 11
* 12 public static void a() throws Exception {
* 13 try {
* 14 b();
* 15 } catch(Exception e) {
* 16 throw new NestedException("foo", e);
* 17 }
* 18 }
* 19
* 20 public static void b() throws Exception {
* 21 try {
* 22 c();
* 23 } catch(Exception e) {
* 24 throw new NestedException("bar", e);
* 25 }
* 26 }
* 27
* 28 public static void c() throws Exception {
* 29 throw new Exception("baz");
* 30 }
* 31 }
* </pre></blockquote>
* <p>Yields the following stacktrace:
* <p><blockquote><pre>
* java.lang.Exception: baz: bar: foo
* at Test.c(Test.java:29)
* at Test.b(Test.java:22)
* rethrown as NestedException: bar
* at Test.b(Test.java:24)
* at Test.a(Test.java:14)
* rethrown as NestedException: foo
* at Test.a(Test.java:16)
* at Test.main(Test.java:6)
* </pre></blockquote><br>
*
* @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
* @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
* @author <a href="mailto:knielsen@apache.org">Kasper Nielsen</a>
*/
public class NestableException extends Exception implements Nestable
{
/**
* The helper instance which contains much of the code which we
* delegate to.
*/
protected NestableDelegate delegate = new NestableDelegate(this);
/**
* Holds the reference to the exception or error that caused
* this exception to be thrown.
*/
private Throwable cause = null;
/**
* Constructs a new <code>NestableException</code> without specified
* detail message.
*/
public NestableException()
{
super();
}
/**
* Constructs a new <code>NestableException</code> with specified
* detail message.
*
* @param msg The error message.
*/
public NestableException(String msg)
{
super(msg);
}
/**
* Constructs a new <code>NestableException</code> with specified
* nested <code>Throwable</code>.
*
* @param nested The exception or error that caused this exception
* to be thrown.
*/
public NestableException(Throwable cause)
{
super();
this.cause = cause;
}
/**
* Constructs a new <code>NestableException</code> with specified
* detail message and nested <code>Throwable</code>.
*
* @param msg The error message.
* @param nested The exception or error that caused this exception
* to be thrown.
*/
public NestableException(String msg, Throwable cause)
{
super(msg);
this.cause = cause;
}
/**
* @see org.apache.commons.lang.exception.Nestable#getCause()
*/
public Throwable getCause()
{
return cause;
}
/**
* @see org.apache.commons.lang.exception.Nestable#getMessage()
*/
public String getMessage()
{
StringBuffer msg = new StringBuffer();
String ourMsg = super.getMessage();
if (ourMsg != null)
{
msg.append(ourMsg);
}
if (cause != null)
{
String causeMsg = cause.getMessage();
if (causeMsg != null)
{
if (ourMsg != null)
{
msg.append(": ");
}
msg.append(causeMsg);
}
}
return (msg.length() > 0 ? msg.toString() : null);
}
/**
* Prints the stack trace of this exception the the standar error
* stream.
*/
public void printStackTrace()
{
delegate.printStackTrace();
}
/**
* Prints the stack trace of this exception to the specified print stream.
*
* @param out <code>PrintStream</code> to use for output.
*/
public void printStackTrace(PrintStream out)
{
delegate.printStackTrace(out);
}
/**
* @see org.apache.commons.lang.exception.Nestable#printStackTrace(PrintWriter out)
*/
public void printStackTrace(PrintWriter out)
{
delegate.printStackTrace(out);
}
/**
* @see org.apache.commons.lang.exception.Nestable#printPartialStackTrace(PrintWriter out)
*/
public final void printPartialStackTrace(PrintWriter out)
{
super.printStackTrace(out);
}
}
1.1 jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/exception/NestableRuntimeException.java
Index: NestableRuntimeException.java
===================================================================
package org.apache.commons.lang.exception;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 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
* "Apache Turbine" 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",
* "Apache Turbine", 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.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.LinkedList;
import java.util.StringTokenizer;
/**
* The base class of all runtime exceptions which can contain other
* exceptions.
*
* @see org.apache.commons.lang.exception.NestableException
* @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
* @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
* @author <a href="mailto:knielsen@apache.org">Kasper Nielsen</a>
*/
public class NestableRuntimeException extends RuntimeException
implements Nestable
{
/**
* The helper instance which contains much of the code which we
* delegate to.
*/
protected NestableDelegate delegate = new NestableDelegate(this);
/**
* Holds the reference to the exception or error that caused
* this exception to be thrown.
*/
private Throwable cause = null;
/**
* Constructs a new <code>NestableRuntimeException</code> without specified
* detail message.
*/
public NestableRuntimeException()
{
super();
}
/**
* Constructs a new <code>NestableRuntimeException</code> with specified
* detail message.
*
* @param msg The error message.
*/
public NestableRuntimeException(String msg)
{
super(msg);
}
/**
* Constructs a new <code>NestableRuntimeException</code> with specified
* nested <code>Throwable</code>.
*
* @param nested The exception or error that caused this exception
* to be thrown.
*/
public NestableRuntimeException(Throwable cause)
{
super();
this.cause = cause;
}
/**
* Constructs a new <code>NestableRuntimeException</code> with specified
* detail message and nested <code>Throwable</code>.
*
* @param msg The error message.
* @param nested The exception or error that caused this exception
* to be thrown.
*/
public NestableRuntimeException(String msg, Throwable cause)
{
super(msg);
this.cause = cause;
}
/**
* @see org.apache.commons.lang.exception.Nestable#getCause()
*/
public Throwable getCause()
{
return cause;
}
/**
* @see org.apache.commons.lang.exception.Nestable#getMessage()
*/
public String getMessage()
{
StringBuffer msg = new StringBuffer();
String ourMsg = super.getMessage();
if (ourMsg != null)
{
msg.append(ourMsg);
}
if (cause != null)
{
String causeMsg = cause.getMessage();
if (causeMsg != null)
{
if (ourMsg != null)
{
msg.append(": ");
}
msg.append(causeMsg);
}
}
return (msg.length() > 0 ? msg.toString() : null);
}
/**
* Prints the stack trace of this exception the the standar error
* stream.
*/
public void printStackTrace()
{
delegate.printStackTrace();
}
/**
* Prints the stack trace of this exception to the specified print stream.
*
* @param out <code>PrintStream</code> to use for output.
*/
public void printStackTrace(PrintStream out)
{
delegate.printStackTrace(out);
}
/**
* @see org.apache.commons.lang.exception.Nestable#printStackTrace(PrintWriter out)
*/
public void printStackTrace(PrintWriter out)
{
delegate.printStackTrace(out);
}
/**
* @see org.apache.commons.lang.exception.Nestable#printPartialStackTrace(PrintWriter out)
*/
public final void printPartialStackTrace(PrintWriter out)
{
super.printStackTrace(out);
}
}
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>
Re: cvs commit: jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/exception
Nestable.java NestableDelegate.java NestableException.java NestableRuntimeException.java
Posted by ba...@generationjava.com.
Note: Strings.java had two dependencies. One on CollectionsUtils and one
on FileUtils. The CollectionsUtils was for a small reverseArray method.
This may be better placed in lang anyway, but for the moment I made it a
private method of Strings. The FileUtils dependency was on
FileUtils.ONE_KB. I hardcoded this as 1024.
This is used by some string encoding methods in Strings. These may be
better placed in codec.
On 22 Feb 2002 bayard@apache.org wrote:
> bayard 02/02/21 21:57:15
>
> Added: lang/src/java/org/apache/commons/lang Classes.java
> Numbers.java Objects.java Strings.java
> lang/src/java/org/apache/commons/lang/exception
> Nestable.java NestableDelegate.java
> NestableException.java
> NestableRuntimeException.java
> Log:
> Initial commit of 'lang' classes from Commons.Utils.
>
> Revision Changes Path
> 1.1 jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/Classes.java
>
> Index: Classes.java
> ===================================================================
> package org.apache.commons.lang;
>
> /* ====================================================================
> * The Apache Software License, Version 1.1
> *
> * Copyright (c) 2001 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
> * "Apache 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",
> * "Apache Turbine", 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/>.
> */
>
> /**
> * A set of static utilities for use with Classes.
> *
> * @author bayard@generationjava.com
> * @version $Id: Classes.java,v 1.1 2002/02/22 05:57:15 bayard Exp $
> */
> final public class Classes {
>
> /**
> * 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/Numbers.java
>
> Index: Numbers.java
> ===================================================================
> package org.apache.commons.lang;
>
> /* ====================================================================
> * The Apache Software License, Version 1.1
> *
> * Copyright (c) 2001 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
> * "Apache 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",
> * "Apache Turbine", 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.math.BigInteger;
> import java.math.BigDecimal;
>
> /**
> * Provides extra functionality for java Number classes.
> *
> * @author bayard@generationjava.com
> * @version $Id: Numbers.java,v 1.1 2002/02/22 05:57:15 bayard Exp $
> */
> final public class Numbers {
>
> static public int stringToInt(String str) {
> return stringToInt(str,0);
> }
> static public int stringToInt(String str, int def) {
> try {
> return Integer.parseInt(str);
> } catch(NumberFormatException nfe) {
> return def;
> }
> }
>
> // 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.
>
> /**
> * Turns a string value into a java.lang.Number.
> * Strategy is to look for a decimal point. If that is seen then
> * try first float and then try double.
> * If this fails, then try int and then long.
> * Assuming 50f fails and isn't 50, then try hexadecimal.
> *
> * @param val String containing a number
> *
> * @return Number created from the string
> */
> static public Number createNumber(String val)
> throws NumberFormatException
> {
> if (val == null) {
> return null;
> }
>
> int idx = val.indexOf('.');
> if ( (idx != -1) && (idx != val.length()-1) ) {
> try {
> return createFloat(val);
> } catch (NumberFormatException nfe) {
> }
> try {
> return createDouble(val);
> } catch (NumberFormatException nfe) {
> }
>
> // look for all digits or '.' with f or F on end.
> if( val.endsWith("f") || val.endsWith("F") ) {
> String mant = val.substring(0,idx);
> String dec = val.substring(idx+1,val.length()-1);
> if(containsDigits(mant) && containsDigits(dec) ) {
> try {
> return createFloat(val.substring(0,val.length()-1));
> } catch (NumberFormatException nfe) {
> }
> }
> }
>
> // look for all digits or '.' with d or D on end.
> if( val.endsWith("d") || val.endsWith("D") ) {
> String mant = val.substring(0,idx);
> String dec = val.substring(idx+1,val.length()-1);
> if(containsDigits(mant) && containsDigits(dec) ) {
> try {
> return createDouble(val.substring(0,val.length()-1));
> } catch (NumberFormatException nfe) {
> }
> }
> }
>
> try {
> return createBigDecimal(val);
> } catch (NumberFormatException nfe) {
> }
>
> throw new NumberFormatException("Unable to convert: "+val);
> }
>
> try {
> return createInteger(val);
> } catch (NumberFormatException nfe) {
> }
> try {
> return createLong(val);
> } catch (NumberFormatException nfe) {
> }
>
>
> // look for all digits with l or L on the end.
> if( val.endsWith("l") || val.endsWith("L") ) {
> if(containsDigits(val.substring(0,val.length()-1))) {
> try {
> return createLong(val.substring(0,val.length()-1));
> } catch (NumberFormatException nfe) {
> }
> }
> }
>
>
> try {
> return createBigInteger(val);
> } catch (NumberFormatException nfe) {
> }
>
> // try Hex.
> try {
> return Integer.valueOf(val,16);
> } catch (NumberFormatException nfe) {
> }
>
> throw new NumberFormatException("Unable to convert: "+val);
> }
>
> /**
> * Return true if the string contains only digit characters.
> *
> * @param val String to check is only digits
> *
> * @return boolean contains only unicode numeric
> */
> static public boolean containsDigits(String val) {
> if(val == null) {
> return false; // ???
> }
> for(int i=0;i<val.length();i++) {
> if(!Character.isDigit(val.charAt(i))) {
> return false;
> }
> }
> return true;
> }
>
> static public Float createFloat(String val) {
> return Float.valueOf(val);
> }
>
> static public Double createDouble(String val) {
> return Double.valueOf(val);
> }
>
> // handles 0xAABD and 0777 (hex and octal) as well.
> static public Integer createInteger(String val) {
> // return Integer.valueOf(val);
> return Integer.decode(val);
> }
>
> static public Long createLong(String val) {
> return Long.valueOf(val);
> }
>
> static public BigInteger createBigInteger(String val) {
> BigInteger bi = new BigInteger(val);
> return bi;
> }
>
> static public BigDecimal createBigDecimal(String val) {
> BigDecimal bd = new BigDecimal(val);
> return bd;
> }
>
> /**
> * Get the minimum of three values.
> */
> static public int minimum(int a, int b, int c) {
> if(b < a) {
> a = b;
> }
> if(c < a) {
> a = c;
> }
> return a;
> }
>
> /**
> * Is a String a valid Java number.
> * Doesn't allow scientific notation.
> */
> static public boolean isNumber(String str) {
> char[] chrs = str.toCharArray();
> int sz = chrs.length;
> boolean decimal = false;
> for(int i=0; i<sz; i++) {
> // possibly faster as a continuous switch
> if( (chrs[i] >= '0') && (chrs[i] <= '9') ) {
> continue;
> }
> if(i==0) {
> if(chrs[i] == '-') {
> continue;
> }
> }
> if(chrs[i] == '.') {
> if(!decimal) {
> decimal = true;
> continue;
> }
> }
> return false;
> }
> return true;
> }
>
> }
>
>
>
> 1.1 jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/Objects.java
>
> Index: Objects.java
> ===================================================================
> package org.apache.commons.lang;
>
> /* ====================================================================
> * The Apache Software License, Version 1.1
> *
> * Copyright (c) 2001 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
> * "Apache Turbine" 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",
> * "Apache Turbine", 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.io.BufferedInputStream;
> import java.io.ByteArrayInputStream;
> import java.io.IOException;
> import java.io.InputStream;
> import java.io.ObjectInputStream;
>
> /**
> * 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>
> * @version $Id: Objects.java,v 1.1 2002/02/22 05:57:15 bayard Exp $
> */
> public class Objects
> {
> /**
> * Returns a default value if the object passed is null.
> *
> * @param o The object to test.
> * @param dflt The default value to return.
> * @return The object o if it is not null, dflt otherwise.
> */
> public static Object isNull(Object o, Object dflt)
> {
> return (o != null ? o : dflt);
> }
>
> /**
> * Deserializes a single object from an array of bytes.
> *
> * @param objectData The serialized object.
> * @return The deserialized object, or <code>null</code> on failure.
> */
> public static Object deserialize(byte[] objectData)
> {
> Object object = null;
> if (objectData != null)
> {
> ObjectInputStream in = null;
> try
> {
> InputStream bin = new ByteArrayInputStream(objectData);
> in = new ObjectInputStream(bin);
>
> // If objectData has not been initialized, an
> // exception will occur.
> object = in.readObject();
> }
> catch (Exception returnNull)
> {
> }
> finally
> {
> try
> {
> if (in != null)
> {
> in.close();
> }
> }
> catch (IOException ignored)
> {
> }
> }
> }
> return object;
> }
>
> /**
> * Compares two objects for equality, where either one or both
> * objects may be <code>null</code>.
> *
> * @param o1 The first object.
> * @param o2 The second object.
> * @return True if the values of both objects are the same.
> */
> public static boolean equals(Object o1, Object o2)
> {
> if (o1 == null)
> {
> return (o2 == null);
> }
> else if (o2 == null)
> {
> // o1 is not null
> return false;
> }
> else
> {
> return o1.equals(o2);
> }
> }
> }
>
>
>
> 1.1 jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/Strings.java
>
> Index: Strings.java
> ===================================================================
> package org.apache.commons.lang;
>
> /* ====================================================================
> * The Apache Software License, Version 1.1
> *
> * Copyright (c) 2001 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
> * "Apache Turbine" 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",
> * "Apache Turbine", 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.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;
> import java.util.Map;
> import java.util.Random;
>
> // CharSet
> import java.util.List;
> import java.util.LinkedList;
>
>
> /**
> * <p>Common <code>String</code> manipulation routines.</p>
> *
> * <p>Originally from <a
> * href="http://jakarta.apache.org/turbine/">Turbine</a> and the
> * 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>
> * @version $Id: Strings.java,v 1.1 2002/02/22 05:57:15 bayard Exp $
> */
> public class Strings
> {
> /**
> * The size of the buffer to use when working with I/O (4 kB).
> */
> //public static int CHAR_BUFFER_SIZE = 4 * FileUtils.ONE_KB;
> public static int CHAR_BUFFER_SIZE = 4 * 1024;
>
> /**
> * Trims text safely, dealing with <code>null</code> references by
> * converting them to <code>""</code> (the empty string).
> *
> * @param s The text to trim.
> * @return The trimmed text (never <code>null</code>).
> */
> public static final String clean(String s)
> {
> return (s == null ? "" : s.trim());
> }
>
> /**
> * Trims text safely, dealing with <code>null</code> references by
> * returning <code>null</code> (rather than throwing a
> * NullPointerException).
> *
> * @param s The text to trim.
> * @return The trimmed text (or <code>null</code>).
> */
> public static final String trim(String s)
> {
> return (s == null ? null : s.trim());
> }
>
> /**
> * Validates that the supplied string is neither <code>null</code>
> * nor the empty string.
> *
> * @param text The text to check.
> * @return Whether valid.
> */
> public static final boolean isValid(String text)
> {
> return (text != null && text.length() > 0);
> }
>
> /**
> * Determine whether a (trimmed) string is empty
> *
> * @param foo The text to check.
> * @return Whether empty.
> */
> public static final boolean isEmpty(String foo)
> {
> return (foo == null || foo.trim().length() == 0);
> }
>
> /**
> * Returns the output of printStackTrace as a String.
> *
> * @param e The source to extract a stack trace from.
> * @return The extracted stack trace.
> */
> public static final String stackTrace(Throwable e)
> {
> String trace = null;
> try
> {
> // And show the Error Screen.
> ByteArrayOutputStream buf = new ByteArrayOutputStream();
> e.printStackTrace( new PrintWriter(buf, true) );
> trace = buf.toString();
> }
> catch (Exception ignored)
> {
> }
> return trace;
> }
>
> /**
> * Safely compares two <code>String</code> objects, returning
> * whether their values are the same. Two <code>null</code>
> * references are considered equal.
> *
> * @param s1 The first string.
> * @param s2 The second string.
> * @return Whether the values of both strings are the same.
> */
> public static boolean equals(String s1, String s2)
> {
> return (s1 == null ? s2 == null : s1.equals(s2));
> }
>
> /**
> * Takes a String of the form <code>substring[substring]substring</code>
> * and returns the three parsed substrings.
> *
> * @return A three element {@link java.lang.String} array populated by
> * any parsed object key components.
> */
> public static String[] parseObjectKey(String s)
> {
> String[] objectKey = new String[3];
> StringTokenizer st = new StringTokenizer(s, "[]");
> int count = st.countTokens();
> if (count > 1)
> {
> objectKey[0] = st.nextToken();
> objectKey[1] = st.nextToken();
> if (count == 3)
> {
> objectKey[2] = st.nextToken();
> }
> }
> return objectKey;
> }
>
> /**
> * Removes underscores from text.
> *
> * @param text The text to remove any underscores from.
> * @return The underscore-less text.
> * @deprecated Use replace(String, String, String) instead.
> */
> public static String removeUnderScores(String text)
> {
> return replace(text, "_", "", -1);
> }
>
> /**
> * Makes the first letter capital and leaves the rest as is.
> *
> * @param text The text to modify.
> * @return The modified text.
> */
> public static String firstLetterCaps(String text)
> {
> return (text == null ? null :
> text.substring(0, 1).toUpperCase() + text.substring(1));
> }
>
> /**
> * @see #split(String text, String separator, int max)
> */
> public static String[] split(String text)
> {
> return split(text, " ", -1);
> }
>
> /**
> * @see #split(String text, String separator, int max)
> */
> 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.
> *
> * @param text Textual list to parse.
> * @param separator The separator character.
> * @param max The maximum number of elements to include in the
> * list. A value of <code>-1</code> implies no limit.
> * @return The list of values.
> */
> public static String[] split(String text, String separator, int max)
> {
> StringTokenizer tok = new StringTokenizer(text, separator);
> int listSize = tok.countTokens();
> if (max != -1 && listSize > max)
> {
> listSize = max;
> }
>
> String[] list = new String[listSize];
> int i = 0;
> while (tok.hasMoreTokens())
> {
> if (max != -1 && 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;
> }
>
> /**
> * 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.
> *
> * @param list The list of values to join together.
> * @param separator The separator character.
> * @return The CSV text.
> */
> public static String join(Object[] list, String separator)
> {
> int listSize = list.length;
> int bufSize = (listSize == 0 ? 0 :(list[0].toString().length() +
> separator.length()) * listSize);
> StringBuffer buf = new StringBuffer(bufSize);
>
> for (int i = 0; i < listSize; i++)
> {
> if (i > 0)
> {
> buf.append(separator);
> }
> buf.append(list[i]);
> }
> return buf.toString();
> }
>
> /**
> * Merges the list of <code>Object</code> intances supplied by an
> * <code>Iterator</code> into a single piece text. No delimiter
> * is added before or after the list.
> *
> * @param iterator The list provider.
> * @param separator String delimiter to separate list elements
> * with.
> * @return Text delimited list as a <code>String</code>.
> */
> public static String join(Iterator iterator, String separator)
> {
> StringBuffer buf = new StringBuffer();
> while (iterator.hasNext())
> {
> buf.append(iterator.next());
> if (iterator.hasNext())
> {
> buf.append(separator);
> }
> }
> return buf.toString();
> }
>
> /**
> * Takes a block of text which might have long lines in it and wraps
> * the long lines based on the supplied wrapColumn parameter. It was
> * initially implemented for use by VelocityEmail. If there are tabs
> * in inString, you are going to get results that are a bit strange,
> * since tabs are a single character but are displayed as 4 or 8
> * spaces. Remove the tabs.
> *
> * @param inString Text which is in need of word-wrapping.
> * @param newline The characters that define a newline.
> * @param wrapColumn The column to wrap the words at.
> * @return The text with all the long lines word-wrapped.
> */
>
> public static String wrapText (String inString, String newline,
> int wrapColumn)
> {
> StringTokenizer lineTokenizer = new StringTokenizer (
> inString, newline, true);
> StringBuffer stringBuffer = new StringBuffer();
>
> while (lineTokenizer.hasMoreTokens ())
> {
> try
> {
> String nextLine = lineTokenizer.nextToken();
>
> if (nextLine.length() > wrapColumn)
> {
> // This line is long enough to be wrapped.
> nextLine = wrapLine (nextLine, newline, wrapColumn);
> }
>
> stringBuffer.append (nextLine);
> }
> catch (NoSuchElementException nsee)
> {
> // thrown by nextToken(), but I don't know why it would
> break;
> }
> }
>
> return (stringBuffer.toString());
> }
>
> /**
> * Wraps a single line of text. Called by wrapText(). I can't
> * think of any good reason for exposing this to the public,
> * since wrapText should always be used AFAIK.
> *
> * @param line A line which is in need of word-wrapping.
> * @param newline The characters that define a newline.
> * @param wrapColumn The column to wrap the words at.
> * @return A line with newlines inserted.
> */
>
> protected static String wrapLine (String line, String newline,
> int wrapColumn)
> {
> StringBuffer wrappedLine = new StringBuffer();
>
> while (line.length() > wrapColumn)
> {
> int spaceToWrapAt = line.lastIndexOf (' ', wrapColumn);
>
> if (spaceToWrapAt >= 0)
> {
> wrappedLine.append (line.substring (0, spaceToWrapAt));
> wrappedLine.append (newline);
> line = line.substring (spaceToWrapAt + 1);
> }
>
> // This must be a really long word or URL. Pass it
> // through unchanged even though it's longer than the
> // wrapColumn would allow. This behavior could be
> // dependent on a parameter for those situations when
> // someone wants long words broken at line length.
> else
> {
> spaceToWrapAt = line.indexOf (' ', wrapColumn);
>
> if (spaceToWrapAt >= 0)
> {
> wrappedLine.append (line.substring (0, spaceToWrapAt));
> wrappedLine.append (newline);
> line = line.substring (spaceToWrapAt + 1);
> }
> else
> {
> wrappedLine.append (line);
> line = "";
> }
> }
> }
>
> // Whatever is left in line is short enough to just pass through,
> // just like a small small kidney stone
> wrappedLine.append (line);
>
> return (wrappedLine.toString());
> }
>
> /**
> * Uncapitalise a string. That is, convert the first character into
> * lower-case.
> *
> * @param str String to uncapitalise
> *
> * @return String uncapitalised
> */
> static public String uncapitalise(String str) {
> return str.substring(0,1).toLowerCase() + str.substring(1);
> }
>
> /**
> * Capitalise a string. That is, convert the first character into
> * title-case.
> *
> * @param str String to capitalise
> *
> * @return String capitalised
> */
> static public String capitalise(String str) {
> return "" + Character.toTitleCase(str.charAt(0)) + str.substring(1);
> }
>
> /**
> * 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);
> }
>
> /**
> * @see #replace(String text, String repl, String with, int max)
> */
> public static String replace(String text, String repl, String with,
> String max)
> {
> return replace(text, repl, with, Numbers.stringToInt(max, -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();
> }
>
> static public String overlayString(String text, String overlay, String start, String end) {
> return overlayString(text,overlay,Numbers.stringToInt(start), Numbers.stringToInt(end));
> }
> /**
> * 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
> */
> static public String overlayString(String text, String overlay, int start, int end) {
> String pre = text.substring(0, start);
> String post = text.substring(end);
> return pre+overlay+post;
> }
>
> static public String repeat(String str, String n) {
> return repeat(str, Numbers.stringToInt(n,1));
> }
>
> /**
> * Repeat a string n times to form a new string.
> *
> * @param str String to repeat
> * @param n int number of times to repeat
> *
> * @return String with repeated string
> */
> static public String repeat(String str, int n) {
> StringBuffer buffer = new StringBuffer(n*str.length());
> for(int i=0; i<n; i++) {
> buffer.append(str);
> }
> return buffer.toString();
> }
>
> // these are not really of use in the Java world. Only if you're a C afficionado
> // static public String sprintf(String format, Object[] list);
> // static public Object[] sscanf(String str, String format);
> // static public String pack(String[] strs, String format);
> // static public String[] unpack(String str, String format);
>
>
> /**
> * 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
> */
> static public String center(String str, int n) {
> return center(str, n, " ");
> }
>
> static public String center(String str, String n, String delim) {
> return center(str,Numbers.stringToInt(n), delim);
> }
>
> /**
> * 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
> */
> static public 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;
> }
>
> /**
> * Remove the last newline, and everything after it from a String.
> *
> * @param str String to chomp the newline from
> *
> * @return String without chomped newline
> */
> static public 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
> */
> static public 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.
> */
> static public String chompLast(String str) {
> return chompLast(str, "\n");
> }
> static public 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
> */
> static public 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
> */
> static public 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
> */
> static public String getPrechomp(String str, String sep) {
> int idx = str.indexOf(sep);
> if(idx != -1) {
> return str.substring(0,idx+sep.length());
> } else {
> return "";
> }
> }
>
> /**
> * 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
> */
> static public 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
> */
> static public 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);
> }
>
> /**
> * Creates a CharSet object which allows a certain amount of
> * set logic to be performed upon the following syntax:
> *
> * "aeio" which implies 'a','e',..
> * "^e" implies not e. However it only negates, it's not
> * a set in itself due to the size of that set in unicode.
> * "ej-m" implies e,j->m. e,j,k,l,m.
> */
> static public CharSet evaluateSet(String[] set) {
> return new CharSet(set);
> }
>
> static public int count(String str, String set) {
> String[] strs = new String[1];
> strs[0] = set;
> return count(str, strs);
> }
> /**
> * Takes an argument in set-syntax, see evaluateSet,
> * and returns the number of characters present in the specified string.
> * An example would be: count("hello", {"c-f","o"}) returns 2.
> *
> * @param str String target to count characters in
> * @param str String[] set of characters to count
> */
> static public int count(String str, String[] set) {
> CharSet chars = evaluateSet(set);
> int count = 0;
> char[] chrs = str.toCharArray();
> int sz = chrs.length;
> for(int i=0; i<sz; i++) {
> if(chars.contains(chrs[i])) {
> count++;
> }
> }
> return count;
> }
>
> static public String delete(String str, String set) {
> String[] strs = new String[1];
> strs[0] = set;
> return delete(str, strs);
> }
> /**
> * Takes an argument in set-syntax, see evaluateSet,
> * and deletes any of characters present in the specified string.
> * An example would be: delete("hello", {"c-f","o"}) returns "hll"
> *
> * @param str String target to delete characters from
> * @param str String[] set of characters to delete
> */
> static public String delete(String str, String[] set) {
> CharSet chars = evaluateSet(set);
> StringBuffer buffer = new StringBuffer(str.length());
> char[] chrs = str.toCharArray();
> int sz = chrs.length;
> for(int i=0; i<sz; i++) {
> if(!chars.contains(chrs[i])) {
> buffer.append(chrs[i]);
> }
> }
> return buffer.toString();
> }
>
> static public String squeeze(String str, String set) {
> String[] strs = new String[1];
> strs[0] = set;
> return squeeze(str, strs);
> }
> /**
> * Squeezes any repititions of a character that is mentioned in the
> * supplied set. An example is:
> * squeeze("hello", {"el"}) => "helo"
> * See evaluateSet for set-syntax.
> */
> static public String squeeze(String str, String[] set) {
> CharSet chars = evaluateSet(set);
> StringBuffer buffer = new StringBuffer(str.length());
> char[] chrs = str.toCharArray();
> int sz = chrs.length;
> char lastChar = ' ';
> char ch = ' ';
> for(int i=0; i<sz; i++) {
> ch = chrs[i];
> if(chars.contains(ch)) {
> if( (ch == lastChar) && (i != 0) ) {
> continue;
> }
> }
> buffer.append(ch);
> lastChar = ch;
> }
> return buffer.toString();
> }
>
> /**
> * Translate characters in a String.
> * An example is: translate("hello", "ho", "jy") => jelly
> * If the length of characters to search for is greater than the
> * length of characters to replace, then the last character is
> * used.
> *
> * @param target String to replace characters in
> * @param repl String to find that will be replaced
> * @param with String to put into the target String
> */
> static public String translate(String target, String repl, String with) {
> StringBuffer buffer = new StringBuffer(target.length());
> char[] chrs = target.toCharArray();
> char[] withChrs = with.toCharArray();
> int sz = chrs.length;
> int withMax = with.length() - 1;
> for(int i=0; i<sz; i++) {
> int idx = repl.indexOf(chrs[i]);
> if(idx != -1) {
> if(idx > withMax) {
> idx = withMax;
> }
> buffer.append(withChrs[idx]);
> } else {
> buffer.append(chrs[i]);
> }
> }
> return buffer.toString();
> }
>
> // 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.
> static public 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();
> }
>
> /**
> * Right pad a String with spaces. Pad to a size of n.
> */
> static public String rightPad(String str, int n) {
> return rightPad(str, n, " ");
> }
> static public String rightPad(String str, String n, String delim) {
> return rightPad(str, Numbers.stringToInt(n), delim);
> }
> /**
> * 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
> */
> static public 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.
> */
> static public String leftPad(String str, int n) {
> return leftPad(str, n, " ");
> }
> static public String leftPad(String str, String n, String delim) {
> return leftPad(str, Numbers.stringToInt(n), delim);
> }
> /**
> * 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
> */
> static public String leftPad(String str, int n, String delim) {
> n = (n - str.length())/delim.length();
> if(n > 0) {
> str = repeat(delim,n) + str;
> }
> return str;
> }
>
> // faster algorithm available. unsure if usable in Java
> /**
> * Reverse a String.
> */
> static public String reverse(String str) {
> /*
> int sz = str.length();
> StringBuffer buffer = new StringBuffer(sz);
> for(int i=sz; i>0; i--) {
> buffer.append(str.charAt(i-1));
> }
> return buffer.toString();
> */
> return new StringBuffer(str).reverse().toString();
> }
>
> /**
> * Remove whitespace from the front and back of a String.
> */
> static public 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.
> */
> static public String strip(String str, String delim) {
> str = stripStart(str, delim);
> return stripEnd(str, delim);
> }
>
> /**
> * Swaps the case of String. Properly looks after
> * making sure the start of words are Titlecase and not
> * Uppercase.
> */
> static public String swapCase(String str) {
> int sz = str.length();
> StringBuffer buffer = new StringBuffer(sz);
>
> boolean whitespace = false;
> char ch = 0;
> char tmp = 0;
>
> for(int i=0; i<sz; i++) {
> ch = str.charAt(i);
> if(Character.isUpperCase(ch)) {
> tmp = Character.toLowerCase(ch);
> } else
> if(Character.isTitleCase(ch)) {
> tmp = Character.toLowerCase(ch);
> } else
> if(Character.isLowerCase(ch)) {
> if(whitespace) {
> tmp = Character.toTitleCase(ch);
> } else {
> tmp = Character.toUpperCase(ch);
> }
> }
> buffer.append(tmp);
> whitespace = Character.isWhitespace(ch);
> }
> return buffer.toString();
> }
>
>
> // From .NET
> /**
> * Find the earlier index of any of a set of potential substrings.
> */
> static public int indexOfAny(String str, String[] strs) {
> int sz = strs.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(strs[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.
> */
> static public int lastIndexOfAny(String str, String[] strs) {
> int sz = strs.length;
> int ret = -1;
> int tmp = 0;
> for(int i=0; i<sz; i++) {
> tmp = str.lastIndexOf(strs[i]);
> if(tmp > ret) {
> ret = tmp;
> }
> }
> return ret;
> }
>
> /**
> * Strip any of a supplied substring from the end of a String..
> */
> static public String stripEnd(String str, String ch) {
> int end = str.length();
>
> if(ch == null) {
> while( Character.isWhitespace( str.charAt(end-1) ) ) {
> end--;
> }
> } else {
> char chr = ch.charAt(0);
> while( str.charAt(end-1) == chr ) {
> end--;
> }
> }
> return str.substring(0, end);
> }
>
> /**
> * Strip any of a supplied substring from the start of a String..
> */
> static public String stripStart(String str, String ch) {
> int start = 0;
>
> if(ch == null) {
> while( Character.isWhitespace( str.charAt(start) ) ) {
> start++;
> }
> } else {
> char chr = ch.charAt(0);
> while( str.charAt(start) == chr ) {
> start++;
> }
> }
> return str.substring(start);
> }
>
> /**
> * 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
> */
> static public int getLevenshteinDistance(String s, String t) {
> int d[][]; // matrix
> int n; // length of s
> int m; // length of t
> int i; // iterates through s
> int j; // iterates through t
> char s_i; // ith character of s
> char t_j; // jth character of t
> int cost; // cost
>
> // Step 1
> n = s.length ();
> m = t.length ();
> if (n == 0) {
> return m;
> }
> if (m == 0) {
> return n;
> }
> d = new int[n+1][m+1];
>
> // Step 2
> for (i = 0; i <= n; i++) {
> d[i][0] = i;
> }
>
> for (j = 0; j <= m; j++) {
> d[0][j] = j;
> }
>
> // Step 3
> for (i = 1; i <= n; i++) {
> s_i = s.charAt (i - 1);
>
> // Step 4
> for (j = 1; j <= m; j++) {
> t_j = t.charAt (j - 1);
>
> // Step 5
> if (s_i == t_j) {
> cost = 0;
> } else {
> cost = 1;
> }
>
> // Step 6
> d[i][j] = Numbers.minimum(d[i-1][j]+1, d[i][j-1]+1, d[i-1][j-1] + cost);
> }
> }
>
> // Step 7
> return d[n][m];
> }
>
> /**
> * Quote a string so that it may be used in a regular expression
> * without any parts of the string being considered as a
> * part of the regular expression's control characters.
> */
> static public String quoteRegularExpression(String str) {
> // replace ? + * / . ^ $ as long as they're not in character
> // class. so must be done by hand
> char[] chrs = str.toCharArray();
> int sz = chrs.length;
> StringBuffer buffer = new StringBuffer(2*sz);
> for(int i=0; i<sz; i++) {
> switch(chrs[i]) {
> case '[' :
> case ']' :
> case '?' :
> case '+' :
> case '*' :
> case '/' :
> case '.' :
> case '^' :
> case '$' :
> buffer.append("\\");
> default :
> buffer.append(chrs[i]);
> }
> }
> return buffer.toString();
> }
>
> /**
> * Capitalise all the words in a string. Uses Character.isWhitespace
> * as a separator between words.
> */
> static public String capitaliseAllWords(String str) {
> int sz = str.length();
> StringBuffer buffer = new StringBuffer(sz);
> boolean space = true;
> for(int i=0; i<sz; i++) {
> char ch = str.charAt(i);
> if(Character.isWhitespace(ch)) {
> buffer.append(ch);
> space = true;
> } else
> if(space) {
> buffer.append(Character.toTitleCase(ch));
> space = false;
> } else {
> buffer.append(ch);
> }
> }
> return buffer.toString();
> }
>
> /**
> * Create a word-wrapped version of a String. Wrap at 80 characters and
> * use newlines as the delimiter. If a word is over 80 characters long
> * use a - sign to split it.
> */
> static public String wordWrap(String str) {
> return wordWrap(str, 80, "\n", "-");
> }
> /**
> * Create a word-wrapped version of a String. Wrap at a specified width and
> * use newlines as the delimiter. If a word is over the width in lenght
> * use a - sign to split it.
> */
> static public String wordWrap(String str, int width) {
> return wordWrap(str, width, "\n", "-");
> }
> static public String wordWrap(String str, String width, String delim, String split) {
> return wordWrap(str, Numbers.stringToInt(width), delim, split);
> }
> /**
> * Word-wrap a string.
> *
> * @param str String to word-wrap
> * @param width int to wrap at
> * @param delim String to use to separate lines
> * @param split String to use to split a word greater than width long
> *
> * @return String that has been word wrapped
> */
> static public String wordWrap(String str, int width, String delim, String split) {
> int sz = str.length();
>
> /// shift width up one. mainly as it makes the logic easier
> width++;
>
> // our best guess as to an initial size
> StringBuffer buffer = new StringBuffer(sz/width*delim.length()+sz);
>
> // every line will include a delim on the end
> width = width - delim.length();
>
> int idx = -1;
> String substr = null;
>
> // beware: i is rolled-back inside the loop
> for(int i=0; i<sz; i+=width) {
>
> // on the last line
> if(i > sz - width) {
> buffer.append(str.substring(i));
> // System.err.print("LAST-LINE: "+str.substring(i));
> break;
> }
>
> // System.err.println("loop[i] is: "+i);
> // the current line
> substr = str.substring(i, i+width);
>
> // is the delim already on the line
> idx = substr.indexOf(delim);
> if(idx != -1) {
> buffer.append(substr.substring(0,idx));
> // System.err.println("Substr: '"+substr.substring(0,idx)+"'");
> buffer.append(delim);
> i -= width-idx-delim.length();
>
> // System.err.println("loop[i] is now: "+i);
> // System.err.println("found-whitespace: '"+substr.charAt(idx+1)+"'.");
> // Erase a space after a delim. Is this too obscure?
> if(substr.charAt(idx+1) != '\n') {
> if(Character.isWhitespace(substr.charAt(idx+1))) {
> i++;
> }
> }
> // System.err.println("i -= "+width+"-"+idx);
> continue;
> }
>
> idx = -1;
>
> // figure out where the last space is
> char[] chrs = substr.toCharArray();
> for(int j=width; j>0; j--) {
> if(Character.isWhitespace(chrs[j-1])) {
> idx = j;
> // System.err.println("Found whitespace: "+idx);
> break;
> }
> }
>
> // idx is the last whitespace on the line.
> // System.err.println("idx is "+idx);
> if(idx == -1) {
> for(int j=width; j>0; j--) {
> if(chrs[j-1] == '-') {
> idx = j;
> // System.err.println("Found Dash: "+idx);
> break;
> }
> }
> if(idx == -1) {
> buffer.append(substr);
> buffer.append(delim);
> // System.err.print(substr);
> // System.err.print(delim);
> } else {
> if(idx != width) {
> idx++;
> }
> buffer.append(substr.substring(0,idx));
> buffer.append(delim);
> // System.err.print(substr.substring(0,idx));
> // System.err.print(delim);
> i -= width-idx;
> }
> } else {
> /*
> if(force) {
> if(idx == width-1) {
> buffer.append(substr);
> buffer.append(delim);
> } else {
> // stick a split in.
> int splitsz = split.length();
> buffer.append(substr.substring(0,width-splitsz));
> buffer.append(split);
> buffer.append(delim);
> i -= splitsz;
> }
> } else {
> */
> // insert spaces
> buffer.append(substr.substring(0,idx));
> buffer.append(repeat(" ",width-idx));
> // System.err.print(substr.substring(0,idx));
> // System.err.print(repeat(" ",width-idx));
> buffer.append(delim);
> // System.err.print(delim);
> // System.err.println("i -= "+width+"-"+idx);
> i -= width-idx;
> // }
> }
> }
> // System.err.println("\n*************");
> return buffer.toString();
> }
>
>
> /**
> * Get the String that is nested in between two instances of the
> * same String.
> *
> * @param str String containing nested-string
> * @param tag String before and after nested-string
> *
> * @return String that was nested
> */
> static public String getNestedString(String str, String tag) {
> return getNestedString(str, tag, tag);
> }
> /**
> * Get the string that is nested in between two strings.
> *
> * @param str String containing nested-string
> * @param open String before nested-string
> * @param close String after nested-string
> *
> * @return String that was nested
> */
> static public String getNestedString(String str, String open, String close) {
> 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 "";
> }
>
>
> /**
> * How mmany times is the substring in the larger string.
> */
> static public int countMatches(String str, String sub) {
> int count = 0;
> int idx = 0;
> while( (idx = str.indexOf(sub, idx)) != -1) {
> count++;
> idx += sub.length();
> }
> return count;
> }
>
> /**
> * Is a String a word. Contains only unicode letters.
> */
> static public boolean isWord(String str) {
> int sz = str.length();
> for(int i=0; i<sz; i++) {
> if(!Character.isLetter(str.charAt(i))) {
> return false;
> }
> }
> return true;
> }
>
> /**
> * Does a String contain only unicode letters or digits.
> */
> static public boolean isAlphanumeric(String str) {
> int sz = str.length();
> for(int i=0; i<sz; i++) {
> if(!Character.isLetterOrDigit(str.charAt(i))) {
> return false;
> }
> }
> return true;
> }
>
> /**
> * Does a String contain only unicode digits.
> */
> static public boolean isNumeric(String str) {
> int sz = str.length();
> for(int i=0; i<sz; i++) {
> if(!Character.isDigit(str.charAt(i))) {
> return false;
> }
> }
> return true;
> }
>
> /**
> * Is a String a line, containing only letters, digits or
> * whitespace, and ending with an optional newline.
> * NB: Punctuation not allowed.
> */
> static public boolean isLine(String str) {
> char ch = 0;
> char[] chrs = str.toCharArray();
> int sz = chrs.length-1;
> for(int i=0; i<sz-2; i++) {
> if(!Character.isLetterOrDigit(chrs[i])) {
> if(!Character.isWhitespace(chrs[i])) {
> return false;
> }
> }
> }
> if(!Character.isLetterOrDigit(chrs[sz-1])) {
> if(!Character.isWhitespace(chrs[sz-1])) {
> if(chrs[sz-1] != '\r') {
> return false;
> } else
> if(chrs[sz] != '\n') {
> return false;
> }
> }
> }
> if(!Character.isLetterOrDigit(chrs[sz])) {
> if(!Character.isWhitespace(chrs[sz])) {
> if(chrs[sz] != '\n') {
> return false;
> }
> }
> }
> return true;
> }
>
> /*
> // needs to handle punctuation
> static public boolean isText(String str) {
> int sz = str.length();
> char ch = 0;
> for(int i=0; i<sz; i++) {
> ch = str.charAt(i);
> if(!Character.isLetterOrDigit(ch)) {
> if(!Character.isWhitespace(ch)) {
> if( (ch != '\n') && (ch != '\r') ) {
> return false;
> }
> }
> }
> }
> return true;
> }
> */
>
> /**
> * Return either the passed in String, or if it is null,
> * then an empty String.
> */
> static public String defaultString(String str) {
> return defaultString(str,"");
> }
>
> /**
> * Return either the passed in String, or if it is null,
> * then a passed in default String.
> */
> static public String defaultString(String str, String def) {
> return (str == null)?def:str;
> }
>
> static public String upperCase(String str) {
> return str.toUpperCase();
> }
>
> static public String lowerCase(String str) {
> return str.toLowerCase();
> }
>
> static public String substring(String str, String start) {
> return substring(str, Numbers.stringToInt(start));
> }
> static public String substring(String str, int start) {
> if(str == null) {
> return null;
> }
>
> // handle negatives
> if(start < 0) {
> start = str.length() + start; // remember start is negative
> }
>
> if(start < 0) {
> start = 0;
> }
>
> return str.substring(start);
> }
> static public String substring(String str, String start, String end) {
> return substring(str, Numbers.stringToInt(start), Numbers.stringToInt(end));
> }
> static public 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();
> }
>
> // what if start is greater than end??
>
> if(start < 0) {
> start = 0;
> }
>
> // a good default?
> if(end < 0) {
> end = 0;
> }
>
> return str.substring(start, end);
> }
>
>
> static public String random(int count) {
> return random(count, false, false);
> }
>
> static public String randomAscii(int count) {
> return random(count, 32, 127, false, false);
> }
> static public String randomAlphabetic(int count) {
> return random(count, true, false);
> }
> static public String randomAlphanumeric(int count) {
> return random(count, true, true);
> }
> static public String randomNumeric(int count) {
> return random(count, false, true);
> }
>
> static public String random(int count, boolean letters, boolean numbers) {
> return random(count, 0, 0, letters, numbers);
> }
> static public String random(int count, int start, int end, boolean letters, boolean numbers) {
> return random(count, start, end, letters, numbers, null);
> }
> /**
> * Create 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.
> *
> */
> static public 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;
> }
> }
> Random rnd = new Random();
> StringBuffer buffer = new StringBuffer();
> int gap = end - start;
>
> while(count-- != 0) {
> char ch;
> if(set == null) {
> ch = (char)(rnd.nextInt(gap) + start);
> } else {
> ch = set[rnd.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();
> }
>
> static public String random(int count, String set) {
> return random(count, set.toCharArray());
> }
>
> static public String random(int count, char[] set) {
> return random(count,0,set.length-1,false,false,set);
> }
>
> static public String reverseDottedName(String text) {
> return reverseDelimitedString(text, ".");
> }
>
> static public String reverseDelimitedString(String text, String delimiter) {
> // could implement manually, but simple way is to reuse other,
> // probably slower, methods.
> String[] strs = split(text, delimiter);
> // CollectionsUtils.reverseArray(strs);
> // call private method instead for the moment.
> reverseArray(strs);
> return join(strs, delimiter);
> }
>
> /// TAKEN FROM CollectionsUtils. Need to find a solution.
> static private 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++;
> }
> }
>
>
> /**
> * Interpolate variables into a String.
> */
> static public String interpolate(String text, Map map) {
> Iterator keys = map.keySet().iterator();
> while(keys.hasNext()) {
> String key = keys.next().toString();
> String value = map.get(key).toString();
> text = replace(text, "${"+key+"}", value);
> if(key.indexOf(" ") == -1) {
> text = replace(text, "$"+key, value);
> }
> }
> return text;
> }
>
> /**
> * 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();
> }
> }
>
>
> /**
> * A range of characters. Able to understand the idea of a contiguous
> * sublist of an alphbet, a negated concept, and a set of characters.
> * Used by StringUtil to handle sets of characters.
> *
> * @author bayard@generationjava.com
> * @version 0.4 20010812
> */
> class CharRange {
>
> /**
> * Used internally to represent null in a char.
> */
> static private char UNSET;
>
> private char start;
> private char close;
> private boolean negated;
>
> /**
> * Construct a CharRange over a single character.
> *
> * @param start char over which this range is placed
> */
> public CharRange(char start) {
> this.start = start;
> }
>
> /**
> * Construct a CharRange over a set of characters.
> *
> * @param start char start character in this range. inclusive
> * @param close char close character in this range. inclusive
> */
> public CharRange(char start, char close) {
> this.start = start;
> this.close = close;
> }
>
> /**
> * Construct a CharRange over a set of characters.
> *
> * @param start String start first character is in this range (inclusive).
> * @param close String first character is close character in this
> * range (inclusive).
> */
> public CharRange(String start, String close) {
> this.start = start.charAt(0);
> this.close = close.charAt(0);
> }
>
> public char getStart() {
> return this.start;
> }
>
> public char getEnd() {
> return this.close;
> }
>
> public void setStart(char ch) {
> this.start = ch;
> }
>
> public void setEnd(char ch) {
> this.close = ch;
> }
>
> /**
> * Is this CharRange over many characters
> *
> * @return boolean true is many characters
> */
> public boolean isRange() {
> return this.close != UNSET;
> }
>
> /**
> * Is the passed in character inside this range
> *
> * @return boolean true is in range
> */
> public boolean inRange(char ch) {
> if(isRange()) {
> return ((ch >= start) && (ch <= close) );
> } else {
> return start == ch;
> }
> }
>
> /**
> * Is this CharRange negated
> *
> * @return boolean true is negated
> */
> public boolean isNegated() {
> return negated;
> }
>
> /**
> * Make this character range be negated.
> * This implies that this CharRange is over all characters except
> * the ones in this range.
> */
> public void setNegated(boolean b) {
> this.negated = b;
> }
>
> public String toString() {
> String str = "";
> if(isNegated()) {
> str += "^";
> }
> str += start;
> if(isRange()) {
> str += "-";
> str += close;
> }
> return str;
> }
> }
>
>
>
> /**
> * A set of characters. You can iterate over the characters in the
> * set.
> *
> * @author bayard@generationjava.com
> * @version 0.4 20010812
> */
> class CharSet {
>
> // used to be a com.generationjava.collections.typed.TypedList
> private LinkedList set = new LinkedList();
>
> public CharSet(String[] set) {
> int sz = set.length;
> for(int i=0; i<sz; i++) {
> add(set[i]);
> }
> }
>
> public boolean contains(char ch) {
> Iterator iterator = set.iterator();
> boolean bool = false;
> while(iterator.hasNext()) {
> CharRange range = (CharRange)iterator.next();
> if(range.isNegated()) {
> if(!range.inRange(ch)) {
> bool = true;
> }
> } else {
> if(range.inRange(ch)) {
> bool = true;
> }
> }
> }
> return bool;
> }
>
> public void add(String str) {
> int sz = str.length();
> CharRange range = null;
> boolean end = false;
> boolean negated = false;
> for(int i=0; i<sz; i++) {
> char ch = str.charAt(i);
> if(ch == '-') {
> end = true;
> continue;
> }
> if(end) {
> range.setEnd(ch);
> continue;
> }
> if(ch == '^') {
> negated = true;
> continue;
> }
> range = new CharRange(ch);
> range.setNegated(negated);
> set.add(range);
> }
> }
>
> public String toString() {
> return set.toString();
> }
>
> }
>
>
>
>
>
>
> 1.1 jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/exception/Nestable.java
>
> Index: Nestable.java
> ===================================================================
> package org.apache.commons.lang.exception;
>
> /* ====================================================================
> * The Apache Software License, Version 1.1
> *
> * Copyright (c) 2001 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
> * "Apache Turbine" 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",
> * "Apache Turbine", 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.io.PrintWriter;
>
> /**
> * An interface to be implemented by {@link java.lang.Throwable}
> * extensions which would like to be able to nest root exceptions
> * inside themselves.
> *
> * @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
> * @author <a href="mailto:knielsen@apache.org">Kasper Nielsen</a>
> */
> public interface Nestable
> {
> /**
> * Returns the reference to the exception or error that caused the
> * exception implementing the <code>Nestable</code> to be thrown.
> */
> public Throwable getCause();
>
> /**
> * Returns the error message of this and any nested
> * <code>Throwable</code>.
> *
> * @return The error message.
> */
> public String getMessage();
>
> /**
> * Prints the stack trace of this exception to the specified print
> * writer. Includes inforamation from the exception--if
> * any--which caused this exception.
> *
> * @param out <code>PrintWriter</code> to use for output.
> */
> public void printStackTrace(PrintWriter out);
>
> /**
> * Prints the stack trace for this exception only--root cause not
> * included--using the provided writer. Used by {@link
> * org.apache.commons.lang.exception.NestableDelegate} to write
> * individual stack traces to a buffer. The implementation of
> * this method should call
> * <code>super.printStackTrace(out);</code> in most cases.
> *
> * @param out The writer to use.
> */
> public void printPartialStackTrace(PrintWriter out);
> }
>
>
>
> 1.1 jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/exception/NestableDelegate.java
>
> Index: NestableDelegate.java
> ===================================================================
> package org.apache.commons.lang.exception;
>
> /* ====================================================================
> * The Apache Software License, Version 1.1
> *
> * Copyright (c) 2001 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
> * "Apache Turbine" 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",
> * "Apache Turbine", 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.io.OutputStream;
> import java.io.PrintStream;
> import java.io.PrintWriter;
> import java.io.StringWriter;
> import java.io.Writer;
> import java.util.LinkedList;
> import java.util.StringTokenizer;
>
> /**
> * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
> * @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
> * @author <a href="mailto:knielsen@apache.org">Kasper Nielsen</a>
> */
> public class NestableDelegate
> {
> /**
> * Constructor error message.
> */
> private static final String MUST_BE_THROWABLE =
> "The Nestable implementation passed to the NestableDelegate(Nestable) "
> + "constructor must extend java.lang.Throwable";
>
> /**
> * Holds the reference to the exception or error that caused
> * this exception to be thrown.
> */
> private Nestable cause = null;
>
> /**
> * @param cause The Nestable implementation to get a stack trace for
> * (<i>must</i> extend {@link java.lang.Throwable}).
> */
> public NestableDelegate(Nestable cause)
> {
> if (cause instanceof Throwable)
> {
> this.cause = cause;
> }
> else
> {
> throw new IllegalArgumentException(MUST_BE_THROWABLE);
> }
> }
>
> /**
> * @param baseMsg The base message to use when creating the full
> * message. Should be generally be called via
> * <code>nestableHelper.getMessage(super.getMessage())</code>,
> * where <code>super</code> is an instance of {@link
> * java.lang.Throwable}.
> * @return The concatenated message for this and all nested
> * exceptions.
> */
> public String getMessage(String baseMsg)
> {
> StringBuffer msg = new StringBuffer();
> if (baseMsg != null)
> {
> msg.append(baseMsg);
> }
>
> Throwable nestedCause = cause.getCause();
> if (nestedCause != null)
> {
> String causeMsg = nestedCause.getMessage();
> if (causeMsg != null)
> {
> if (baseMsg != null)
> {
> msg.append(": ");
> }
> msg.append(causeMsg);
> }
>
> }
> return (msg.length() > 0 ? msg.toString() : null);
> }
>
> /**
> * Prints the stack trace of this exception the the standar error
> * stream.
> */
> public void printStackTrace()
> {
> synchronized (System.err)
> {
> printStackTrace(System.err);
> }
> }
>
> /**
> * Prints the stack trace of this exception to the specified print stream.
> *
> * @param out <code>PrintStream</code> to use for output.
> */
> public void printStackTrace(PrintStream out)
> {
> synchronized (out)
> {
> PrintWriter pw = new PrintWriter(out, false);
> printStackTrace(pw);
> // Flush the PrintWriter before it's GC'ed.
> pw.flush();
> }
> }
>
> /**
> * Prints the stack trace of this exception to the specified print writer.
> *
> * @param out <code>PrintWriter</code> to use for output.
> */
> public void printStackTrace(PrintWriter out)
> {
> synchronized (out)
> {
> String[] st = decompose((Throwable) cause);
> Throwable nestedCause = cause.getCause();
> if (nestedCause != null)
> {
> if (nestedCause instanceof Nestable)
> {
> // Recurse until a non-Nestable is encountered.
> ((Nestable) nestedCause).printStackTrace(out);
> }
> else
> {
> String[] nst = decompose(nestedCause);
> for (int i = 0; i < nst.length; i++)
> {
> out.println(nst[i]);
> }
> }
> out.print("rethrown as ");
> }
>
> // Output desired frames from stack trace.
> for (int i = 0; i < st.length; i++)
> {
> out.println(st[i]);
> }
> }
> }
>
> /**
> * Captures the stack trace associated with a <code>Throwable</code>
> * object, decomposing it into a list of stack frames.
> *
> * @param t The <code>Throwable</code>.
> * @return An array of strings describing each stack frame.
> */
> private String[] decompose(Throwable t)
> {
> StringWriter sw = new StringWriter();
> PrintWriter pw = new PrintWriter(sw, true);
>
> // Avoid infinite loop between decompose() and printStackTrace().
> if (t instanceof Nestable)
> {
> ((Nestable) t).printPartialStackTrace(pw);
> }
> else
> {
> t.printStackTrace(pw);
> }
>
> String linebreak = System.getProperty("line.separator");
> StringTokenizer st = new StringTokenizer(sw.getBuffer().toString(),
> linebreak);
> LinkedList list = new LinkedList();
> while (st.hasMoreTokens())
> {
> list.add(st.nextToken());
> }
> return (String []) list.toArray(new String[] {});
> }
> }
>
>
>
> 1.1 jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/exception/NestableException.java
>
> Index: NestableException.java
> ===================================================================
> package org.apache.commons.lang.exception;
>
> /* ====================================================================
> * The Apache Software License, Version 1.1
> *
> * Copyright (c) 2001 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
> * "Apache Turbine" 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",
> * "Apache Turbine", 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.io.OutputStream;
> import java.io.PrintStream;
> import java.io.PrintWriter;
> import java.io.StringWriter;
> import java.io.Writer;
> import java.util.LinkedList;
> import java.util.StringTokenizer;
>
> /**
> * The base class of all exceptions which can contain other exceptions.
> *
> * It is intended to ease the debugging by carrying on the information
> * about the exception which was caught and provoked throwing the
> * current exception. Catching and rethrowing may occur multiple
> * times, and provided that all exceptions except the first one
> * are descendands of <code>NestedException</code>, when the
> * exception is finally printed out using any of the <code>
> * printStackTrace()</code> methods, the stacktrace will contain
> * the information about all exceptions thrown and caught on
> * the way.
> * <p> Running the following program
> * <p><blockquote><pre>
> * 1 import org.apache.commons.NestedException;
> * 2
> * 3 public class Test {
> * 4 public static void main( String[] args ) {
> * 5 try {
> * 6 a();
> * 7 } catch(Exception e) {
> * 8 e.printStackTrace();
> * 9 }
> * 10 }
> * 11
> * 12 public static void a() throws Exception {
> * 13 try {
> * 14 b();
> * 15 } catch(Exception e) {
> * 16 throw new NestedException("foo", e);
> * 17 }
> * 18 }
> * 19
> * 20 public static void b() throws Exception {
> * 21 try {
> * 22 c();
> * 23 } catch(Exception e) {
> * 24 throw new NestedException("bar", e);
> * 25 }
> * 26 }
> * 27
> * 28 public static void c() throws Exception {
> * 29 throw new Exception("baz");
> * 30 }
> * 31 }
> * </pre></blockquote>
> * <p>Yields the following stacktrace:
> * <p><blockquote><pre>
> * java.lang.Exception: baz: bar: foo
> * at Test.c(Test.java:29)
> * at Test.b(Test.java:22)
> * rethrown as NestedException: bar
> * at Test.b(Test.java:24)
> * at Test.a(Test.java:14)
> * rethrown as NestedException: foo
> * at Test.a(Test.java:16)
> * at Test.main(Test.java:6)
> * </pre></blockquote><br>
> *
> * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
> * @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
> * @author <a href="mailto:knielsen@apache.org">Kasper Nielsen</a>
> */
> public class NestableException extends Exception implements Nestable
> {
> /**
> * The helper instance which contains much of the code which we
> * delegate to.
> */
> protected NestableDelegate delegate = new NestableDelegate(this);
>
> /**
> * Holds the reference to the exception or error that caused
> * this exception to be thrown.
> */
> private Throwable cause = null;
>
> /**
> * Constructs a new <code>NestableException</code> without specified
> * detail message.
> */
> public NestableException()
> {
> super();
> }
>
> /**
> * Constructs a new <code>NestableException</code> with specified
> * detail message.
> *
> * @param msg The error message.
> */
> public NestableException(String msg)
> {
> super(msg);
> }
>
> /**
> * Constructs a new <code>NestableException</code> with specified
> * nested <code>Throwable</code>.
> *
> * @param nested The exception or error that caused this exception
> * to be thrown.
> */
> public NestableException(Throwable cause)
> {
> super();
> this.cause = cause;
> }
>
> /**
> * Constructs a new <code>NestableException</code> with specified
> * detail message and nested <code>Throwable</code>.
> *
> * @param msg The error message.
> * @param nested The exception or error that caused this exception
> * to be thrown.
> */
> public NestableException(String msg, Throwable cause)
> {
> super(msg);
> this.cause = cause;
> }
>
> /**
> * @see org.apache.commons.lang.exception.Nestable#getCause()
> */
> public Throwable getCause()
> {
> return cause;
> }
>
> /**
> * @see org.apache.commons.lang.exception.Nestable#getMessage()
> */
> public String getMessage()
> {
> StringBuffer msg = new StringBuffer();
> String ourMsg = super.getMessage();
> if (ourMsg != null)
> {
> msg.append(ourMsg);
> }
> if (cause != null)
> {
> String causeMsg = cause.getMessage();
> if (causeMsg != null)
> {
> if (ourMsg != null)
> {
> msg.append(": ");
> }
> msg.append(causeMsg);
> }
>
> }
> return (msg.length() > 0 ? msg.toString() : null);
> }
>
> /**
> * Prints the stack trace of this exception the the standar error
> * stream.
> */
> public void printStackTrace()
> {
> delegate.printStackTrace();
> }
>
> /**
> * Prints the stack trace of this exception to the specified print stream.
> *
> * @param out <code>PrintStream</code> to use for output.
> */
> public void printStackTrace(PrintStream out)
> {
> delegate.printStackTrace(out);
> }
>
> /**
> * @see org.apache.commons.lang.exception.Nestable#printStackTrace(PrintWriter out)
> */
> public void printStackTrace(PrintWriter out)
> {
> delegate.printStackTrace(out);
> }
>
> /**
> * @see org.apache.commons.lang.exception.Nestable#printPartialStackTrace(PrintWriter out)
> */
> public final void printPartialStackTrace(PrintWriter out)
> {
> super.printStackTrace(out);
> }
> }
>
>
>
> 1.1 jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/exception/NestableRuntimeException.java
>
> Index: NestableRuntimeException.java
> ===================================================================
> package org.apache.commons.lang.exception;
>
> /* ====================================================================
> * The Apache Software License, Version 1.1
> *
> * Copyright (c) 2001 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
> * "Apache Turbine" 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",
> * "Apache Turbine", 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.io.OutputStream;
> import java.io.PrintStream;
> import java.io.PrintWriter;
> import java.io.StringWriter;
> import java.io.Writer;
> import java.util.LinkedList;
> import java.util.StringTokenizer;
>
> /**
> * The base class of all runtime exceptions which can contain other
> * exceptions.
> *
> * @see org.apache.commons.lang.exception.NestableException
> * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
> * @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
> * @author <a href="mailto:knielsen@apache.org">Kasper Nielsen</a>
> */
> public class NestableRuntimeException extends RuntimeException
> implements Nestable
> {
> /**
> * The helper instance which contains much of the code which we
> * delegate to.
> */
> protected NestableDelegate delegate = new NestableDelegate(this);
>
> /**
> * Holds the reference to the exception or error that caused
> * this exception to be thrown.
> */
> private Throwable cause = null;
>
> /**
> * Constructs a new <code>NestableRuntimeException</code> without specified
> * detail message.
> */
> public NestableRuntimeException()
> {
> super();
> }
>
> /**
> * Constructs a new <code>NestableRuntimeException</code> with specified
> * detail message.
> *
> * @param msg The error message.
> */
> public NestableRuntimeException(String msg)
> {
> super(msg);
> }
>
> /**
> * Constructs a new <code>NestableRuntimeException</code> with specified
> * nested <code>Throwable</code>.
> *
> * @param nested The exception or error that caused this exception
> * to be thrown.
> */
> public NestableRuntimeException(Throwable cause)
> {
> super();
> this.cause = cause;
> }
>
> /**
> * Constructs a new <code>NestableRuntimeException</code> with specified
> * detail message and nested <code>Throwable</code>.
> *
> * @param msg The error message.
> * @param nested The exception or error that caused this exception
> * to be thrown.
> */
> public NestableRuntimeException(String msg, Throwable cause)
> {
> super(msg);
> this.cause = cause;
> }
>
> /**
> * @see org.apache.commons.lang.exception.Nestable#getCause()
> */
> public Throwable getCause()
> {
> return cause;
> }
>
> /**
> * @see org.apache.commons.lang.exception.Nestable#getMessage()
> */
> public String getMessage()
> {
> StringBuffer msg = new StringBuffer();
> String ourMsg = super.getMessage();
> if (ourMsg != null)
> {
> msg.append(ourMsg);
> }
> if (cause != null)
> {
> String causeMsg = cause.getMessage();
> if (causeMsg != null)
> {
> if (ourMsg != null)
> {
> msg.append(": ");
> }
> msg.append(causeMsg);
> }
>
> }
> return (msg.length() > 0 ? msg.toString() : null);
> }
>
> /**
> * Prints the stack trace of this exception the the standar error
> * stream.
> */
> public void printStackTrace()
> {
> delegate.printStackTrace();
> }
>
> /**
> * Prints the stack trace of this exception to the specified print stream.
> *
> * @param out <code>PrintStream</code> to use for output.
> */
> public void printStackTrace(PrintStream out)
> {
> delegate.printStackTrace(out);
> }
>
> /**
> * @see org.apache.commons.lang.exception.Nestable#printStackTrace(PrintWriter out)
> */
> public void printStackTrace(PrintWriter out)
> {
> delegate.printStackTrace(out);
> }
>
> /**
> * @see org.apache.commons.lang.exception.Nestable#printPartialStackTrace(PrintWriter out)
> */
> public final void printPartialStackTrace(PrintWriter out)
> {
> super.printStackTrace(out);
> }
> }
>
>
>
>
> --
> To unsubscribe, e-mail: <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>
>
>
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>