Index: 3rdParty_sources/versions.txt =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/versions.txt,v diff -u -r1.2 -r1.3 --- 3rdParty_sources/versions.txt 22 Aug 2012 17:30:39 -0000 1.2 +++ 3rdParty_sources/versions.txt 30 Aug 2012 16:24:44 -0000 1.3 @@ -11,6 +11,8 @@ Commons HttpClient 3.0 +Commons Lang 2.0 + Hibernate Core 3.3.1 GA jbosscache 3.1.0.CR1 Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/ArrayUtils.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/ArrayUtils.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/ArrayUtils.java 30 Aug 2012 16:24:42 -0000 1.1 @@ -0,0 +1,2274 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; + +/** + *

Operations on arrays, primitive arrays (like int[]) and primitive wrapper arrays + * (like Integer[]).

+ * + *

This class tries to handle null input gracefully. + * An exception will not be thrown for a null + * array input. However, an Object array that contains a null + * element may throw an exception. Each method documents its behaviour.

+ * + * @author Stephen Colebourne + * @author Moritz Petersen + * @author Fredrik Westermarck + * @author Nikolay Metchev + * @author Matthew Hawthorne + * @author Tim O'Brien + * @author Pete Gieser + * @author Gary Gregory + * @since 2.0 + * @version $Id: ArrayUtils.java,v 1.1 2012/08/30 16:24:42 marcin Exp $ + */ +public class ArrayUtils { + + /** + * An empty immutable Object array. + */ + public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0]; + /** + * An empty immutable Class array. + */ + public static final Class[] EMPTY_CLASS_ARRAY = new Class[0]; + /** + * An empty immutable String array. + */ + public static final String[] EMPTY_STRING_ARRAY = new String[0]; + /** + * An empty immutable long array. + */ + public static final long[] EMPTY_LONG_ARRAY = new long[0]; + /** + * An empty immutable Long array. + */ + public static final Long[] EMPTY_LONG_OBJECT_ARRAY = new Long[0]; + /** + * An empty immutable int array. + */ + public static final int[] EMPTY_INT_ARRAY = new int[0]; + /** + * An empty immutable Integer array. + */ + public static final Integer[] EMPTY_INTEGER_OBJECT_ARRAY = new Integer[0]; + /** + * An empty immutable short array. + */ + public static final short[] EMPTY_SHORT_ARRAY = new short[0]; + /** + * An empty immutable Short array. + */ + public static final Short[] EMPTY_SHORT_OBJECT_ARRAY = new Short[0]; + /** + * An empty immutable byte array. + */ + public static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; + /** + * An empty immutable Byte array. + */ + public static final Byte[] EMPTY_BYTE_OBJECT_ARRAY = new Byte[0]; + /** + * An empty immutable double array. + */ + public static final double[] EMPTY_DOUBLE_ARRAY = new double[0]; + /** + * An empty immutable Double array. + */ + public static final Double[] EMPTY_DOUBLE_OBJECT_ARRAY = new Double[0]; + /** + * An empty immutable float array. + */ + public static final float[] EMPTY_FLOAT_ARRAY = new float[0]; + /** + * An empty immutable Float array. + */ + public static final Float[] EMPTY_FLOAT_OBJECT_ARRAY = new Float[0]; + /** + * An empty immutable boolean array. + */ + public static final boolean[] EMPTY_BOOLEAN_ARRAY = new boolean[0]; + /** + * An empty immutable Boolean array. + */ + public static final Boolean[] EMPTY_BOOLEAN_OBJECT_ARRAY = new Boolean[0]; + /** + * An empty immutable char array. + */ + public static final char[] EMPTY_CHAR_ARRAY = new char[0]; + /** + * An empty immutable Character array. + */ + public static final Character[] EMPTY_CHARACTER_OBJECT_ARRAY = new Character[0]; + + /** + *

ArrayUtils instances should NOT be constructed in standard programming. + * Instead, the class should be used as ArrayUtils.clone(new int[] {2}).

+ * + *

This constructor is public to permit tools that require a JavaBean instance + * to operate.

+ */ + public ArrayUtils() { + } + + // Basic methods handling multi-dimensional arrays + //----------------------------------------------------------------------- + /** + *

Outputs an array as a String, treating null as an empty array.

+ * + *

Multi-dimensional arrays are handled correctly, including + * multi-dimensional primitive arrays.

+ * + *

The format is that of Java source code, for example {a,b}.

+ * + * @param array the array to get a toString for, may be null + * @return a String representation of the array, '{}' if null array input + */ + public static String toString(final Object array) { + return toString(array, "{}"); + } + + /** + *

Outputs an array as a String handling nulls.

+ * + *

Multi-dimensional arrays are handled correctly, including + * multi-dimensional primitive arrays.

+ * + *

The format is that of Java source code, for example {a,b}.

+ * + * @param array the array to get a toString for, may be null + * @param stringIfNull the String to return if the array is null + * @return a String representation of the array + */ + public static String toString(final Object array, final String stringIfNull) { + if (array == null) { + return stringIfNull; + } + return new ToStringBuilder(array, ToStringStyle.SIMPLE_STYLE).append(array).toString(); + } + + /** + *

Get a hashCode for an array handling multi-dimensional arrays correctly.

+ * + *

Multi-dimensional primitive arrays are also handled correctly by this method.

+ * + * @param array the array to get a hashCode for, may be null + * @return a hashCode for the array, zero if null array input + */ + public static int hashCode(final Object array) { + return new HashCodeBuilder().append(array).toHashCode(); + } + + /** + *

Compares two arrays, using equals(), handling multi-dimensional arrays + * correctly.

+ * + *

Multi-dimensional primitive arrays are also handled correctly by this method.

+ * + * @param array1 the array to get a hashCode for, may be null + * @param array2 the array to get a hashCode for, may be null + * @return true if the arrays are equal + */ + public static boolean isEquals(final Object array1, final Object array2) { + return new EqualsBuilder().append(array1, array2).isEquals(); + } + + // To map + //----------------------------------------------------------------------- + /** + *

Converts the given array into a {@link java.util.Map}. Each element of the array + * must be either a {@link java.util.Map.Entry} or an Array, containing at least two + * elements, where the first element is used as key and the second as + * value.

+ * + *

This method can be used to initialize:

+ *
+     * // Create a Map mapping colors.
+     * Map colorMap = MapUtils.toMap(new String[][] {{
+     *     {"RED", "#FF0000"},
+     *     {"GREEN", "#00FF00"},
+     *     {"BLUE", "#0000FF"}});
+     * 
+ * + *

This method returns null if null array input.

+ * + * @param array an array whose elements are either a {@link java.util.Map.Entry} or + * an Array containing at least two elements, may be null + * @return a Map that was created from the array + * @throws IllegalArgumentException if one element of this Array is + * itself an Array containing less then two elements + * @throws IllegalArgumentException if the array contains elements other + * than {@link java.util.Map.Entry} and an Array + */ + public static Map toMap(final Object[] array) { + if (array == null) { + return null; + } + final Map map = new HashMap((int) (array.length * 1.5)); + for (int i = 0; i < array.length; i++) { + Object object = array[i]; + if (object instanceof Map.Entry) { + Map.Entry entry = (Map.Entry) object; + map.put(entry.getKey(), entry.getValue()); + } else if (object instanceof Object[]) { + Object[] entry = (Object[]) object; + if (entry.length < 2) { + throw new IllegalArgumentException("Array element " + i + ", '" + + object + + "', has a length less than 2"); + } + map.put(entry[0], entry[1]); + } else { + throw new IllegalArgumentException("Array element " + i + ", '" + + object + + "', is neither of type Map.Entry nor an Array"); + } + } + return map; + } + + // Clone + //----------------------------------------------------------------------- + /** + *

Shallow clones an array returning a typecast result and handling + * null.

+ * + *

The objecs in the array are not cloned, thus there is no special + * handling for multi-dimensional arrays.

+ * + *

This method returns null if null array input.

+ * + * @param array the array to shallow clone, may be null + * @return the cloned array, null if null input + */ + public static Object[] clone(final Object[] array) { + if (array == null) { + return null; + } + return (Object[]) array.clone(); + } + + /** + *

Clones an array returning a typecast result and handling + * null.

+ * + *

This method returns null if null array input.

+ * + * @param array the array to clone, may be null + * @return the cloned array, null if null input + */ + public static long[] clone(final long[] array) { + if (array == null) { + return null; + } + return (long[]) array.clone(); + } + + /** + *

Clones an array returning a typecast result and handling + * null.

+ * + *

This method returns null if null array input.

+ * + * @param array the array to clone, may be null + * @return the cloned array, null if null input + */ + public static int[] clone(int[] array) { + if (array == null) { + return null; + } + return (int[]) array.clone(); + } + + /** + *

Clones an array returning a typecast result and handling + * null.

+ * + *

This method returns null if null array input.

+ * + * @param array the array to clone, may be null + * @return the cloned array, null if null input + */ + public static short[] clone(final short[] array) { + if (array == null) { + return null; + } + return (short[]) array.clone(); + } + + /** + *

Clones an array returning a typecast result and handling + * null.

+ * + *

This method returns null if null array input.

+ * + * @param array the array to clone, may be null + * @return the cloned array, null if null input + */ + public static char[] clone(final char[] array) { + if (array == null) { + return null; + } + return (char[]) array.clone(); + } + + /** + *

Clones an array returning a typecast result and handling + * null.

+ * + *

This method returns null if null array input.

+ * + * @param array the array to clone, may be null + * @return the cloned array, null if null input + */ + public static byte[] clone(final byte[] array) { + if (array == null) { + return null; + } + return (byte[]) array.clone(); + } + + /** + *

Clones an array returning a typecast result and handling + * null.

+ * + *

This method returns null if null array input.

+ * + * @param array the array to clone, may be null + * @return the cloned array, null if null input + */ + public static double[] clone(final double[] array) { + if (array == null) { + return null; + } + return (double[]) array.clone(); + } + + /** + *

Clones an array returning a typecast result and handling + * null.

+ * + *

This method returns null if null array input.

+ * + * @param array the array to clone, may be null + * @return the cloned array, null if null input + */ + public static float[] clone(final float[] array) { + if (array == null) { + return null; + } + return (float[]) array.clone(); + } + + /** + *

Clones an array returning a typecast result and handling + * null.

+ * + *

This method returns null if null array input.

+ * + * @param array the array to clone, may be null + * @return the cloned array, null if null input + */ + public static boolean[] clone(final boolean[] array) { + if (array == null) { + return null; + } + return (boolean[]) array.clone(); + } + + // Is same length + //----------------------------------------------------------------------- + /** + *

Checks whether two arrays are the same length, treating + * null arrays as length 0. + * + *

Any multi-dimensional aspects of the arrays are ignored.

+ * + * @param array1 the first array, may be null + * @param array2 the second array, may be null + * @return true if length of arrays matches, treating + * null as an empty array + */ + public static boolean isSameLength(final Object[] array1, final Object[] array2) { + if ((array1 == null && array2 != null && array2.length > 0) || + (array2 == null && array1 != null && array1.length > 0) || + (array1 != null && array2 != null && array1.length != array2.length)) { + return false; + } + return true; + } + + /** + *

Checks whether two arrays are the same length, treating + * null arrays as length 0.

+ * + * @param array1 the first array, may be null + * @param array2 the second array, may be null + * @return true if length of arrays matches, treating + * null as an empty array + */ + public static boolean isSameLength(final long[] array1, final long[] array2) { + if ((array1 == null && array2 != null && array2.length > 0) || + (array2 == null && array1 != null && array1.length > 0) || + (array1 != null && array2 != null && array1.length != array2.length)) { + return false; + } + return true; + } + + /** + *

Checks whether two arrays are the same length, treating + * null arrays as length 0.

+ * + * @param array1 the first array, may be null + * @param array2 the second array, may be null + * @return true if length of arrays matches, treating + * null as an empty array + */ + public static boolean isSameLength(final int[] array1, final int[] array2) { + if ((array1 == null && array2 != null && array2.length > 0) || + (array2 == null && array1 != null && array1.length > 0) || + (array1 != null && array2 != null && array1.length != array2.length)) { + return false; + } + return true; + } + + /** + *

Checks whether two arrays are the same length, treating + * null arrays as length 0.

+ * + * @param array1 the first array, may be null + * @param array2 the second array, may be null + * @return true if length of arrays matches, treating + * null as an empty array + */ + public static boolean isSameLength(final short[] array1, final short[] array2) { + if ((array1 == null && array2 != null && array2.length > 0) || + (array2 == null && array1 != null && array1.length > 0) || + (array1 != null && array2 != null && array1.length != array2.length)) { + return false; + } + return true; + } + + /** + *

Checks whether two arrays are the same length, treating + * null arrays as length 0.

+ * + * @param array1 the first array, may be null + * @param array2 the second array, may be null + * @return true if length of arrays matches, treating + * null as an empty array + */ + public static boolean isSameLength(final char[] array1, final char[] array2) { + if ((array1 == null && array2 != null && array2.length > 0) || + (array2 == null && array1 != null && array1.length > 0) || + (array1 != null && array2 != null && array1.length != array2.length)) { + return false; + } + return true; + } + + /** + *

Checks whether two arrays are the same length, treating + * null arrays as length 0.

+ * + * @param array1 the first array, may be null + * @param array2 the second array, may be null + * @return true if length of arrays matches, treating + * null as an empty array + */ + public static boolean isSameLength(final byte[] array1, final byte[] array2) { + if ((array1 == null && array2 != null && array2.length > 0) || + (array2 == null && array1 != null && array1.length > 0) || + (array1 != null && array2 != null && array1.length != array2.length)) { + return false; + } + return true; + } + + /** + *

Checks whether two arrays are the same length, treating + * null arrays as length 0.

+ * + * @param array1 the first array, may be null + * @param array2 the second array, may be null + * @return true if length of arrays matches, treating + * null as an empty array + */ + public static boolean isSameLength(final double[] array1, final double[] array2) { + if ((array1 == null && array2 != null && array2.length > 0) || + (array2 == null && array1 != null && array1.length > 0) || + (array1 != null && array2 != null && array1.length != array2.length)) { + return false; + } + return true; + } + + /** + *

Checks whether two arrays are the same length, treating + * null arrays as length 0.

+ * + * @param array1 the first array, may be null + * @param array2 the second array, may be null + * @return true if length of arrays matches, treating + * null as an empty array + */ + public static boolean isSameLength(final float[] array1, final float[] array2) { + if ((array1 == null && array2 != null && array2.length > 0) || + (array2 == null && array1 != null && array1.length > 0) || + (array1 != null && array2 != null && array1.length != array2.length)) { + return false; + } + return true; + } + + /** + *

Checks whether two arrays are the same length, treating + * null arrays as length 0.

+ * + * @param array1 the first array, may be null + * @param array2 the second array, may be null + * @return true if length of arrays matches, treating + * null as an empty array + */ + public static boolean isSameLength(final boolean[] array1, final boolean[] array2) { + if ((array1 == null && array2 != null && array2.length > 0) || + (array2 == null && array1 != null && array1.length > 0) || + (array1 != null && array2 != null && array1.length != array2.length)) { + return false; + } + return true; + } + + /** + *

Checks whether two arrays are the same type taking into account + * multi-dimensional arrays.

+ * + * @param array1 the first array, must not be null + * @param array2 the second array, must not be null + * @return true if type of arrays matches + * @throws IllegalArgumentException if either array is null + */ + public static boolean isSameType(final Object array1, final Object array2) { + if (array1 == null || array2 == null) { + throw new IllegalArgumentException("The Array must not be null"); + } + return array1.getClass().getName().equals(array2.getClass().getName()); + } + + // Reverse + //----------------------------------------------------------------------- + /** + *

Reverses the order of the given array.

+ * + *

There is no special handling for multi-dimensional arrays.

+ * + *

This method does nothing if null array input.

+ * + * @param array the array to reverse, may be null + */ + public static void reverse(final Object[] array) { + if (array == null) { + return; + } + 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++; + } + } + + /** + *

Reverses the order of the given array.

+ * + *

This method does nothing if null array input.

+ * + * @param array the array to reverse, may be null + */ + public static void reverse(final long[] array) { + if (array == null) { + return; + } + int i = 0; + int j = array.length - 1; + long tmp; + while (j > i) { + tmp = array[j]; + array[j] = array[i]; + array[i] = tmp; + j--; + i++; + } + } + + /** + *

Reverses the order of the given array.

+ * + *

This method does nothing if null array input.

+ * + * @param array the array to reverse, may be null + */ + public static void reverse(final int[] array) { + if (array == null) { + return; + } + int i = 0; + int j = array.length - 1; + int tmp; + while (j > i) { + tmp = array[j]; + array[j] = array[i]; + array[i] = tmp; + j--; + i++; + } + } + + /** + *

Reverses the order of the given array.

+ * + *

This method does nothing if null array input.

+ * + * @param array the array to reverse, may be null + */ + public static void reverse(final short[] array) { + if (array == null) { + return; + } + int i = 0; + int j = array.length - 1; + short tmp; + while (j > i) { + tmp = array[j]; + array[j] = array[i]; + array[i] = tmp; + j--; + i++; + } + } + + /** + *

Reverses the order of the given array.

+ * + *

This method does nothing if null array input.

+ * + * @param array the array to reverse, may be null + */ + public static void reverse(final char[] array) { + if (array == null) { + return; + } + int i = 0; + int j = array.length - 1; + char tmp; + while (j > i) { + tmp = array[j]; + array[j] = array[i]; + array[i] = tmp; + j--; + i++; + } + } + + /** + *

Reverses the order of the given array.

+ * + *

This method does nothing if null array input.

+ * + * @param array the array to reverse, may be null + */ + public static void reverse(final byte[] array) { + if (array == null) { + return; + } + int i = 0; + int j = array.length - 1; + byte tmp; + while (j > i) { + tmp = array[j]; + array[j] = array[i]; + array[i] = tmp; + j--; + i++; + } + } + + /** + *

Reverses the order of the given array.

+ * + *

This method does nothing if null array input.

+ * + * @param array the array to reverse, may be null + */ + public static void reverse(final double[] array) { + if (array == null) { + return; + } + int i = 0; + int j = array.length - 1; + double tmp; + while (j > i) { + tmp = array[j]; + array[j] = array[i]; + array[i] = tmp; + j--; + i++; + } + } + + /** + *

Reverses the order of the given array.

+ * + *

This method does nothing if null array input.

+ * + * @param array the array to reverse, may be null + */ + public static void reverse(final float[] array) { + if (array == null) { + return; + } + int i = 0; + int j = array.length - 1; + float tmp; + while (j > i) { + tmp = array[j]; + array[j] = array[i]; + array[i] = tmp; + j--; + i++; + } + } + + /** + *

Reverses the order of the given array.

+ * + *

This method does nothing if null array input.

+ * + * @param array the array to reverse, may be null + */ + public static void reverse(final boolean[] array) { + if (array == null) { + return; + } + int i = 0; + int j = array.length - 1; + boolean tmp; + while (j > i) { + tmp = array[j]; + array[j] = array[i]; + array[i] = tmp; + j--; + i++; + } + } + + // IndexOf search + // ---------------------------------------------------------------------- + + // Object IndexOf + //----------------------------------------------------------------------- + /** + *

Find the index of the given object in the array.

+ * + *

This method returns -1 if null array input.

+ * + * @param array the array to search through for the object, may be null + * @param objectToFind the object to find, may be null + * @return the index of the object within the array, + * -1 if not found or null array input + */ + public static int indexOf(final Object[] array, final Object objectToFind) { + return indexOf(array, objectToFind, 0); + } + + /** + *

Find the index of the given object in the array starting at the given index.

+ * + *

This method returns -1 if null array input.

+ * + *

A negative startIndex is treated as zero. A startIndex larger than the array + * length will return -1.

+ * + * @param array the array to search through for the object, may be null + * @param objectToFind the object to find, may be null + * @param startIndex the index to start searching at + * @return the index of the object within the array starting at the index, + * -1 if not found or null array input + */ + public static int indexOf(final Object[] array, final Object objectToFind, int startIndex) { + if (array == null) { + return -1; + } + if (startIndex < 0) { + startIndex = 0; + } + if (objectToFind == null) { + for (int i = startIndex; i < array.length; i++) { + if (array[i] == null) { + return i; + } + } + } else { + for (int i = startIndex; i < array.length; i++) { + if (objectToFind.equals(array[i])) { + return i; + } + } + } + return -1; + } + + /** + *

Find the last index of the given object within the array.

+ * + *

This method returns -1 if null array input.

+ * + * @param array the array to travers backwords looking for the object, may be null + * @param objectToFind the object to find, may be null + * @return the last index of the object within the array, + * -1 if not found or null array input + */ + public static int lastIndexOf(final Object[] array, final Object objectToFind) { + return lastIndexOf(array, objectToFind, Integer.MAX_VALUE); + } + + /** + *

Find the last index of the given object in the array starting at the given index.

+ * + *

This method returns -1 if null array input.

+ * + *

A negative startIndex will return -1. A startIndex larger than + * the array length will search from the end of the array.

+ * + * @param array the array to traverse for looking for the object, may be null + * @param objectToFind the object to find, may be null + * @param startIndex the start index to travers backwards from + * @return the last index of the object within the array, + * -1 if not found or null array input + */ + public static int lastIndexOf(final Object[] array, final Object objectToFind, int startIndex) { + if (array == null) { + return -1; + } + if (startIndex < 0) { + return -1; + } else if (startIndex >= array.length) { + startIndex = array.length - 1; + } + if (objectToFind == null) { + for (int i = startIndex; i >= 0; i--) { + if (array[i] == null) { + return i; + } + } + } else { + for (int i = startIndex; i >= 0; i--) { + if (objectToFind.equals(array[i])) { + return i; + } + } + } + return -1; + } + + /** + *

Checks if the object is in the given array.

+ * + *

The method returns false if a null array is passed in.

+ * + * @param array the array to search through + * @param objectToFind the object to find + * @return true if the array contains the object + */ + public static boolean contains(final Object[] array, final Object objectToFind) { + return (indexOf(array, objectToFind) != -1); + } + + // long IndexOf + //----------------------------------------------------------------------- + /** + *

Find the index of the given value in the array.

+ * + *

This method returns -1 if null array input.

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @return the index of the value within the array, + * -1 if not found or null array input + */ + public static int indexOf(final long[] array, final long valueToFind) { + return indexOf(array, valueToFind, 0); + } + + /** + *

Find the index of the given value in the array starting at the given index.

+ * + *

This method returns -1 if null array input.

+ * + *

A negative startIndex is treated as zero. A startIndex larger than the array + * length will return -1.

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @param startIndex the index to start searching at + * @return the index of the value within the array, + * -1 if not found or null array input + */ + public static int indexOf(final long[] array, final long valueToFind, int startIndex) { + if (array == null) { + return -1; + } + if (startIndex < 0) { + startIndex = 0; + } + for (int i = startIndex; i < array.length; i++) { + if (valueToFind == array[i]) { + return i; + } + } + return -1; + } + + /** + *

Find the last index of the given value within the array.

+ * + *

This method returns -1 if null array input.

+ * + * @param array the array to travers backwords looking for the object, may be null + * @param valueToFind the object to find + * @return the last index of the value within the array, + * -1 if not found or null array input + */ + public static int lastIndexOf(final long[] array, final long valueToFind) { + return lastIndexOf(array, valueToFind, Integer.MAX_VALUE); + } + + /** + *

Find the last index of the given value in the array starting at the given index.

+ * + *

This method returns -1 if null array input.

+ * + *

A negative startIndex will return -1. A startIndex larger than the array + * length will search from the end of the array.

+ * + * @param array the array to traverse for looking for the object, may be null + * @param valueToFind the value to find + * @param startIndex the start index to travers backwards from + * @return the last index of the value within the array, + * -1 if not found or null array input + */ + public static int lastIndexOf(final long[] array, final long valueToFind, int startIndex) { + if (array == null) { + return -1; + } + if (startIndex < 0) { + return -1; + } else if (startIndex >= array.length) { + startIndex = array.length - 1; + } + for (int i = startIndex; i >= 0; i--) { + if (valueToFind == array[i]) { + return i; + } + } + return -1; + } + + /** + *

Checks if the value is in the given array.

+ * + *

The method returns false if a null array is passed in.

+ * + * @param array the array to search through + * @param valueToFind the value to find + * @return true if the array contains the object + */ + public static boolean contains(final long[] array, final long valueToFind) { + return (indexOf(array, valueToFind) != -1); + } + + // int IndexOf + //----------------------------------------------------------------------- + /** + *

Find the index of the given value in the array.

+ * + *

This method returns -1 if null array input.

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @return the index of the value within the array, + * -1 if not found or null array input + */ + public static int indexOf(final int[] array, final int valueToFind) { + return indexOf(array, valueToFind, 0); + } + + /** + *

Find the index of the given value in the array starting at the given index.

+ * + *

This method returns -1 if null array input.

+ * + *

A negative startIndex is treated as zero. A startIndex larger than the array + * length will return -1.

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @param startIndex the index to start searching at + * @return the index of the value within the array, + * -1 if not found or null array input + */ + public static int indexOf(final int[] array, final int valueToFind, int startIndex) { + if (array == null) { + return -1; + } + if (startIndex < 0) { + startIndex = 0; + } + for (int i = startIndex; i < array.length; i++) { + if (valueToFind == array[i]) { + return i; + } + } + return -1; + } + + /** + *

Find the last index of the given value within the array.

+ * + *

This method returns -1 if null array input.

+ * + * @param array the array to travers backwords looking for the object, may be null + * @param valueToFind the object to find + * @return the last index of the value within the array, + * -1 if not found or null array input + */ + public static int lastIndexOf(final int[] array, final int valueToFind) { + return lastIndexOf(array, valueToFind, Integer.MAX_VALUE); + } + + /** + *

Find the last index of the given value in the array starting at the given index.

+ * + *

This method returns -1 if null array input.

+ * + *

A negative startIndex will return -1. A startIndex larger than the array + * length will search from the end of the array.

+ * + * @param array the array to traverse for looking for the object, may be null + * @param valueToFind the value to find + * @param startIndex the start index to travers backwards from + * @return the last index of the value within the array, + * -1 if not found or null array input + */ + public static int lastIndexOf(final int[] array, final int valueToFind, int startIndex) { + if (array == null) { + return -1; + } + if (startIndex < 0) { + return -1; + } else if (startIndex >= array.length) { + startIndex = array.length - 1; + } + for (int i = startIndex; i >= 0; i--) { + if (valueToFind == array[i]) { + return i; + } + } + return -1; + } + + /** + *

Checks if the value is in the given array.

+ * + *

The method returns false if a null array is passed in.

+ * + * @param array the array to search through + * @param valueToFind the value to find + * @return true if the array contains the object + */ + public static boolean contains(final int[] array, final int valueToFind) { + return (indexOf(array, valueToFind) != -1); + } + + // short IndexOf + //----------------------------------------------------------------------- + /** + *

Find the index of the given value in the array.

+ * + *

This method returns -1 if null array input.

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @return the index of the value within the array, + * -1 if not found or null array input + */ + public static int indexOf(final short[] array, final short valueToFind) { + return indexOf(array, valueToFind, 0); + } + + /** + *

Find the index of the given value in the array starting at the given index.

+ * + *

This method returns -1 if null array input.

+ * + *

A negative startIndex is treated as zero. A startIndex larger than the array + * length will return -1.

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @param startIndex the index to start searching at + * @return the index of the value within the array, + * -1 if not found or null array input + */ + public static int indexOf(final short[] array, final short valueToFind, int startIndex) { + if (array == null) { + return -1; + } + if (startIndex < 0) { + startIndex = 0; + } + for (int i = startIndex; i < array.length; i++) { + if (valueToFind == array[i]) { + return i; + } + } + return -1; + } + + /** + *

Find the last index of the given value within the array.

+ * + *

This method returns -1 if null array input.

+ * + * @param array the array to travers backwords looking for the object, may be null + * @param valueToFind the object to find + * @return the last index of the value within the array, + * -1 if not found or null array input + */ + public static int lastIndexOf(final short[] array, final short valueToFind) { + return lastIndexOf(array, valueToFind, Integer.MAX_VALUE); + } + + /** + *

Find the last index of the given value in the array starting at the given index.

+ * + *

This method returns -1 if null array input.

+ * + *

A negative startIndex will return -1. A startIndex larger than the array + * length will search from the end of the array.

+ * + * @param array the array to traverse for looking for the object, may be null + * @param valueToFind the value to find + * @param startIndex the start index to travers backwards from + * @return the last index of the value within the array, + * -1 if not found or null array input + */ + public static int lastIndexOf(final short[] array, final short valueToFind, int startIndex) { + if (array == null) { + return -1; + } + if (startIndex < 0) { + return -1; + } else if (startIndex >= array.length) { + startIndex = array.length - 1; + } + for (int i = startIndex; i >= 0; i--) { + if (valueToFind == array[i]) { + return i; + } + } + return -1; + } + + /** + *

Checks if the value is in the given array.

+ * + *

The method returns false if a null array is passed in.

+ * + * @param array the array to search through + * @param valueToFind the value to find + * @return true if the array contains the object + */ + public static boolean contains(final short[] array, final short valueToFind) { + return (indexOf(array, valueToFind) != -1); + } + + // byte IndexOf + //----------------------------------------------------------------------- + /** + *

Find the index of the given value in the array.

+ * + *

This method returns -1 if null array input.

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @return the index of the value within the array, + * -1 if not found or null array input + */ + public static int indexOf(final byte[] array, final byte valueToFind) { + return indexOf(array, valueToFind, 0); + } + + /** + *

Find the index of the given value in the array starting at the given index.

+ * + *

This method returns -1 if null array input.

+ * + *

A negative startIndex is treated as zero. A startIndex larger than the array + * length will return -1.

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @param startIndex the index to start searching at + * @return the index of the value within the array, + * -1 if not found or null array input + */ + public static int indexOf(final byte[] array, final byte valueToFind, int startIndex) { + if (array == null) { + return -1; + } + if (startIndex < 0) { + startIndex = 0; + } + for (int i = startIndex; i < array.length; i++) { + if (valueToFind == array[i]) { + return i; + } + } + return -1; + } + + /** + *

Find the last index of the given value within the array.

+ * + *

This method returns -1 if null array input.

+ * + * @param array the array to travers backwords looking for the object, may be null + * @param valueToFind the object to find + * @return the last index of the value within the array, + * -1 if not found or null array input + */ + public static int lastIndexOf(final byte[] array, final byte valueToFind) { + return lastIndexOf(array, valueToFind, Integer.MAX_VALUE); + } + + /** + *

Find the last index of the given value in the array starting at the given index.

+ * + *

This method returns -1 if null array input.

+ * + *

A negative startIndex will return -1. A startIndex larger than the array + * length will search from the end of the array.

+ * + * @param array the array to traverse for looking for the object, may be null + * @param valueToFind the value to find + * @param startIndex the start index to travers backwards from + * @return the last index of the value within the array, + * -1 if not found or null array input + */ + public static int lastIndexOf(final byte[] array, final byte valueToFind, int startIndex) { + if (array == null) { + return -1; + } + if (startIndex < 0) { + return -1; + } else if (startIndex >= array.length) { + startIndex = array.length - 1; + } + for (int i = startIndex; i >= 0; i--) { + if (valueToFind == array[i]) { + return i; + } + } + return -1; + } + + /** + *

Checks if the value is in the given array.

+ * + *

The method returns false if a null array is passed in.

+ * + * @param array the array to search through + * @param valueToFind the value to find + * @return true if the array contains the object + */ + public static boolean contains(final byte[] array, final byte valueToFind) { + return (indexOf(array, valueToFind) != -1); + } + + // double IndexOf + //----------------------------------------------------------------------- + /** + *

Find the index of the given value in the array.

+ * + *

This method returns -1 if null array input.

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @return the index of the value within the array, + * -1 if not found or null array input + */ + public static int indexOf(final double[] array, final double valueToFind) { + return indexOf(array, valueToFind, 0); + } + + /** + *

Find the index of the given value within a given tolerance in the array. + * This method will return the index of the first value which falls between the region + * defined by valueToFind - tolerance and valueToFind + tolerance.

+ * + *

This method returns -1 if null array input.

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @param tolerance tolerance of the search + * @return the index of the value within the array, + * -1 if not found or null array input + */ + public static int indexOf(final double[] array, final double valueToFind, final double tolerance) { + return indexOf(array, valueToFind, 0, tolerance); + } + + /** + *

Find the index of the given value in the array starting at the given index.

+ * + *

This method returns -1 if null array input.

+ * + *

A negative startIndex is treated as zero. A startIndex larger than the array + * length will return -1.

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @param startIndex the index to start searching at + * @return the index of the value within the array, + * -1 if not found or null array input + */ + public static int indexOf(final double[] array, final double valueToFind, int startIndex) { + if (array == null || array.length == 0) { + return -1; + } + if (startIndex < 0) { + startIndex = 0; + } + for (int i = startIndex; i < array.length; i++) { + if (valueToFind == array[i]) { + return i; + } + } + return -1; + } + + /** + *

Find the index of the given value in the array starting at the given index. + * This method will return the index of the first value which falls between the region + * defined by valueToFind - tolerance and valueToFind + tolerance.

+ * + *

This method returns -1 if null array input.

+ * + *

A negative startIndex is treated as zero. A startIndex larger than the array + * length will return -1.

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @param startIndex the index to start searching at + * @param tolerance tolerance of the search + * @return the index of the value within the array, + * -1 if not found or null array input + */ + public static int indexOf(final double[] array, final double valueToFind, int startIndex, double tolerance) { + if (array == null || array.length == 0) { + return -1; + } + if (startIndex < 0) { + startIndex = 0; + } + double min = valueToFind - tolerance; + double max = valueToFind + tolerance; + for (int i = startIndex; i < array.length; i++) { + if (array[i] >= min && array[i] <= max) { + return i; + } + } + return -1; + } + + /** + *

Find the last index of the given value within the array.

+ * + *

This method returns -1 if null array input.

+ * + * @param array the array to travers backwords looking for the object, may be null + * @param valueToFind the object to find + * @return the last index of the value within the array, + * -1 if not found or null array input + */ + public static int lastIndexOf(final double[] array, final double valueToFind) { + return lastIndexOf(array, valueToFind, Integer.MAX_VALUE); + } + + /** + *

Find the last index of the given value within a given tolerance in the array. + * This method will return the index of the last value which falls between the region + * defined by valueToFind - tolerance and valueToFind + tolerance.

+ * + *

This method returns -1 if null array input.

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @param tolerance tolerance of the search + * @return the index of the value within the array, + * -1 if not found or null array input + */ + public static int lastIndexOf(final double[] array, final double valueToFind, final double tolerance) { + return lastIndexOf(array, valueToFind, Integer.MAX_VALUE, tolerance); + } + + /** + *

Find the last index of the given value in the array starting at the given index.

+ * + *

This method returns -1 if null array input.

+ * + *

A negative startIndex will return -1. A startIndex larger than the array + * length will search from the end of the array.

+ * + * @param array the array to traverse for looking for the object, may be null + * @param valueToFind the value to find + * @param startIndex the start index to travers backwards from + * @return the last index of the value within the array, + * -1 if not found or null array input + */ + public static int lastIndexOf(final double[] array, final double valueToFind, int startIndex) { + if (array == null || array.length == 0) { + return -1; + } + if (startIndex < 0) { + return -1; + } else if (startIndex >= array.length) { + startIndex = array.length - 1; + } + for (int i = startIndex; i >= 0; i--) { + if (valueToFind == array[i]) { + return i; + } + } + return -1; + } + + /** + *

Find the last index of the given value in the array starting at the given index. + * This method will return the index of the last value which falls between the region + * defined by valueToFind - tolerance and valueToFind + tolerance.

+ * + *

This method returns -1 if null array input.

+ * + *

A negative startIndex will return -1. A startIndex larger than the array + * length will search from the end of the array.

+ * + * @param array the array to traverse for looking for the object, may be null + * @param valueToFind the value to find + * @param startIndex the start index to travers backwards from + * @param tolerance search for value within plus/minus this amount + * @return the last index of the value within the array, + * -1 if not found or null array input + */ + public static int lastIndexOf(final double[] array, final double valueToFind, int startIndex, double tolerance) { + if (array == null || array.length == 0) { + return -1; + } + if (startIndex < 0) { + return -1; + } else if (startIndex >= array.length) { + startIndex = array.length - 1; + } + double min = valueToFind - tolerance; + double max = valueToFind + tolerance; + for (int i = startIndex; i >= 0; i--) { + if (array[i] >= min && array[i] <= max) { + return i; + } + } + return -1; + } + + /** + *

Checks if the value is in the given array.

+ * + *

The method returns false if a null array is passed in.

+ * + * @param array the array to search through + * @param valueToFind the value to find + * @return true if the array contains the object + */ + public static boolean contains(final double[] array, final double valueToFind) { + return (indexOf(array, valueToFind) != -1); + } + + /** + *

Checks if a value falling within the given tolerance is in the + * given array. If the array contains a value within the inclusive range + * defined by (value - tolerance) to (value + tolerance).

+ * + *

The method returns false if a null array + * is passed in.

+ * + * @param array the array to search + * @param valueToFind the value to find + * @param tolerance the array contains the tolerance of the search + * @return true if value falling within tolerance is in array + */ + public static boolean contains(final double[] array, final double valueToFind, final double tolerance) { + return (indexOf(array, valueToFind, 0, tolerance) != -1); + } + + // float IndexOf + //----------------------------------------------------------------------- + /** + *

Find the index of the given value in the array.

+ * + *

This method returns -1 if null array input.

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @return the index of the value within the array, + * -1 if not found or null array input + */ + public static int indexOf(final float[] array, final float valueToFind) { + return indexOf(array, valueToFind, 0); + } + + /** + *

Find the index of the given value in the array starting at the given index.

+ * + *

This method returns -1 if null array input.

+ * + *

A negative startIndex is treated as zero. A startIndex larger than the array + * length will return -1.

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @param startIndex the index to start searching at + * @return the index of the value within the array, + * -1 if not found or null array input + */ + public static int indexOf(final float[] array, final float valueToFind, int startIndex) { + if (array == null || array.length == 0) { + return -1; + } + if (startIndex < 0) { + startIndex = 0; + } + for (int i = startIndex; i < array.length; i++) { + if (valueToFind == array[i]) { + return i; + } + } + return -1; + } + + /** + *

Find the last index of the given value within the array.

+ * + *

This method returns -1 if null array input.

+ * + * @param array the array to travers backwords looking for the object, may be null + * @param valueToFind the object to find + * @return the last index of the value within the array, + * -1 if not found or null array input + */ + public static int lastIndexOf(final float[] array, final float valueToFind) { + return lastIndexOf(array, valueToFind, Integer.MAX_VALUE); + } + + /** + *

Find the last index of the given value in the array starting at the given index.

+ * + *

This method returns -1 if null array input.

+ * + *

A negative startIndex will return -1. A startIndex larger than the array + * length will search from the end of the array.

+ * + * @param array the array to traverse for looking for the object, may be null + * @param valueToFind the value to find + * @param startIndex the start index to travers backwards from + * @return the last index of the value within the array, + * -1 if not found or null array input + */ + public static int lastIndexOf(final float[] array, final float valueToFind, int startIndex) { + if (array == null || array.length == 0) { + return -1; + } + if (startIndex < 0) { + return -1; + } else if (startIndex >= array.length) { + startIndex = array.length - 1; + } + for (int i = startIndex; i >= 0; i--) { + if (valueToFind == array[i]) { + return i; + } + } + return -1; + } + + /** + *

Checks if the value is in the given array.

+ * + *

The method returns false if a null array is passed in.

+ * + * @param array the array to search through + * @param valueToFind the value to find + * @return true if the array contains the object + */ + public static boolean contains(final float[] array, final float valueToFind) { + return (indexOf(array, valueToFind) != -1); + } + + // boolean IndexOf + //----------------------------------------------------------------------- + /** + *

Find the index of the given value in the array.

+ * + *

This method returns -1 if null array input.

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @return the index of the value within the array, + * -1 if not found or null array input + */ + public static int indexOf(final boolean[] array, final boolean valueToFind) { + return indexOf(array, valueToFind, 0); + } + + /** + *

Find the index of the given value in the array starting at the given index.

+ * + *

This method returns -1 if null array input.

+ * + *

A negative startIndex is treated as zero. A startIndex larger than the array + * length will return -1.

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @param startIndex the index to start searching at + * @return the index of the value within the array, + * -1 if not found or null array input + */ + public static int indexOf(final boolean[] array, final boolean valueToFind, int startIndex) { + if (array == null || array.length == 0) { + return -1; + } + if (startIndex < 0) { + startIndex = 0; + } + for (int i = startIndex; i < array.length; i++) { + if (valueToFind == array[i]) { + return i; + } + } + return -1; + } + + /** + *

Find the last index of the given value within the array.

+ * + *

This method returns -1 if null array input.

+ * + * @param array the array to travers backwords looking for the object, may be null + * @param valueToFind the object to find + * @return the last index of the value within the array, + * -1 if not found or null array input + */ + public static int lastIndexOf(final boolean[] array, final boolean valueToFind) { + return lastIndexOf(array, valueToFind, Integer.MAX_VALUE); + } + + /** + *

Find the last index of the given value in the array starting at the given index.

+ * + *

This method returns -1 if null array input.

+ * + *

A negative startIndex will return -1. A startIndex larger than the array + * length will search from the end of the array.

+ * + * @param array the array to traverse for looking for the object, may be null + * @param valueToFind the value to find + * @param startIndex the start index to travers backwards from + * @return the last index of the value within the array, + * -1 if not found or null array input + */ + public static int lastIndexOf(final boolean[] array, final boolean valueToFind, int startIndex) { + if (array == null || array.length == 0) { + return -1; + } + if (startIndex < 0) { + return -1; + } else if (startIndex >= array.length) { + startIndex = array.length - 1; + } + for (int i = startIndex; i >= 0; i--) { + if (valueToFind == array[i]) { + return i; + } + } + return -1; + } + + /** + *

Checks if the value is in the given array.

+ * + *

The method returns false if a null array is passed in.

+ * + * @param array the array to search through + * @param valueToFind the value to find + * @return true if the array contains the object + */ + public static boolean contains(final boolean[] array, final boolean valueToFind) { + return (indexOf(array, valueToFind) != -1); + } + + // Primitive/Object array converters + // ---------------------------------------------------------------------- + + // Long array converters + // ---------------------------------------------------------------------- + /** + *

Converts an array of object Longs to primitives.

+ * + *

This method returns null if null array input.

+ * + * @param array a Long array, may be null + * @return a long array, null if null array input + * @throws NullPointerException if array content is null + */ + public static long[] toPrimitive(final Long[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_LONG_ARRAY; + } + final long[] result = new long[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = array[i].longValue(); + } + return result; + } + + /** + *

Converts an array of object Long to primitives handling null.

+ * + *

This method returns null if null array input.

+ * + * @param array a Long array, may be null + * @param valueForNull the value to insert if null found + * @return a long array, null if null array input + */ + public static long[] toPrimitive(final Long[] array, final long valueForNull) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_LONG_ARRAY; + } + final long[] result = new long[array.length]; + for (int i = 0; i < array.length; i++) { + Long b = array[i]; + result[i] = (b == null ? valueForNull : b.longValue()); + } + return result; + } + + /** + *

Converts an array of primitive longs to objects.

+ * + *

This method returns null if null array input.

+ * + * @param array a long array + * @return a Long array, null if null array input + */ + public static Long[] toObject(final long[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_LONG_OBJECT_ARRAY; + } + final Long[] result = new Long[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = new Long(array[i]); + } + return result; + } + + // Int array converters + // ---------------------------------------------------------------------- + /** + *

Converts an array of object Integers to primitives.

+ * + *

This method returns null if null array input.

+ * + * @param array a Integer array, may be null + * @return an int array, null if null array input + * @throws NullPointerException if array content is null + */ + public static int[] toPrimitive(final Integer[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_INT_ARRAY; + } + final int[] result = new int[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = array[i].intValue(); + } + return result; + } + + /** + *

Converts an array of object Integer to primitives handling null.

+ * + *

This method returns null if null array input.

+ * + * @param array a Integer array, may be null + * @param valueForNull the value to insert if null found + * @return an int array, null if null array input + */ + public static int[] toPrimitive(final Integer[] array, final int valueForNull) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_INT_ARRAY; + } + final int[] result = new int[array.length]; + for (int i = 0; i < array.length; i++) { + Integer b = array[i]; + result[i] = (b == null ? valueForNull : b.intValue()); + } + return result; + } + + /** + *

Converts an array of primitive ints to objects.

+ * + *

This method returns null if null array input.

+ * + * @param array an int array + * @return an Integer array, null if null array input + */ + public static Integer[] toObject(final int[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_INTEGER_OBJECT_ARRAY; + } + final Integer[] result = new Integer[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = new Integer(array[i]); + } + return result; + } + + // Short array converters + // ---------------------------------------------------------------------- + /** + *

Converts an array of object Shorts to primitives.

+ * + *

This method returns null if null array input.

+ * + * @param array a Short array, may be null + * @return a byte array, null if null array input + * @throws NullPointerException if array content is null + */ + public static short[] toPrimitive(final Short[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_SHORT_ARRAY; + } + final short[] result = new short[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = array[i].shortValue(); + } + return result; + } + + /** + *

Converts an array of object Short to primitives handling null.

+ * + *

This method returns null if null array input.

+ * + * @param array a Short array, may be null + * @param valueForNull the value to insert if null found + * @return a byte array, null if null array input + */ + public static short[] toPrimitive(final Short[] array, final short valueForNull) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_SHORT_ARRAY; + } + final short[] result = new short[array.length]; + for (int i = 0; i < array.length; i++) { + Short b = array[i]; + result[i] = (b == null ? valueForNull : b.shortValue()); + } + return result; + } + + /** + *

Converts an array of primitive shorts to objects.

+ * + *

This method returns null if null array input.

+ * + * @param array a short array + * @return a Short array, null if null array input + */ + public static Short[] toObject(final short[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_SHORT_OBJECT_ARRAY; + } + final Short[] result = new Short[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = new Short(array[i]); + } + return result; + } + + // Byte array converters + // ---------------------------------------------------------------------- + /** + *

Converts an array of object Bytes to primitives.

+ * + *

This method returns null if null array input.

+ * + * @param array a Byte array, may be null + * @return a byte array, null if null array input + * @throws NullPointerException if array content is null + */ + public static byte[] toPrimitive(final Byte[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_BYTE_ARRAY; + } + final byte[] result = new byte[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = array[i].byteValue(); + } + return result; + } + + /** + *

Converts an array of object Bytes to primitives handling null.

+ * + *

This method returns null if null array input.

+ * + * @param array a Byte array, may be null + * @param valueForNull the value to insert if null found + * @return a byte array, null if null array input + */ + public static byte[] toPrimitive(final Byte[] array, final byte valueForNull) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_BYTE_ARRAY; + } + final byte[] result = new byte[array.length]; + for (int i = 0; i < array.length; i++) { + Byte b = array[i]; + result[i] = (b == null ? valueForNull : b.byteValue()); + } + return result; + } + + /** + *

Converts an array of primitive bytes to objects.

+ * + *

This method returns null if null array input.

+ * + * @param array a byte array + * @return a Byte array, null if null array input + */ + public static Byte[] toObject(final byte[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_BYTE_OBJECT_ARRAY; + } + final Byte[] result = new Byte[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = new Byte(array[i]); + } + return result; + } + + // Double array converters + // ---------------------------------------------------------------------- + /** + *

Converts an array of object Doubles to primitives.

+ * + *

This method returns null if null array input.

+ * + * @param array a Double array, may be null + * @return a double array, null if null array input + * @throws NullPointerException if array content is null + */ + public static double[] toPrimitive(final Double[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_DOUBLE_ARRAY; + } + final double[] result = new double[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = array[i].doubleValue(); + } + return result; + } + + /** + *

Converts an array of object Doubles to primitives handling null.

+ * + *

This method returns null if null array input.

+ * + * @param array a Double array, may be null + * @param valueForNull the value to insert if null found + * @return a double array, null if null array input + */ + public static double[] toPrimitive(final Double[] array, final double valueForNull) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_DOUBLE_ARRAY; + } + final double[] result = new double[array.length]; + for (int i = 0; i < array.length; i++) { + Double b = array[i]; + result[i] = (b == null ? valueForNull : b.doubleValue()); + } + return result; + } + + /** + *

Converts an array of primitive doubles to objects.

+ * + *

This method returns null if null array input.

+ * + * @param array a double array + * @return a Double array, null if null array input + */ + public static Double[] toObject(final double[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_DOUBLE_OBJECT_ARRAY; + } + final Double[] result = new Double[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = new Double(array[i]); + } + return result; + } + + // Float array converters + // ---------------------------------------------------------------------- + /** + *

Converts an array of object Floats to primitives.

+ * + *

This method returns null if null array input.

+ * + * @param array a Float array, may be null + * @return a float array, null if null array input + * @throws NullPointerException if array content is null + */ + public static float[] toPrimitive(final Float[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_FLOAT_ARRAY; + } + final float[] result = new float[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = array[i].floatValue(); + } + return result; + } + + /** + *

Converts an array of object Floats to primitives handling null.

+ * + *

This method returns null if null array input.

+ * + * @param array a Float array, may be null + * @param valueForNull the value to insert if null found + * @return a float array, null if null array input + */ + public static float[] toPrimitive(final Float[] array, final float valueForNull) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_FLOAT_ARRAY; + } + final float[] result = new float[array.length]; + for (int i = 0; i < array.length; i++) { + Float b = array[i]; + result[i] = (b == null ? valueForNull : b.floatValue()); + } + return result; + } + + /** + *

Converts an array of primitive floats to objects.

+ * + *

This method returns null if null array input.

+ * + * @param array a float array + * @return a Float array, null if null array input + */ + public static Float[] toObject(final float[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_FLOAT_OBJECT_ARRAY; + } + final Float[] result = new Float[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = new Float(array[i]); + } + return result; + } + + // Boolean array converters + // ---------------------------------------------------------------------- + /** + *

Converts an array of object Booleans to primitives.

+ * + *

This method returns null if null array input.

+ * + * @param array a Boolean array, may be null + * @return a boolean array, null if null array input + * @throws NullPointerException if array content is null + */ + public static boolean[] toPrimitive(final Boolean[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_BOOLEAN_ARRAY; + } + final boolean[] result = new boolean[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = array[i].booleanValue(); + } + return result; + } + + /** + *

Converts an array of object Booleans to primitives handling null.

+ * + *

This method returns null if null array input.

+ * + * @param array a Boolean array, may be null + * @param valueForNull the value to insert if null found + * @return a boolean array, null if null array input + */ + public static boolean[] toPrimitive(final Boolean[] array, final boolean valueForNull) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_BOOLEAN_ARRAY; + } + final boolean[] result = new boolean[array.length]; + for (int i = 0; i < array.length; i++) { + Boolean b = array[i]; + result[i] = (b == null ? valueForNull : b.booleanValue()); + } + return result; + } + + /** + *

Converts an array of primitive booleans to objects.

+ * + *

This method returns null if null array input.

+ * + * @param array a boolean array + * @return a Boolean array, null if null array input + */ + public static Boolean[] toObject(final boolean[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_BOOLEAN_OBJECT_ARRAY; + } + final Boolean[] result = new Boolean[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = (array[i] ? Boolean.TRUE : Boolean.FALSE); + } + return result; + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/BitField.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/BitField.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/BitField.java 30 Aug 2012 16:24:42 -0000 1.1 @@ -0,0 +1,327 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang; + +/** + *

Operations on bit-mapped fields.

+ * + * @author Apache Jakarta POI + * @author Scott Sanders (sanders at apache dot org) + * @author Marc Johnson (mjohnson at apache dot org) + * @author Andrew C. Oliver (acoliver at apache dot org) + * @author Stephen Colebourne + * @author Pete Gieser + * @author Gary Gregory + * @since 2.0 + * @version $Id: BitField.java,v 1.1 2012/08/30 16:24:42 marcin Exp $ + */ +public class BitField { + + private final int _mask; + private final int _shift_count; + + /** + *

Creates a BitField instance.

+ * + * @param mask the mask specifying which bits apply to this + * BitField. Bits that are set in this mask are the bits + * that this BitField operates on + */ + public BitField(final int mask) { + _mask = mask; + int count = 0; + int bit_pattern = mask; + + if (bit_pattern != 0) { + while ((bit_pattern & 1) == 0) { + count++; + bit_pattern >>= 1; + } + } + _shift_count = count; + } + + /** + *

Obtains the value for the specified BitField, appropriately + * shifted right.

+ * + *

Many users of a BitField will want to treat the specified + * bits as an int value, and will not want to be aware that the + * value is stored as a BitField (and so shifted left so many + * bits).

+ * + * @see #setValue + * @param holder the int data containing the bits we're interested + * in + * @return the selected bits, shifted right appropriately + */ + public int getValue(final int holder) { + return getRawValue(holder) >> _shift_count; + } + + /** + *

Obtains the value for the specified BitField, appropriately + * shifted right, as a short.

+ * + *

Many users of a BitField will want to treat the specified + * bits as an int value, and will not want to be aware that the + * value is stored as a BitField (and so shifted left so many + * bits).

+ * + * @see #setShortValue + * @param holder the short data containing the bits we're + * interested in + * @return the selected bits, shifted right appropriately + */ + public short getShortValue(final short holder) { + return (short) getValue(holder); + } + + /** + *

Obtains the value for the specified BitField, unshifted.

+ * + * @param holder the int data containing the bits we're + * interested in + * @return the selected bits + */ + public int getRawValue(final int holder) { + return (holder & _mask); + } + + /** + *

Obtains the value for the specified BitField, unshifted.

+ * + * @param holder the short data containing the bits we're + * interested in + * @return the selected bits + */ + public short getShortRawValue(final short holder) { + return (short) getRawValue(holder); + } + + /** + *

Returns whether the field is set or not.

+ * + *

This is most commonly used for a single-bit field, which is + * often used to represent a boolean value; the results of using + * it for a multi-bit field is to determine whether *any* of its + * bits are set.

+ * + * @param holder the int data containing the bits we're interested + * in + * @return true if any of the bits are set, + * else false + */ + public boolean isSet(final int holder) { + return (holder & _mask) != 0; + } + + /** + *

Returns whether all of the bits are set or not.

+ * + *

This is a stricter test than {@link #isSet(int)}, + * in that all of the bits in a multi-bit set must be set + * for this method to return true.

+ * + * @param holder the int data containing the bits we're + * interested in + * @return true if all of the bits are set, + * else false + */ + public boolean isAllSet(final int holder) { + return (holder & _mask) == _mask; + } + + /** + *

Replaces the bits with new values.

+ * + * @see #getValue + * @param holder the int data containint the bits we're + * interested in + * @param value the new value for the specified bits + * @return the value of holder with the bits from the value + * parameter replacing the old bits + */ + public int setValue(final int holder, final int value) { + return (holder & ~_mask) | ((value << _shift_count) & _mask); + } + + /** + *

Replaces the bits with new values.

+ * + * @see #getShortValue + * @param holder the short data containing the bits we're + * interested in + * @param value the new value for the specified bits + * @return the value of holder with the bits from the value + * parameter replacing the old bits + */ + public short setShortValue(final short holder, final short value) { + return (short) setValue(holder, value); + } + + /** + *

Clears the bits.

+ * + * @param holder the int data containing the bits we're + * interested in + * @return the value of holder with the specified bits cleared + * (set to 0) + */ + public int clear(final int holder) { + return holder & ~_mask; + } + + /** + *

Clears the bits.

+ * + * @param holder the short data containing the bits we're + * interested in + * @return the value of holder with the specified bits cleared + * (set to 0) + */ + public short clearShort(final short holder) { + return (short) clear(holder); + } + + /** + *

Clears the bits.

+ * + * @param holder the byte data containing the bits we're + * interested in + * + * @return the value of holder with the specified bits cleared + * (set to 0) + */ + public byte clearByte(final byte holder) { + return (byte) clear(holder); + } + + /** + *

Sets the bits.

+ * + * @param holder the int data containing the bits we're + * interested in + * @return the value of holder with the specified bits set + * to 1 + */ + public int set(final int holder) { + return holder | _mask; + } + + /** + *

Sets the bits.

+ * + * @param holder the short data containing the bits we're + * interested in + * @return the value of holder with the specified bits set + * to 1 + */ + public short setShort(final short holder) { + return (short) set(holder); + } + + /** + *

Sets the bits.

+ * + * @param holder the byte data containing the bits we're + * interested in + * + * @return the value of holder with the specified bits set + * to 1 + */ + public byte setByte(final byte holder) { + return (byte) set(holder); + } + + /** + *

Sets a boolean BitField.

+ * + * @param holder the int data containing the bits we're + * interested in + * @param flag indicating whether to set or clear the bits + * @return the value of holder with the specified bits set or + * cleared + */ + public int setBoolean(final int holder, final boolean flag) { + return flag ? set(holder) : clear(holder); + } + + /** + *

Sets a boolean BitField.

+ * + * @param holder the short data containing the bits we're + * interested in + * @param flag indicating whether to set or clear the bits + * @return the value of holder with the specified bits set or + * cleared + */ + public short setShortBoolean(final short holder, final boolean flag) { + return flag ? setShort(holder) : clearShort(holder); + } + + /** + *

Sets a boolean BitField.

+ * + * @param holder the byte data containing the bits we're + * interested in + * @param flag indicating whether to set or clear the bits + * @return the value of holder with the specified bits set or + * cleared + */ + public byte setByteBoolean(final byte holder, final boolean flag) { + return flag ? setByte(holder) : clearByte(holder); + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/BooleanUtils.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/BooleanUtils.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/BooleanUtils.java 30 Aug 2012 16:24:42 -0000 1.1 @@ -0,0 +1,676 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang; + +import org.apache.commons.lang.math.NumberUtils; + +/** + *

Operations on boolean primitives and Boolean objects.

+ * + *

This class tries to handle null input gracefully. + * An exception will not be thrown for a null input. + * Each method documents its behaviour in more detail.

+ * + * @author Stephen Colebourne + * @author Matthew Hawthorne + * @author Gary Gregory + * @since 2.0 + * @version $Id: BooleanUtils.java,v 1.1 2012/08/30 16:24:42 marcin Exp $ + */ +public class BooleanUtils { + + /** + *

BooleanUtils instances should NOT be constructed in standard programming. + * Instead, the class should be used as BooleanUtils.toBooleanObject(true);.

+ * + *

This constructor is public to permit tools that require a JavaBean instance + * to operate.

+ */ + public BooleanUtils() { + } + + // Boolean utilities + //-------------------------------------------------------------------------- + /** + *

Negates the specified boolean.

+ * + *

If null is passed in, null will be returned.

+ * + * @param bool the Boolean to negate, may be null + * @return the negated Boolean, or null if null input + */ + public static Boolean negate(Boolean bool) { + if (bool == null) { + return null; + } + return (bool.booleanValue() ? Boolean.FALSE : Boolean.TRUE); + } + + // boolean Boolean methods + //----------------------------------------------------------------------- + /** + *

Boolean factory that avoids creating new Boolean objecs all the time.

+ * + *

This method was added to JDK1.4 but is available here for earlier JDKs.

+ * + * @param bool the boolean to convert + * @return Boolean.TRUE or Boolean.FALSE as appropriate + */ + public static Boolean toBooleanObject(boolean bool) { + return (bool ? Boolean.TRUE : Boolean.FALSE); + } + + /** + *

Converts a Boolean to a boolean handling null + * by returning false.

+ * + * @param bool the boolean to convert + * @return true or false, + * null returns false + */ + public static boolean toBoolean(Boolean bool) { + if (bool == null) { + return false; + } + return (bool.booleanValue() ? true : false); + } + + /** + *

Converts a Boolean to a boolean handling null.

+ * + * @param bool the boolean to convert + * @param valueIfNull the boolean value to return if null + * @return true or false + */ + public static boolean toBooleanDefaultIfNull(Boolean bool, boolean valueIfNull) { + if (bool == null) { + return valueIfNull; + } + return (bool.booleanValue() ? true : false); + } + + // Integer to Boolean methods + //----------------------------------------------------------------------- + /** + *

Converts an int to a boolean using the convention that zero + * is false.

+ * + * @param value the int to convert + * @return true if non-zero, false + * if zero + */ + public static boolean toBoolean(int value) { + return (value == 0 ? false : true); + } + + /** + *

Converts an int to a Boolean using the convention that zero + * is false.

+ * + * @param value the int to convert + * @return Boolean.TRUE if non-zero, Boolean.FALSE if zero, + * null if null + */ + public static Boolean toBooleanObject(int value) { + return (value == 0 ? Boolean.FALSE : Boolean.TRUE); + } + + /** + *

Converts an Integer to a Boolean using the convention that zero + * is false.

+ * + *

null will be converted to null.

+ * + * @param value the Integer to convert + * @return Boolean.TRUE if non-zero, Boolean.FALSE if zero, + * null if null input + */ + public static Boolean toBooleanObject(Integer value) { + if (value == null) { + return null; + } + return (value.intValue() == 0 ? Boolean.FALSE : Boolean.TRUE); + } + + /** + *

Converts an int to a boolean specifying the conversion values.

+ * + * @param value the Integer to convert + * @param trueValue the value to match for true + * @param falseValue the value to match for false + * @return true or false + * @throws IllegalArgumentException if no match + */ + public static boolean toBoolean(int value, int trueValue, int falseValue) { + if (value == trueValue) { + return true; + } else if (value == falseValue) { + return false; + } + // no match + throw new IllegalArgumentException("The Integer did not match either specified value"); + } + + /** + *

Converts an Integer to a boolean specifying the conversion values.

+ * + * @param value the Integer to convert + * @param trueValue the value to match for true, + * may be null + * @param falseValue the value to match for false, + * may be null + * @return true or false + * @throws IllegalArgumentException if no match + */ + public static boolean toBoolean(Integer value, Integer trueValue, Integer falseValue) { + if (value == null) { + if (trueValue == null) { + return true; + } else if (falseValue == null) { + return false; + } + } else if (value.equals(trueValue)) { + return true; + } else if (value.equals(falseValue)) { + return false; + } + // no match + throw new IllegalArgumentException("The Integer did not match either specified value"); + } + + /** + *

Converts an int to a Boolean specifying the conversion values.

+ * + * @param value the Integer to convert + * @param trueValue the value to match for true + * @param falseValue the value to match for false + * @param nullValue the value to to match for null + * @return Boolean.TRUE, Boolean.FALSE, or null + * @throws IllegalArgumentException if no match + */ + public static Boolean toBooleanObject(int value, int trueValue, int falseValue, int nullValue) { + if (value == trueValue) { + return Boolean.TRUE; + } else if (value == falseValue) { + return Boolean.FALSE; + } else if (value == nullValue) { + return null; + } + // no match + throw new IllegalArgumentException("The Integer did not match any specified value"); + } + + /** + *

Converts an Integer to a Boolean specifying the conversion values.

+ * + * @param value the Integer to convert + * @param trueValue the value to match for true, + * may be null + * @param falseValue the value to match for false, + * may be null + * @param nullValue the value to to match for null, + * may be null + * @return Boolean.TRUE, Boolean.FALSE, or null + * @throws IllegalArgumentException if no match + */ + public static Boolean toBooleanObject(Integer value, Integer trueValue, Integer falseValue, Integer nullValue) { + if (value == null) { + if (trueValue == null) { + return Boolean.TRUE; + } else if (falseValue == null) { + return Boolean.FALSE; + } else if (nullValue == null) { + return null; + } + } else if (value.equals(trueValue)) { + return Boolean.TRUE; + } else if (value.equals(falseValue)) { + return Boolean.FALSE; + } else if (value.equals(nullValue)) { + return null; + } + // no match + throw new IllegalArgumentException("The Integer did not match any specified value"); + } + + // Boolean to Integer methods + //----------------------------------------------------------------------- + /** + *

Converts a boolean to an int using the convention that + * zero is false.

+ * + * @param bool the boolean to convert + * @return one if true, zero if false + */ + public static int toInteger(boolean bool) { + return (bool ? 1 : 0); + } + + /** + *

Converts a boolean to an Integer using the convention that + * zero is false.

+ * + * @param bool the boolean to convert + * @return one if true, zero if false + */ + public static Integer toIntegerObject(boolean bool) { + return (bool ? NumberUtils.INTEGER_ONE : NumberUtils.INTEGER_ZERO); + } + + /** + *

Converts a Boolean to a Integer using the convention that + * zero is false.

+ * + *

null will be converted to null.

+ * + * @param bool the Boolean to convert + * @return one if Boolean.TRUE, zero if Boolean.FALSE, null if null + */ + public static Integer toIntegerObject(Boolean bool) { + if (bool == null) { + return null; + } + return (bool.booleanValue() ? NumberUtils.INTEGER_ONE : NumberUtils.INTEGER_ZERO); + } + + /** + *

Converts a boolean to an int specifying the conversion values.

+ * + * @param bool the to convert + * @param trueValue the value to return if true + * @param falseValue the value to return if false + * @return the appropriate value + */ + public static int toInteger(boolean bool, int trueValue, int falseValue) { + return (bool ? trueValue : falseValue); + } + + /** + *

Converts a Boolean to an int specifying the conversion values.

+ * + * @param bool the Boolean to convert + * @param trueValue the value to return if true + * @param falseValue the value to return if false + * @param nullValue the value to return if null + * @return the appropriate value + */ + public static int toInteger(Boolean bool, int trueValue, int falseValue, int nullValue) { + if (bool == null) { + return nullValue; + } + return (bool.booleanValue() ? trueValue : falseValue); + } + + /** + *

Converts a boolean to an Integer specifying the conversion values.

+ * + * @param bool the to convert + * @param trueValue the value to return if true, + * may be null + * @param falseValue the value to return if false, + * may be null + * @return the appropriate value + */ + public static Integer toIntegerObject(boolean bool, Integer trueValue, Integer falseValue) { + return (bool ? trueValue : falseValue); + } + + /** + *

Converts a Boolean to an Integer specifying the conversion values.

+ * + * @param bool the Boolean to convert + * @param trueValue the value to return if true, + * may be null + * @param falseValue the value to return if false, + * may be null + * @param nullValue the value to return if null, + * may be null + * @return the appropriate value + */ + public static Integer toIntegerObject(Boolean bool, Integer trueValue, Integer falseValue, Integer nullValue) { + if (bool == null) { + return nullValue; + } + return (bool.booleanValue() ? trueValue : falseValue); + } + + // String to Boolean methods + //----------------------------------------------------------------------- + /** + *

Converts a String to a Boolean.

+ * + *

'true', 'on' or 'yes' + * (case insensitive) will return true. + * 'false', 'off' or 'no' + * (case insensitive) will return false. + * Otherwise, null is returned.

+ * + * @param str the String to check + * @return the Boolean value of the string, + * null if no match or null input + */ + public static Boolean toBooleanObject(String str) { + if ("true".equalsIgnoreCase(str)) { + return Boolean.TRUE; + } else if ("false".equalsIgnoreCase(str)) { + return Boolean.FALSE; + } else if ("on".equalsIgnoreCase(str)) { + return Boolean.TRUE; + } else if ("off".equalsIgnoreCase(str)) { + return Boolean.FALSE; + } else if ("yes".equalsIgnoreCase(str)) { + return Boolean.TRUE; + } else if ("no".equalsIgnoreCase(str)) { + return Boolean.FALSE; + } + // no match + return null; + } + + /** + *

Converts a String to a Boolean throwing an exception if no match.

+ * + * @param str the String to check + * @param trueString the String to match for true + * (case sensitive), may be null + * @param falseString the String to match for false + * (case sensitive), may be null + * @param nullString the String to match for null + * (case sensitive), may be null + * @return the Boolean value of the string, + * null if no match or null input + */ + public static Boolean toBooleanObject(String str, String trueString, String falseString, String nullString) { + if (str == null) { + if (trueString == null) { + return Boolean.TRUE; + } else if (falseString == null) { + return Boolean.FALSE; + } else if (nullString == null) { + return null; + } + } else if (str.equals(trueString)) { + return Boolean.TRUE; + } else if (str.equals(falseString)) { + return Boolean.FALSE; + } else if (str.equals(nullString)) { + return null; + } + // no match + throw new IllegalArgumentException("The String did not match any specified value"); + } + + // String to boolean methods + //----------------------------------------------------------------------- + /** + *

Converts a String to a boolean.

+ * + *

'true', 'on' or 'yes' + * (case insensitive) will return true. Otherwise, + * false is returned.

+ * + * @param str the String to check + * @return the boolean value of the string, false if no match + */ + public static boolean toBoolean(String str) { + if ("true".equalsIgnoreCase(str)) { + return true; + } else if ("on".equalsIgnoreCase(str)) { + return true; + } else if ("yes".equalsIgnoreCase(str)) { + return true; + } + // no match + return false; + } + + /** + *

Converts a String to a Boolean throwing an exception if no match found.

+ * + *

null is returned if there is no match.

+ * + * @param str the String to check + * @param trueString the String to match for true + * (case sensitive), may be null + * @param falseString the String to match for false + * (case sensitive), may be null + * @return the boolean value of the string + * @throws IllegalArgumentException if the String doesn't match + */ + public static boolean toBoolean(String str, String trueString, String falseString) { + if (str == null) { + if (trueString == null) { + return true; + } else if (falseString == null) { + return false; + } + } else if (str.equals(trueString)) { + return true; + } else if (str.equals(falseString)) { + return false; + } + // no match + throw new IllegalArgumentException("The String did not match either specified value"); + } + + // Boolean to String methods + //----------------------------------------------------------------------- + /** + *

Converts a Boolean to a String returning 'true', + * 'false', or null.

+ * + * @param bool the Boolean to check + * @return 'true', 'false', + * or null + */ + public static String toStringTrueFalse(Boolean bool) { + return toString(bool, "true", "false", null); + } + + /** + *

Converts a Boolean to a String returning 'on', + * 'off', or null.

+ * + * @param bool the Boolean to check + * @return 'on', 'off', + * or null + */ + public static String toStringOnOff(Boolean bool) { + return toString(bool, "on", "off", null); + } + + /** + *

Converts a Boolean to a String returning 'yes', + * 'no', or null.

+ * + * @param bool the Boolean to check + * @return 'yes', 'no', + * or null + */ + public static String toStringYesNo(Boolean bool) { + return toString(bool, "yes", "no", null); + } + + /** + *

Converts a Boolean to a String returning one of the input Strings.

+ * + * @param bool the Boolean to check + * @param trueString the String to return if true, + * may be null + * @param falseString the String to return if false, + * may be null + * @param nullString the String to return if null, + * may be null + * @return one of the three input Strings + */ + public static String toString(Boolean bool, String trueString, String falseString, String nullString) { + if (bool == null) { + return nullString; + } + return (bool.booleanValue() ? trueString : falseString); + } + + // boolean to String methods + //----------------------------------------------------------------------- + /** + *

Converts a boolean to a String returning 'true' + * or 'false'.

+ * + * @param bool the Boolean to check + * @return 'true', 'false', + * or null + */ + public static String toStringTrueFalse(boolean bool) { + return toString(bool, "true", "false"); + } + + /** + *

Converts a boolean to a String returning 'on' + * or 'off'.

+ * + * @param bool the Boolean to check + * @return 'on', 'off', + * or null + */ + public static String toStringOnOff(boolean bool) { + return toString(bool, "on", "off"); + } + + /** + *

Converts a boolean to a String returning 'yes' + * or 'no'.

+ * + * @param bool the Boolean to check + * @return 'yes', 'no', + * or null + */ + public static String toStringYesNo(boolean bool) { + return toString(bool, "yes", "no"); + } + + /** + *

Converts a boolean to a String returning one of the input Strings.

+ * + * @param bool the Boolean to check + * @param trueString the String to return if true, + * may be null + * @param falseString the String to return if false, + * may be null + * @return one of the two input Strings + */ + public static String toString(boolean bool, String trueString, String falseString) { + return (bool ? trueString : falseString); + } + + // xor methods + // ---------------------------------------------------------------------- + /** + *

Performs an xor on a set of booleans.

+ * + * @param array an array of booleans + * @return true if the xor is successful. + * @throws IllegalArgumentException if array is null + * @throws IllegalArgumentException if array is empty. + */ + public static boolean xor(boolean[] array) { + // Validates input + if (array == null) { + throw new IllegalArgumentException("The Array must not be null"); + } else if (array.length == 0) { + throw new IllegalArgumentException("Array is empty"); + } + + // Loops through array, comparing each item + int trueCount = 0; + for (int i = 0; i < array.length; i++) { + // If item is true, and trueCount is < 1, increments count + // Else, xor fails + if (array[i]) { + if (trueCount < 1) { + trueCount++; + } else { + return false; + } + } + } + + // Returns true if there was exactly 1 true item + return trueCount == 1; + } + + /** + *

Performs an xor on an array of Booleans.

+ * + * @param array an array of Booleans + * @return true if the xor is successful. + * @throws IllegalArgumentException if array is null + * @throws IllegalArgumentException if array is empty. + * @throws IllegalArgumentException if array contains a null + */ + public static Boolean xor(Boolean[] array) { + if (array == null) { + throw new IllegalArgumentException("The Array must not be null"); + } else if (array.length == 0) { + throw new IllegalArgumentException("Array is empty"); + } + boolean[] primitive = null; + try { + primitive = ArrayUtils.toPrimitive(array); + } catch (NullPointerException ex) { + throw new IllegalArgumentException("The array must not conatin any null elements"); + } + return (xor(primitive) ? Boolean.TRUE : Boolean.FALSE); + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/CharRange.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/CharRange.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/CharRange.java 30 Aug 2012 16:24:42 -0000 1.1 @@ -0,0 +1,266 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang; + +import java.io.Serializable; + +/** + *

A contiguous range of characters, optionally negated.

+ * + *

Instances are immutable.

+ * + * @author Henri Yandell + * @author Stephen Colebourne + * @author Chris Feldhacker + * @author Gary Gregory + * @since 1.0 + * @version $Id: CharRange.java,v 1.1 2012/08/30 16:24:42 marcin Exp $ + */ +public final class CharRange implements Serializable { + + /** Serialization lock, Lang version 2.0. */ + private static final long serialVersionUID = 8270183163158333422L; + + /** The first character, inclusive, in the range. */ + private final char start; + /** The last character, inclusive, in the range. */ + private final char end; + /** True if the range is everything except the characters specified. */ + private final boolean negated; + + /** Cached toString. */ + private transient String iToString; + + //----------------------------------------------------------------------- + /** + *

Constructs a CharRange over a single character.

+ * + * @param ch only character in this range + */ + public CharRange(char ch) { + this(ch, ch, false); + } + + /** + *

Constructs a CharRange over a single character, + * optionally negating the range.

+ * + *

A negated range includes everything except the specified char.

+ * + * @param ch only character in this range + * @param negated true to express everything except the range + */ + public CharRange(char ch, boolean negated) { + this(ch, ch, negated); + } + + /** + *

Constructs a CharRange over a set of characters.

+ * + * @param start first character, inclusive, in this range + * @param end last character, inclusive, in this range + */ + public CharRange(char start, char end) { + this(start, end, false); + } + + /** + *

Constructs a CharRange over a set of characters, + * optionally negating the range.

+ * + *

A negated range includes everything except that defined by the + * start and end characters.

+ * + *

If start and end are in the wrong order, they are reversed. + * Thus a-e is the same as e-a.

+ * + * @param start first character, inclusive, in this range + * @param end last character, inclusive, in this range + * @param negated true to express everything except the range + */ + public CharRange(char start, char end, boolean negated) { + super(); + if (start > end) { + char temp = start; + start = end; + end = temp; + } + + this.start = start; + this.end = end; + this.negated = negated; + } + + // Accessors + //----------------------------------------------------------------------- + /** + *

Gets the start character for this character range.

+ * + * @return the start char (inclusive) + */ + public char getStart() { + return this.start; + } + + /** + *

Gets the end character for this character range.

+ * + * @return the end char (inclusive) + */ + public char getEnd() { + return this.end; + } + + /** + *

Is this CharRange negated.

+ * + *

A negated range includes everything except that defined by the + * start and end characters.

+ * + * @return true is negated + */ + public boolean isNegated() { + return negated; + } + + // Contains + //----------------------------------------------------------------------- + /** + *

Is the character specified contained in this range.

+ * + * @param ch the character to check + * @return true if this range contains the input character + */ + public boolean contains(char ch) { + return ((ch >= start && ch <= end) != negated); + } + + /** + *

Are all the characters of the passed in range contained in + * this range.

+ * + * @param range the range to check against + * @return true if this range entirely contains the input range + * @throws IllegalArgumentException if null input + */ + public boolean contains(CharRange range) { + if (range == null) { + throw new IllegalArgumentException("The Range must not be null"); + } + if (negated) { + if (range.negated) { + return (start >= range.start && end <= range.end); + } else { + return (range.end < start || range.start > end); + } + } else { + if (range.negated) { + return (start == 0 && end == Character.MAX_VALUE); + } else { + return (start <= range.start && end >= range.end); + } + } + } + + // Basics + //----------------------------------------------------------------------- + /** + *

Compares two CharRange objects, returning true if they represent + * exactly the same range of characters defined in the same way.

+ * + * @param obj the object to compare to + * @return true if equal + */ + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof CharRange == false) { + return false; + } + CharRange other = (CharRange) obj; + return (start == other.start && end == other.end && negated == other.negated); + } + + /** + *

Gets a hashCode compatable with the equals method.

+ * + * @return a suitable hashCode + */ + public int hashCode() { + return 83 + start + 7 * end + (negated ? 1 : 0); + } + + /** + *

Gets a string representation of the character range.

+ * + * @return string representation of this range + */ + public String toString() { + if (iToString == null) { + StringBuffer buf = new StringBuffer(4); + if (isNegated()) { + buf.append('^'); + } + buf.append(start); + if (start != end) { + buf.append('-'); + buf.append(end); + } + iToString = buf.toString(); + } + return iToString; + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/CharSet.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/CharSet.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/CharSet.java 30 Aug 2012 16:24:42 -0000 1.1 @@ -0,0 +1,317 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +/** + *

A set of characters.

+ * + *

Instances are immutable, but instances of subclasses may not be.

+ * + * @author Henri Yandell + * @author Stephen Colebourne + * @author Phil Steitz + * @author Pete Gieser + * @author Gary Gregory + * @since 1.0 + * @version $Id: CharSet.java,v 1.1 2012/08/30 16:24:42 marcin Exp $ + */ +public class CharSet implements Serializable { + + /** Serialization lock, Lang version 2.0. */ + private static final long serialVersionUID = 5947847346149275958L; + + /** + * A CharSet defining no characters. + * @since 2.0 + */ + public static final CharSet EMPTY = new CharSet((String) null); + + /** + * A CharSet defining ASCII alphabetic characters "a-zA-Z". + * @since 2.0 + */ + public static final CharSet ASCII_ALPHA = new CharSet("a-zA-Z"); + + /** + * A CharSet defining ASCII alphabetic characters "a-z". + * @since 2.0 + */ + public static final CharSet ASCII_ALPHA_LOWER = new CharSet("a-z"); + + /** + * A CharSet defining ASCII alphabetic characters "A-Z". + * @since 2.0 + */ + public static final CharSet ASCII_ALPHA_UPPER = new CharSet("A-Z"); + + /** + * A CharSet defining ASCII alphabetic characters "0-9". + * @since 2.0 + */ + public static final CharSet ASCII_NUMERIC = new CharSet("0-9"); + + /** + * A Map of the common cases used in the factory. + * Subclasses can add more common patterns if desired. + * @since 2.0 + */ + protected static final Map COMMON = new HashMap(); + + static { + COMMON.put(null, EMPTY); + COMMON.put("", EMPTY); + COMMON.put("a-zA-Z", ASCII_ALPHA); + COMMON.put("A-Za-z", ASCII_ALPHA); + COMMON.put("a-z", ASCII_ALPHA_LOWER); + COMMON.put("A-Z", ASCII_ALPHA_UPPER); + COMMON.put("0-9", ASCII_NUMERIC); + } + + /** The set of CharRange objects. */ + private Set set = new HashSet(); + + //----------------------------------------------------------------------- + /** + *

Factory method to create a new CharSet using a special syntax.

+ * + *
    + *
  • null or empty string ("") + * - set containing no characters
  • + *
  • Single character, such as "a" + * - set containing just that character
  • + *
  • Multi character, such as "a-e" + * - set containing characters from one character to the other
  • + *
  • Negated, such as "^a" or "^a-e" + * - set containing all characters except those defined
  • + *
  • Combinations, such as "abe-g" + * - set containing all the characters from the individual sets
  • + *
+ * + *

The matching order is:

+ *
    + *
  1. Negated multi character range, such as "^a-e" + *
  2. Ordinary multi character range, such as "a-e" + *
  3. Negated single character, such as "^a" + *
  4. Ordinary single character, such as "a" + *
+ *

Matching works left to right. Once a match is found the + * search starts again from the next character.

+ * + *

If the same range is defined twice using the same syntax, only + * one range will be kept. + * Thus, "a-ca-c" creates only one range of "a-c".

+ * + *

If the start and end of a range are in the wrong order, + * they are reversed. Thus "a-e" is the same as "e-a". + * As a result, "a-ee-a" would create only one range, + * as the "a-e" and "e-a" are the same.

+ * + *

The set of characters represented is the union of the specified ranges.

+ * + *

All CharSet objects returned by this method will be immutable.

+ * + * @param setStr the String describing the set, may be null + * @return a CharSet instance + * @since 2.0 + */ + public static CharSet getInstance(String setStr) { + Object set = COMMON.get(setStr); + if (set != null) { + return (CharSet) set; + } + return new CharSet(setStr); + } + + //----------------------------------------------------------------------- + /** + *

Constructs a new CharSet using the set syntax.

+ * + * @param setStr the String describing the set, may be null + * @since 2.0 + */ + protected CharSet(String setStr) { + super(); + add(setStr); + } + + /** + *

Constructs a new CharSet using the set syntax. + * Each string is merged in with the set.

+ * + * @param set Strings to merge into the initial set + * @throws NullPointerException if set is null + */ + protected CharSet(String[] set) { + super(); + int sz = set.length; + for (int i = 0; i < sz; i++) { + add(set[i]); + } + } + + //----------------------------------------------------------------------- + /** + *

Add a set definition string to the CharSet.

+ * + * @param str set definition string + */ + protected void add(String str) { + if (str == null) { + return; + } + + int len = str.length(); + int pos = 0; + while (pos < len) { + int remainder = (len - pos); + if (remainder >= 4 && str.charAt(pos) == '^' && str.charAt(pos + 2) == '-') { + // negated range + set.add(new CharRange(str.charAt(pos + 1), str.charAt(pos + 3), true)); + pos += 4; + } else if (remainder >= 3 && str.charAt(pos + 1) == '-') { + // range + set.add(new CharRange(str.charAt(pos), str.charAt(pos + 2))); + pos += 3; + } else if (remainder >= 2 && str.charAt(pos) == '^') { + // negated char + set.add(new CharRange(str.charAt(pos + 1), true)); + pos += 2; + } else { + // char + set.add(new CharRange(str.charAt(pos))); + pos += 1; + } + } + } + + //----------------------------------------------------------------------- + /** + *

Gets the internal set as an array of CharRange objects.

+ * + * @return an array of immutable CharRange objects + * @since 2.0 + */ + public CharRange[] getCharRanges() { + return (CharRange[]) set.toArray(new CharRange[set.size()]); + } + + //----------------------------------------------------------------------- + /** + *

Does the CharSet contain the specified + * character ch.

+ * + * @param ch the character to check for + * @return true if the set contains the characters + */ + public boolean contains(char ch) { + for (Iterator it = set.iterator(); it.hasNext();) { + CharRange range = (CharRange) it.next(); + if (range.contains(ch)) { + return true; + } + } + return false; + } + + // Basics + //----------------------------------------------------------------------- + /** + *

Compares two CharSet objects, returning true if they represent + * exactly the same set of characters defined in the same way.

+ * + *

The two sets abc and a-c are not + * equal according to this method.

+ * + * @param obj the object to compare to + * @return true if equal + * @since 2.0 + */ + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof CharSet == false) { + return false; + } + CharSet other = (CharSet) obj; + return (set.equals(other.set)); + } + + /** + *

Gets a hashCode compatable with the equals method.

+ * + * @return a suitable hashCode + * @since 2.0 + */ + public int hashCode() { + return 89 + set.hashCode(); + } + + /** + *

Gets a string representation of the set.

+ * + * @return string representation of the set + */ + public String toString() { + return set.toString(); + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/CharSetUtils.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/CharSetUtils.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/CharSetUtils.java 30 Aug 2012 16:24:42 -0000 1.1 @@ -0,0 +1,417 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang; + +/** + *

Operations on CharSets.

+ * + *

This class handles null input gracefully. + * An exception will not be thrown for a null input. + * Each method documents its behaviour in more detail.

+ * + * @see CharSet + * @author Henri Yandell + * @author Stephen Colebourne + * @author Phil Steitz + * @author Gary Gregory + * @since 1.0 + * @version $Id: CharSetUtils.java,v 1.1 2012/08/30 16:24:42 marcin Exp $ + */ +public class CharSetUtils { + + /** + *

CharSetUtils instances should NOT be constructed in standard programming. + * Instead, the class should be used as CharSetUtils.evaluateSet(null);.

+ * + *

This constructor is public to permit tools that require a JavaBean instance + * to operate.

+ */ + public CharSetUtils() { + } + + // Factory + //----------------------------------------------------------------------- + /** + *

Creates a CharSet instance which allows a certain amount of + * set logic to be performed.

+ *

The syntax is:

+ *
    + *
  • "aeio" which implies 'a','e',..
  • + *
  • "^e" implies not e.
  • + *
  • "ej-m" implies e,j->m. e,j,k,l,m.
  • + *
+ * + *
+     * CharSetUtils.evaluateSet(null)    = null
+     * CharSetUtils.evaluateSet([])      = CharSet matching nothing
+     * CharSetUtils.evaluateSet(["a-e"]) = CharSet matching a,b,c,d,e
+     * 
+ * + * @param set the set, may be null + * @return a CharSet instance, null if null input + * @deprecated Use {@link CharSet#getInstance(String)}. + * Method will be removed in Commons Lang 3.0. + */ + public static CharSet evaluateSet(String[] set) { + if (set == null) { + return null; + } + return new CharSet(set); + } + + // Squeeze + //----------------------------------------------------------------------- + /** + *

Squeezes any repititions of a character that is mentioned in the + * supplied set.

+ * + *
+     * CharSetUtils.squeeze(null, *)        = null
+     * CharSetUtils.squeeze("", *)          = ""
+     * CharSetUtils.squeeze(*, null)        = *
+     * CharSetUtils.squeeze(*, "")          = *
+     * CharSetUtils.squeeze("hello", "k-p") = "helo"
+     * CharSetUtils.squeeze("hello", "a-e") = "hello"
+     * 
+ * + * @see #evaluateSet(java.lang.String[]) for set-syntax. + * @param str the string to squeeze, may be null + * @param set the character set to use for manipulation, may be null + * @return modified String, null if null string input + */ + public static String squeeze(String str, String set) { + if (str == null || str.length() == 0 || set == null || set.length() == 0) { + return str; + } + 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(java.lang.String[]) for set-syntax. + * @param str the string to squeeze, may be null + * @param set the character set to use for manipulation, may be null + * @return modified String, null if null string input + */ + public static String squeeze(String str, String[] set) { + if (str == null || str.length() == 0 || set == null || set.length == 0) { + return str; + } + 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(); + } + + // Count + //----------------------------------------------------------------------- + /** + *

Takes an argument in set-syntax, see evaluateSet, + * and returns the number of characters present in the specified string.

+ * + *
+     * CharSetUtils.count(null, *)        = 0
+     * CharSetUtils.count("", *)          = 0
+     * CharSetUtils.count(*, null)        = 0
+     * CharSetUtils.count(*, "")          = 0
+     * CharSetUtils.count("hello", "k-p") = 3
+     * CharSetUtils.count("hello", "a-e") = 1
+     * 
+ * + * @see #evaluateSet(java.lang.String[]) for set-syntax. + * @param str String to count characters in, may be null + * @param set String set of characters to count, may be null + * @return character count, zero if null string input + */ + public static int count(String str, String set) { + if (str == null || str.length() == 0 || set == null || set.length() == 0) { + return 0; + } + 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.
  • + *
+ * + * @see #evaluateSet(java.lang.String[]) for set-syntax. + * @param str String to count characters in, may be null + * @param set String[] set of characters to count, may be null + * @return character count, zero if null string input + */ + public static int count(String str, String[] set) { + if (str == null || str.length() == 0 || set == null || set.length == 0) { + return 0; + } + CharSet chars = evaluateSet(set); + int count = 0; + char[] chrs = str.toCharArray(); + int sz = chrs.length; + for(int i=0; iTakes an argument in set-syntax, see evaluateSet, + * and keeps any of characters present in the specified string.

+ * + *
+     * CharSetUtils.keep(null, *)        = null
+     * CharSetUtils.keep("", *)          = ""
+     * CharSetUtils.keep(*, null)        = ""
+     * CharSetUtils.keep(*, "")          = ""
+     * CharSetUtils.keep("hello", "hl") = "hll"
+     * CharSetUtils.keep("hello", "le") = "ell"
+     * 
+ * + * @see #evaluateSet(java.lang.String[]) for set-syntax. + * @param str String to keep characters from, may be null + * @param set String set of characters to keep, may be null + * @return modified String, null if null string input + * @since 2.0 + */ + public static String keep(String str, String set) { + if (str == null) { + return null; + } + if (str.length() == 0 || set == null || set.length() == 0) { + return ""; + } + String[] strs = new String[1]; + strs[0] = set; + return keep(str, strs); + } + + /** + *

Takes an argument in set-syntax, see evaluateSet, + * and keeps any of characters present in the specified string.

+ * + *

An example would be:

+ *
    + *
  • keep("hello", {"c-f", "o"}) + * returns "hll"
  • + *
+ * + * @see #evaluateSet(java.lang.String[]) for set-syntax. + * @param str String to keep characters from, may be null + * @param set String[] set of characters to keep, may be null + * @return modified String, null if null string input + * @since 2.0 + */ + public static String keep(String str, String[] set) { + if (str == null) { + return null; + } + if (str.length() == 0 || set == null || set.length == 0) { + return ""; + } + return modify(str, set, true); + } + + // Delete + //----------------------------------------------------------------------- + /** + *

Takes an argument in set-syntax, see evaluateSet, + * and deletes any of characters present in the specified string.

+ * + *
+     * CharSetUtils.delete(null, *)        = null
+     * CharSetUtils.delete("", *)          = ""
+     * CharSetUtils.delete(*, null)        = *
+     * CharSetUtils.delete(*, "")          = *
+     * CharSetUtils.delete("hello", "hl") = "hll"
+     * CharSetUtils.delete("hello", "le") = "ell"
+     * 
+ * + * @see #evaluateSet(java.lang.String[]) for set-syntax. + * @param str String to delete characters from, may be null + * @param set String set of characters to delete, may be null + * @return modified String, null if null string input + */ + public static String delete(String str, String set) { + if (str == null || str.length() == 0 || set == null || set.length() == 0) { + return str; + } + 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"
  • + *
+ * + * @see #evaluateSet(java.lang.String[]) for set-syntax. + * @param str String to delete characters from, may be null + * @param set String[] set of characters to delete, may be null + * @return modified String, null if null string input + */ + public static String delete(String str, String[] set) { + if (str == null || str.length() == 0 || set == null || set.length == 0) { + return str; + } + return modify(str, set, false); + } + + //----------------------------------------------------------------------- + // Implementation of delete and keep + private static String modify(String str, String[] set, boolean expect) { + CharSet chars = evaluateSet(set); + StringBuffer buffer = new StringBuffer(str.length()); + char[] chrs = str.toCharArray(); + int sz = chrs.length; + for(int i=0; iTranslate characters in a String. + * This is a multi character search and replace routine.

+ * + *

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.

+ * + *
+     * CharSetUtils.translate(null, *, *) = null
+     * CharSetUtils.translate("", *, *) = ""
+     * 
+ * + * @param str String to replace characters in, may be null + * @param searchChars a set of characters to search for, must not be null + * @param replaceChars a set of characters to replace, must not be null or empty ("") + * @return translated String, null if null string input + * @throws NullPointerException if with or repl + * is null + * @throws ArrayIndexOutOfBoundsException if with is empty ("") + * @deprecated Use {@link StringUtils#replaceChars(String, String, String)}. + * Method will be removed in Commons Lang 3.0. + */ + public static String translate(String str, String searchChars, String replaceChars) { + if (str == null || str.length() == 0) { + return str; + } + StringBuffer buffer = new StringBuffer(str.length()); + char[] chrs = str.toCharArray(); + char[] withChrs = replaceChars.toCharArray(); + int sz = chrs.length; + int withMax = replaceChars.length() - 1; + for(int i=0; i withMax) { + idx = withMax; + } + buffer.append(withChrs[idx]); + } else { + buffer.append(chrs[i]); + } + } + return buffer.toString(); + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/ClassUtils.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/ClassUtils.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/ClassUtils.java 30 Aug 2012 16:24:42 -0000 1.1 @@ -0,0 +1,533 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +/** + *

Operates on classes without using reflection.

+ * + *

This class handles invalid null inputs as best it can. + * Each method documents its behaviour in more detail.

+ * + * @author Stephen Colebourne + * @author Gary Gregory + * @since 2.0 + * @version $Id: ClassUtils.java,v 1.1 2012/08/30 16:24:42 marcin Exp $ + */ +public class ClassUtils { + + /** + *

The package separator character: ..

+ */ + public static final char PACKAGE_SEPARATOR_CHAR = '.'; + + /** + *

The package separator String: ..

+ */ + public static final String PACKAGE_SEPARATOR = String.valueOf(PACKAGE_SEPARATOR_CHAR); + + /** + *

The inner class separator character: $.

+ */ + public static final char INNER_CLASS_SEPARATOR_CHAR = '$'; + + /** + *

The inner class separator String: $.

+ */ + public static final String INNER_CLASS_SEPARATOR = String.valueOf(INNER_CLASS_SEPARATOR_CHAR); + + /** + *

ClassUtils instances should NOT be constructed in standard programming. + * Instead, the class should be used as + * ClassUtils.getShortClassName(cls).

+ * + *

This constructor is public to permit tools that require a JavaBean + * instance to operate.

+ */ + public ClassUtils() { + } + + // Short class name + // ---------------------------------------------------------------------- + /** + *

Gets the class name minus the package name for an Object.

+ * + * @param object the class to get the short name for, may be null + * @param valueIfNull the value to return if null + * @return the class name of the object without the package name, or the null value + */ + public static String getShortClassName(Object object, String valueIfNull) { + if (object == null) { + return valueIfNull; + } + return getShortClassName(object.getClass().getName()); + } + + /** + *

Gets the class name minus the package name from a Class.

+ * + * @param cls the class to get the short name for, must not be + * null + * @return the class name without the package name + * @throws IllegalArgumentException if the class is null + */ + public static String getShortClassName(Class cls) { + if (cls == null) { + throw new IllegalArgumentException("The class must not be null"); + } + return getShortClassName(cls.getName()); + } + + /** + *

Gets the class name minus the package name from a String.

+ * + *

The string passed in is assumed to be a class name - it is not checked.

+ * + * @param className the className to get the short name for, + * must not be empty or null + * @return the class name of the class without the package name + * @throws IllegalArgumentException if the className is empty + */ + public static String getShortClassName(String className) { + if (StringUtils.isEmpty(className)) { + throw new IllegalArgumentException("The class name must not be empty"); + } + char[] chars = className.toCharArray(); + int lastDot = 0; + for (int i = 0; i < chars.length; i++) { + if (chars[i] == PACKAGE_SEPARATOR_CHAR) { + lastDot = i + 1; + } else if (chars[i] == INNER_CLASS_SEPARATOR_CHAR) { // handle inner classes + chars[i] = PACKAGE_SEPARATOR_CHAR; + } + } + return new String(chars, lastDot, chars.length - lastDot); + } + + // Package name + // ---------------------------------------------------------------------- + /** + *

Gets the package name of an Object.

+ * + * @param object the class to get the package name for, may be null + * @param valueIfNull the value to return if null + * @return the package name of the object, or the null value + */ + public static String getPackageName(Object object, String valueIfNull) { + if (object == null) { + return valueIfNull; + } + return getPackageName(object.getClass().getName()); + } + + /** + *

Gets the package name of a Class.

+ * + * @param cls the class to get the package name for, + * must not be null + * @return the package name + * @throws IllegalArgumentException if the class is null + */ + public static String getPackageName(Class cls) { + if (cls == null) { + throw new IllegalArgumentException("The class must not be null"); + } + return getPackageName(cls.getName()); + } + + /** + *

Gets the package name from a String.

+ * + *

The string passed in is assumed to be a class name - it is not checked.

+ * + * @param className the className to get the package name for, + * must not be empty or null + * @return the package name + * @throws IllegalArgumentException if the className is empty + */ + public static String getPackageName(String className) { + if (StringUtils.isEmpty(className)) { + throw new IllegalArgumentException("The class name must not be empty"); + } + int i = className.lastIndexOf(PACKAGE_SEPARATOR_CHAR); + if (i == -1) { + return ""; + } + return className.substring(0, i); + } + + // Superclasses/Superinterfaces + // ---------------------------------------------------------------------- + /** + *

Gets a List of superclasses for the given class.

+ * + * @param cls the class to look up, must not be null + * @return the List of superclasses in order going up from this one + * null if null input + */ + public static List getAllSuperclasses(Class cls) { + if (cls == null) { + return null; + } + List classes = new ArrayList(); + Class superclass = cls.getSuperclass(); + while (superclass != null) { + classes.add(superclass); + superclass = superclass.getSuperclass(); + } + return classes; + } + + /** + *

Gets a List of all interfaces implemented by the given + * class and its superclasses.

+ * + *

The order is determined by looking through each interface in turn as + * declared in the source file and following its hieracrchy up. Then each + * superclass is considered in the same way. Later duplicates are ignored, + * so the order is maintained.

+ * + * @param cls the class to look up, must not be null + * @return the List of interfaces in order, + * null if null input + */ + public static List getAllInterfaces(Class cls) { + if (cls == null) { + return null; + } + List list = new ArrayList(); + while (cls != null) { + Class[] interfaces = cls.getInterfaces(); + for (int i = 0; i < interfaces.length; i++) { + if (list.contains(interfaces[i]) == false) { + list.add(interfaces[i]); + } + List superInterfaces = getAllInterfaces(interfaces[i]); + for (Iterator it = superInterfaces.iterator(); it.hasNext();) { + Class intface = (Class) it.next(); + if (list.contains(intface) == false) { + list.add(intface); + } + } + } + cls = cls.getSuperclass(); + } + return list; + } + +// /** +// *

Gets a List of subclasses of the specified class.

+// * +// *

This method searches the classpath to find all the subclasses +// * of a particular class available. No classes are loaded, the +// * returned list contains class names, not classes.

+// * +// * @param cls the class to find subclasses for +// * @return the List of subclass String class names +// * @throws IllegalArgumentException if the class is null +// */ +// public static List getAllSubclassNames(Class cls) { +// if (cls == null) { +// throw new IllegalArgumentException("The class must not be null"); +// } +// // TODO Use JavaWorld tip for searching the classpath +// return null; +// } + +// /** +// *

Gets a List of subclasses of the specified class.

+// * +// *

This method searches the classpath to find all the subclasses +// * of a particular class available.

+// * +// * @param cls the class to find subclasses for +// * @return the List of subclasses +// * @throws IllegalArgumentException if the class is null +// */ +// public static List getAllSubclasses(Class cls) { +// List names = getAllSubclassNames(cls); +// return convertClassNamesToClasses(names); +// } + +// /** +// *

Gets a List of implementations of the specified interface.

+// * +// *

This method searches the classpath to find all the implementations +// * of a particular interface available. No classes are loaded, the +// * returned list contains class names, not classes.

+// * +// * @param cls the class to find sub classes for +// * @return the List of implementation String class names +// * @throws IllegalArgumentException if the class is null +// */ +// public static List getAllImplementationClassNames(Class cls) { +// if (cls == null) { +// throw new IllegalArgumentException("The class must not be null"); +// } +// // TODO Use JavaWorld tip for searching the classpath +// return null; +// } + + // Convert list + // ---------------------------------------------------------------------- + /** + *

Given a List of class names, this method converts them into classes.

+ * + *

A new List is returned. If the class name cannot be found, null + * is stored in the List. If the class name in the List is + * null, null is stored in the output List.

+ * + * @param classNames the classNames to change + * @return a List of Class objects corresponding to the class names, + * null if null input + * @throws ClassCastException if classNames contains a non String entry + */ + public static List convertClassNamesToClasses(List classNames) { + if (classNames == null) { + return null; + } + List classes = new ArrayList(classNames.size()); + for (Iterator it = classNames.iterator(); it.hasNext();) { + String className = (String) it.next(); + try { + classes.add(Class.forName(className)); + } catch (Exception ex) { + classes.add(null); + } + } + return classes; + } + + /** + *

Given a List of Class objects, this method converts + * them into class names.

+ * + *

A new List is returned. null objects will be copied into + * the returned list as null.

+ * + * @param classes the classes to change + * @return a List of Class objects corresponding to the class names, + * null if null input + * @throws ClassCastException if classNames contains a non Class or null entry + */ + public static List convertClassesToClassNames(List classes) { + if (classes == null) { + return null; + } + List classNames = new ArrayList(classes.size()); + for (Iterator it = classes.iterator(); it.hasNext();) { + Class cls = (Class) it.next(); + if (cls == null) { + classNames.add(null); + } else { + classNames.add(cls.getName()); + } + } + return classNames; + } + + // Is assignable + // ---------------------------------------------------------------------- + /** + *

Checks if an array of Classes can be assigned to another array of Classes.

+ * + *

This method calls {@link #isAssignable(Class, Class) isAssignable} for each + * Class pair in the input arrays. It can be used to check if a set of arguments + * (the first parameter) are suitably compatable with a set of method parameter types + * (the second parameter).

+ * + *

Unlike the {@link Class#isAssignableFrom(java.lang.Class)} method, this + * method takes into account widenings of primitive classes and + * nulls.

+ * + *

Primitive widenings allow an int to be assigned to a long, + * float or double. This method returns the correct + * result for these cases.

+ * + *

Null may be assigned to any reference type. This method will + * return true if null is passed in and the toClass is + * non-primitive.

+ * + *

Specifically, this method tests whether the type represented by the + * specified Class parameter can be converted to the type + * represented by this Class object via an identity conversion + * widening primitive or widening reference conversion. See + * The Java Language Specification, + * sections 5.1.1, 5.1.2 and 5.1.4 for details.

+ * + * @param classArray the array of Classes to check, may be null + * @param toClassArray the array of Classes to try to assign into, may be null + * @return true if assignment possible + */ + public static boolean isAssignable(Class[] classArray, Class[] toClassArray) { + if (ArrayUtils.isSameLength(classArray, toClassArray) == false) { + return false; + } + if (classArray == null) { + classArray = ArrayUtils.EMPTY_CLASS_ARRAY; + } + if (toClassArray == null) { + toClassArray = ArrayUtils.EMPTY_CLASS_ARRAY; + } + for (int i = 0; i < classArray.length; i++) { + if (isAssignable(classArray[i], toClassArray[i]) == false) { + return false; + } + } + return true; + } + + /** + *

Checks if one Class can be assigned to a variable of + * another Class.

+ * + *

Unlike the {@link Class#isAssignableFrom(java.lang.Class)} method, + * this method takes into account widenings of primitive classes and + * nulls.

+ * + *

Primitive widenings allow an int to be assigned to a long, float or + * double. This method returns the correct result for these cases.

+ * + *

Null may be assigned to any reference type. This method + * will return true if null is passed in and the + * toClass is non-primitive.

+ * + *

Specifically, this method tests whether the type represented by the + * specified Class parameter can be converted to the type + * represented by this Class object via an identity conversion + * widening primitive or widening reference conversion. See + * The Java Language Specification, + * sections 5.1.1, 5.1.2 and 5.1.4 for details.

+ * + * @param cls the Class to check, may be null + * @param toClass the Class to try to assign into, returns false if null + * @return true if assignment possible + */ + public static boolean isAssignable(Class cls, Class toClass) { + if (toClass == null) { + return false; + } + // have to check for null, as isAssignableFrom doesn't + if (cls == null) { + return !(toClass.isPrimitive()); + } + if (cls.equals(toClass)) { + return true; + } + if (cls.isPrimitive()) { + if (toClass.isPrimitive() == false) { + return false; + } + if (Integer.TYPE.equals(cls)) { + return Long.TYPE.equals(toClass) + || Float.TYPE.equals(toClass) + || Double.TYPE.equals(toClass); + } + if (Long.TYPE.equals(cls)) { + return Float.TYPE.equals(toClass) + || Double.TYPE.equals(toClass); + } + if (Boolean.TYPE.equals(cls)) { + return false; + } + if (Double.TYPE.equals(cls)) { + return false; + } + if (Float.TYPE.equals(cls)) { + return Double.TYPE.equals(toClass); + } + if (Character.TYPE.equals(cls)) { + return Integer.TYPE.equals(toClass) + || Long.TYPE.equals(toClass) + || Float.TYPE.equals(toClass) + || Double.TYPE.equals(toClass); + } + if (Short.TYPE.equals(cls)) { + return Integer.TYPE.equals(toClass) + || Long.TYPE.equals(toClass) + || Float.TYPE.equals(toClass) + || Double.TYPE.equals(toClass); + } + if (Byte.TYPE.equals(cls)) { + return Short.TYPE.equals(toClass) + || Integer.TYPE.equals(toClass) + || Long.TYPE.equals(toClass) + || Float.TYPE.equals(toClass) + || Double.TYPE.equals(toClass); + } + // should never get here + return false; + } + return toClass.isAssignableFrom(cls); + } + + // Inner class + // ---------------------------------------------------------------------- + /** + *

Is the specified class an inner class or static nested class.

+ * + * @param cls the class to check + * @return true if the class is an inner or static nested class, + * false if not or null + */ + public static boolean isInnerClass(Class cls) { + if (cls == null) { + return false; + } + return (cls.getName().indexOf(INNER_CLASS_SEPARATOR_CHAR) >= 0); + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/Entities.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/Entities.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/Entities.java 30 Aug 2012 16:24:42 -0000 1.1 @@ -0,0 +1,702 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang; + +import java.util.HashMap; +import java.util.Map; +import java.util.TreeMap; + +/** + *

Provides HTML and XML entity utilities.

+ * + * @see ISO Entities + * @see
HTML 3.2 Character Entities for ISO Latin-1 + * @see
HTML 4.0 Character entity references + * @see
HTML 4.01 Character References + * @see
HTML 4.01 Code positions + * + * @author Alexander Day Chaffee + * @author Gary Gregory + * @since 2.0 + * @version $Id: Entities.java,v 1.1 2012/08/30 16:24:42 marcin Exp $ + */ +class Entities { + + private static final String[][] BASIC_ARRAY = { + {"quot", "34"}, // " - double-quote + {"amp", "38"}, // & - ampersand + {"lt", "60"}, // < - less-than + {"gt", "62"}, // > - greater-than + }; + + private static final String[][] APOS_ARRAY = { + {"apos", "39"}, // XML apostrophe + }; + + // package scoped for testing + static final String[][] ISO8859_1_ARRAY = { + {"nbsp", "160"}, // non-breaking space + {"iexcl", "161"}, //inverted exclamation mark + {"cent", "162"}, //cent sign + {"pound", "163"}, //pound sign + {"curren", "164"}, //currency sign + {"yen", "165"}, //yen sign = yuan sign + {"brvbar", "166"}, //broken bar = broken vertical bar + {"sect", "167"}, //section sign + {"uml", "168"}, //diaeresis = spacing diaeresis + {"copy", "169"}, // � - copyright sign + {"ordf", "170"}, //feminine ordinal indicator + {"laquo", "171"}, //left-pointing double angle quotation mark = left pointing guillemet + {"not", "172"}, //not sign + {"shy", "173"}, //soft hyphen = discretionary hyphen + {"reg", "174"}, // � - registered trademark sign + {"macr", "175"}, //macron = spacing macron = overline = APL overbar + {"deg", "176"}, //degree sign + {"plusmn", "177"}, //plus-minus sign = plus-or-minus sign + {"sup2", "178"}, //superscript two = superscript digit two = squared + {"sup3", "179"}, //superscript three = superscript digit three = cubed + {"acute", "180"}, //acute accent = spacing acute + {"micro", "181"}, //micro sign + {"para", "182"}, //pilcrow sign = paragraph sign + {"middot", "183"}, //middle dot = Georgian comma = Greek middle dot + {"cedil", "184"}, //cedilla = spacing cedilla + {"sup1", "185"}, //superscript one = superscript digit one + {"ordm", "186"}, //masculine ordinal indicator + {"raquo", "187"}, //right-pointing double angle quotation mark = right pointing guillemet + {"frac14", "188"}, //vulgar fraction one quarter = fraction one quarter + {"frac12", "189"}, //vulgar fraction one half = fraction one half + {"frac34", "190"}, //vulgar fraction three quarters = fraction three quarters + {"iquest", "191"}, //inverted question mark = turned question mark + {"Agrave", "192"}, // � - uppercase A, grave accent + {"Aacute", "193"}, // � - uppercase A, acute accent + {"Acirc", "194"}, // � - uppercase A, circumflex accent + {"Atilde", "195"}, // � - uppercase A, tilde + {"Auml", "196"}, // � - uppercase A, umlaut + {"Aring", "197"}, // � - uppercase A, ring + {"AElig", "198"}, // � - uppercase AE + {"Ccedil", "199"}, // � - uppercase C, cedilla + {"Egrave", "200"}, // � - uppercase E, grave accent + {"Eacute", "201"}, // � - uppercase E, acute accent + {"Ecirc", "202"}, // � - uppercase E, circumflex accent + {"Euml", "203"}, // � - uppercase E, umlaut + {"Igrave", "204"}, // � - uppercase I, grave accent + {"Iacute", "205"}, // � - uppercase I, acute accent + {"Icirc", "206"}, // � - uppercase I, circumflex accent + {"Iuml", "207"}, // � - uppercase I, umlaut + {"ETH", "208"}, // � - uppercase Eth, Icelandic + {"Ntilde", "209"}, // � - uppercase N, tilde + {"Ograve", "210"}, // � - uppercase O, grave accent + {"Oacute", "211"}, // � - uppercase O, acute accent + {"Ocirc", "212"}, // � - uppercase O, circumflex accent + {"Otilde", "213"}, // � - uppercase O, tilde + {"Ouml", "214"}, // � - uppercase O, umlaut + {"times", "215"}, //multiplication sign + {"Oslash", "216"}, // � - uppercase O, slash + {"Ugrave", "217"}, // � - uppercase U, grave accent + {"Uacute", "218"}, // � - uppercase U, acute accent + {"Ucirc", "219"}, // � - uppercase U, circumflex accent + {"Uuml", "220"}, // � - uppercase U, umlaut + {"Yacute", "221"}, // � - uppercase Y, acute accent + {"THORN", "222"}, // � - uppercase THORN, Icelandic + {"szlig", "223"}, // � - lowercase sharps, German + {"agrave", "224"}, // � - lowercase a, grave accent + {"aacute", "225"}, // � - lowercase a, acute accent + {"acirc", "226"}, // � - lowercase a, circumflex accent + {"atilde", "227"}, // � - lowercase a, tilde + {"auml", "228"}, // � - lowercase a, umlaut + {"aring", "229"}, // � - lowercase a, ring + {"aelig", "230"}, // � - lowercase ae + {"ccedil", "231"}, // � - lowercase c, cedilla + {"egrave", "232"}, // � - lowercase e, grave accent + {"eacute", "233"}, // � - lowercase e, acute accent + {"ecirc", "234"}, // � - lowercase e, circumflex accent + {"euml", "235"}, // � - lowercase e, umlaut + {"igrave", "236"}, // � - lowercase i, grave accent + {"iacute", "237"}, // � - lowercase i, acute accent + {"icirc", "238"}, // � - lowercase i, circumflex accent + {"iuml", "239"}, // � - lowercase i, umlaut + {"eth", "240"}, // � - lowercase eth, Icelandic + {"ntilde", "241"}, // � - lowercase n, tilde + {"ograve", "242"}, // � - lowercase o, grave accent + {"oacute", "243"}, // � - lowercase o, acute accent + {"ocirc", "244"}, // � - lowercase o, circumflex accent + {"otilde", "245"}, // � - lowercase o, tilde + {"ouml", "246"}, // � - lowercase o, umlaut + {"divide", "247"}, // division sign + {"oslash", "248"}, // � - lowercase o, slash + {"ugrave", "249"}, // � - lowercase u, grave accent + {"uacute", "250"}, // � - lowercase u, acute accent + {"ucirc", "251"}, // � - lowercase u, circumflex accent + {"uuml", "252"}, // � - lowercase u, umlaut + {"yacute", "253"}, // � - lowercase y, acute accent + {"thorn", "254"}, // � - lowercase thorn, Icelandic + {"yuml", "255"}, // � - lowercase y, umlaut + }; + + // http://www.w3.org/TR/REC-html40/sgml/entities.html + // package scoped for testing + static final String[][] HTML40_ARRAY = { +// + {"fnof", "402"}, //latin small f with hook = function= florin, U+0192 ISOtech --> +// + {"Alpha", "913"}, //greek capital letter alpha, U+0391 --> + {"Beta", "914"}, //greek capital letter beta, U+0392 --> + {"Gamma", "915"}, //greek capital letter gamma,U+0393 ISOgrk3 --> + {"Delta", "916"}, //greek capital letter delta,U+0394 ISOgrk3 --> + {"Epsilon", "917"}, //greek capital letter epsilon, U+0395 --> + {"Zeta", "918"}, //greek capital letter zeta, U+0396 --> + {"Eta", "919"}, //greek capital letter eta, U+0397 --> + {"Theta", "920"}, //greek capital letter theta,U+0398 ISOgrk3 --> + {"Iota", "921"}, //greek capital letter iota, U+0399 --> + {"Kappa", "922"}, //greek capital letter kappa, U+039A --> + {"Lambda", "923"}, //greek capital letter lambda,U+039B ISOgrk3 --> + {"Mu", "924"}, //greek capital letter mu, U+039C --> + {"Nu", "925"}, //greek capital letter nu, U+039D --> + {"Xi", "926"}, //greek capital letter xi, U+039E ISOgrk3 --> + {"Omicron", "927"}, //greek capital letter omicron, U+039F --> + {"Pi", "928"}, //greek capital letter pi, U+03A0 ISOgrk3 --> + {"Rho", "929"}, //greek capital letter rho, U+03A1 --> +// + {"Sigma", "931"}, //greek capital letter sigma,U+03A3 ISOgrk3 --> + {"Tau", "932"}, //greek capital letter tau, U+03A4 --> + {"Upsilon", "933"}, //greek capital letter upsilon,U+03A5 ISOgrk3 --> + {"Phi", "934"}, //greek capital letter phi,U+03A6 ISOgrk3 --> + {"Chi", "935"}, //greek capital letter chi, U+03A7 --> + {"Psi", "936"}, //greek capital letter psi,U+03A8 ISOgrk3 --> + {"Omega", "937"}, //greek capital letter omega,U+03A9 ISOgrk3 --> + {"alpha", "945"}, //greek small letter alpha,U+03B1 ISOgrk3 --> + {"beta", "946"}, //greek small letter beta, U+03B2 ISOgrk3 --> + {"gamma", "947"}, //greek small letter gamma,U+03B3 ISOgrk3 --> + {"delta", "948"}, //greek small letter delta,U+03B4 ISOgrk3 --> + {"epsilon", "949"}, //greek small letter epsilon,U+03B5 ISOgrk3 --> + {"zeta", "950"}, //greek small letter zeta, U+03B6 ISOgrk3 --> + {"eta", "951"}, //greek small letter eta, U+03B7 ISOgrk3 --> + {"theta", "952"}, //greek small letter theta,U+03B8 ISOgrk3 --> + {"iota", "953"}, //greek small letter iota, U+03B9 ISOgrk3 --> + {"kappa", "954"}, //greek small letter kappa,U+03BA ISOgrk3 --> + {"lambda", "955"}, //greek small letter lambda,U+03BB ISOgrk3 --> + {"mu", "956"}, //greek small letter mu, U+03BC ISOgrk3 --> + {"nu", "957"}, //greek small letter nu, U+03BD ISOgrk3 --> + {"xi", "958"}, //greek small letter xi, U+03BE ISOgrk3 --> + {"omicron", "959"}, //greek small letter omicron, U+03BF NEW --> + {"pi", "960"}, //greek small letter pi, U+03C0 ISOgrk3 --> + {"rho", "961"}, //greek small letter rho, U+03C1 ISOgrk3 --> + {"sigmaf", "962"}, //greek small letter final sigma,U+03C2 ISOgrk3 --> + {"sigma", "963"}, //greek small letter sigma,U+03C3 ISOgrk3 --> + {"tau", "964"}, //greek small letter tau, U+03C4 ISOgrk3 --> + {"upsilon", "965"}, //greek small letter upsilon,U+03C5 ISOgrk3 --> + {"phi", "966"}, //greek small letter phi, U+03C6 ISOgrk3 --> + {"chi", "967"}, //greek small letter chi, U+03C7 ISOgrk3 --> + {"psi", "968"}, //greek small letter psi, U+03C8 ISOgrk3 --> + {"omega", "969"}, //greek small letter omega,U+03C9 ISOgrk3 --> + {"thetasym", "977"}, //greek small letter theta symbol,U+03D1 NEW --> + {"upsih", "978"}, //greek upsilon with hook symbol,U+03D2 NEW --> + {"piv", "982"}, //greek pi symbol, U+03D6 ISOgrk3 --> +// + {"bull", "8226"}, //bullet = black small circle,U+2022 ISOpub --> +// + {"hellip", "8230"}, //horizontal ellipsis = three dot leader,U+2026 ISOpub --> + {"prime", "8242"}, //prime = minutes = feet, U+2032 ISOtech --> + {"Prime", "8243"}, //double prime = seconds = inches,U+2033 ISOtech --> + {"oline", "8254"}, //overline = spacing overscore,U+203E NEW --> + {"frasl", "8260"}, //fraction slash, U+2044 NEW --> +// + {"weierp", "8472"}, //script capital P = power set= Weierstrass p, U+2118 ISOamso --> + {"image", "8465"}, //blackletter capital I = imaginary part,U+2111 ISOamso --> + {"real", "8476"}, //blackletter capital R = real part symbol,U+211C ISOamso --> + {"trade", "8482"}, //trade mark sign, U+2122 ISOnum --> + {"alefsym", "8501"}, //alef symbol = first transfinite cardinal,U+2135 NEW --> +// +// + {"larr", "8592"}, //leftwards arrow, U+2190 ISOnum --> + {"uarr", "8593"}, //upwards arrow, U+2191 ISOnum--> + {"rarr", "8594"}, //rightwards arrow, U+2192 ISOnum --> + {"darr", "8595"}, //downwards arrow, U+2193 ISOnum --> + {"harr", "8596"}, //left right arrow, U+2194 ISOamsa --> + {"crarr", "8629"}, //downwards arrow with corner leftwards= carriage return, U+21B5 NEW --> + {"lArr", "8656"}, //leftwards double arrow, U+21D0 ISOtech --> +// + {"uArr", "8657"}, //upwards double arrow, U+21D1 ISOamsa --> + {"rArr", "8658"}, //rightwards double arrow,U+21D2 ISOtech --> +// + {"dArr", "8659"}, //downwards double arrow, U+21D3 ISOamsa --> + {"hArr", "8660"}, //left right double arrow,U+21D4 ISOamsa --> +// + {"forall", "8704"}, //for all, U+2200 ISOtech --> + {"part", "8706"}, //partial differential, U+2202 ISOtech --> + {"exist", "8707"}, //there exists, U+2203 ISOtech --> + {"empty", "8709"}, //empty set = null set = diameter,U+2205 ISOamso --> + {"nabla", "8711"}, //nabla = backward difference,U+2207 ISOtech --> + {"isin", "8712"}, //element of, U+2208 ISOtech --> + {"notin", "8713"}, //not an element of, U+2209 ISOtech --> + {"ni", "8715"}, //contains as member, U+220B ISOtech --> +// + {"prod", "8719"}, //n-ary product = product sign,U+220F ISOamsb --> +// + {"sum", "8721"}, //n-ary sumation, U+2211 ISOamsb --> +// + {"minus", "8722"}, //minus sign, U+2212 ISOtech --> + {"lowast", "8727"}, //asterisk operator, U+2217 ISOtech --> + {"radic", "8730"}, //square root = radical sign,U+221A ISOtech --> + {"prop", "8733"}, //proportional to, U+221D ISOtech --> + {"infin", "8734"}, //infinity, U+221E ISOtech --> + {"ang", "8736"}, //angle, U+2220 ISOamso --> + {"and", "8743"}, //logical and = wedge, U+2227 ISOtech --> + {"or", "8744"}, //logical or = vee, U+2228 ISOtech --> + {"cap", "8745"}, //intersection = cap, U+2229 ISOtech --> + {"cup", "8746"}, //union = cup, U+222A ISOtech --> + {"int", "8747"}, //integral, U+222B ISOtech --> + {"there4", "8756"}, //therefore, U+2234 ISOtech --> + {"sim", "8764"}, //tilde operator = varies with = similar to,U+223C ISOtech --> +// + {"cong", "8773"}, //approximately equal to, U+2245 ISOtech --> + {"asymp", "8776"}, //almost equal to = asymptotic to,U+2248 ISOamsr --> + {"ne", "8800"}, //not equal to, U+2260 ISOtech --> + {"equiv", "8801"}, //identical to, U+2261 ISOtech --> + {"le", "8804"}, //less-than or equal to, U+2264 ISOtech --> + {"ge", "8805"}, //greater-than or equal to,U+2265 ISOtech --> + {"sub", "8834"}, //subset of, U+2282 ISOtech --> + {"sup", "8835"}, //superset of, U+2283 ISOtech --> +// + {"sube", "8838"}, //subset of or equal to, U+2286 ISOtech --> + {"supe", "8839"}, //superset of or equal to,U+2287 ISOtech --> + {"oplus", "8853"}, //circled plus = direct sum,U+2295 ISOamsb --> + {"otimes", "8855"}, //circled times = vector product,U+2297 ISOamsb --> + {"perp", "8869"}, //up tack = orthogonal to = perpendicular,U+22A5 ISOtech --> + {"sdot", "8901"}, //dot operator, U+22C5 ISOamsb --> +// +// + {"lceil", "8968"}, //left ceiling = apl upstile,U+2308 ISOamsc --> + {"rceil", "8969"}, //right ceiling, U+2309 ISOamsc --> + {"lfloor", "8970"}, //left floor = apl downstile,U+230A ISOamsc --> + {"rfloor", "8971"}, //right floor, U+230B ISOamsc --> + {"lang", "9001"}, //left-pointing angle bracket = bra,U+2329 ISOtech --> +// + {"rang", "9002"}, //right-pointing angle bracket = ket,U+232A ISOtech --> +// +// + {"loz", "9674"}, //lozenge, U+25CA ISOpub --> +// + {"spades", "9824"}, //black spade suit, U+2660 ISOpub --> +// + {"clubs", "9827"}, //black club suit = shamrock,U+2663 ISOpub --> + {"hearts", "9829"}, //black heart suit = valentine,U+2665 ISOpub --> + {"diams", "9830"}, //black diamond suit, U+2666 ISOpub --> + +// + {"OElig", "338"}, // -- latin capital ligature OE,U+0152 ISOlat2 --> + {"oelig", "339"}, // -- latin small ligature oe, U+0153 ISOlat2 --> +// + {"Scaron", "352"}, // -- latin capital letter S with caron,U+0160 ISOlat2 --> + {"scaron", "353"}, // -- latin small letter s with caron,U+0161 ISOlat2 --> + {"Yuml", "376"}, // -- latin capital letter Y with diaeresis,U+0178 ISOlat2 --> +// + {"circ", "710"}, // -- modifier letter circumflex accent,U+02C6 ISOpub --> + {"tilde", "732"}, //small tilde, U+02DC ISOdia --> +// + {"ensp", "8194"}, //en space, U+2002 ISOpub --> + {"emsp", "8195"}, //em space, U+2003 ISOpub --> + {"thinsp", "8201"}, //thin space, U+2009 ISOpub --> + {"zwnj", "8204"}, //zero width non-joiner,U+200C NEW RFC 2070 --> + {"zwj", "8205"}, //zero width joiner, U+200D NEW RFC 2070 --> + {"lrm", "8206"}, //left-to-right mark, U+200E NEW RFC 2070 --> + {"rlm", "8207"}, //right-to-left mark, U+200F NEW RFC 2070 --> + {"ndash", "8211"}, //en dash, U+2013 ISOpub --> + {"mdash", "8212"}, //em dash, U+2014 ISOpub --> + {"lsquo", "8216"}, //left single quotation mark,U+2018 ISOnum --> + {"rsquo", "8217"}, //right single quotation mark,U+2019 ISOnum --> + {"sbquo", "8218"}, //single low-9 quotation mark, U+201A NEW --> + {"ldquo", "8220"}, //left double quotation mark,U+201C ISOnum --> + {"rdquo", "8221"}, //right double quotation mark,U+201D ISOnum --> + {"bdquo", "8222"}, //double low-9 quotation mark, U+201E NEW --> + {"dagger", "8224"}, //dagger, U+2020 ISOpub --> + {"Dagger", "8225"}, //double dagger, U+2021 ISOpub --> + {"permil", "8240"}, //per mille sign, U+2030 ISOtech --> + {"lsaquo", "8249"}, //single left-pointing angle quotation mark,U+2039 ISO proposed --> +// + {"rsaquo", "8250"}, //single right-pointing angle quotation mark,U+203A ISO proposed --> +// + {"euro", "8364"}, // -- euro sign, U+20AC NEW --> + }; + + /** + *

The set of entities supported by standard XML.

+ */ + public static final Entities XML; + + /** + *

The set of entities supported by HTML 3.2.

+ */ + public static final Entities HTML32; + + /** + *

The set of entities supported by HTML 4.0.

+ */ + public static final Entities HTML40; + + static { + XML = new Entities(); + XML.addEntities(BASIC_ARRAY); + XML.addEntities(APOS_ARRAY); + } + + static { + HTML32 = new Entities(); + HTML32.addEntities(BASIC_ARRAY); + HTML32.addEntities(ISO8859_1_ARRAY); + } + + static { + HTML40 = new Entities(); + fillWithHtml40Entities(HTML40); + } + + static void fillWithHtml40Entities(Entities entities) { + entities.addEntities(BASIC_ARRAY); + entities.addEntities(ISO8859_1_ARRAY); + entities.addEntities(HTML40_ARRAY); + } + + static interface EntityMap { + void add(String name, int value); + + String name(int value); + + int value(String name); + } + + static class PrimitiveEntityMap implements EntityMap { + private Map mapNameToValue = new HashMap(); + private IntHashMap mapValueToName = new IntHashMap(); + + public void add(String name, int value) { + mapNameToValue.put(name, new Integer(value)); + mapValueToName.put(value, name); + } + + public String name(int value) { + return (String) mapValueToName.get(value); + } + + public int value(String name) { + Object value = mapNameToValue.get(name); + if (value == null) + return -1; + return ((Integer) value).intValue(); + } + } + + + static abstract class MapIntMap implements Entities.EntityMap { + protected Map mapNameToValue; + protected Map mapValueToName; + + public void add(String name, int value) { + mapNameToValue.put(name, new Integer(value)); + mapValueToName.put(new Integer(value), name); + } + + public String name(int value) { + return (String) mapValueToName.get(new Integer(value)); + } + + public int value(String name) { + Object value = mapNameToValue.get(name); + if (value == null) + return -1; + return ((Integer) value).intValue(); + } + } + + static class HashEntityMap extends MapIntMap { + public HashEntityMap() { + mapNameToValue = new HashMap(); + mapValueToName = new HashMap(); + } + } + + static class TreeEntityMap extends MapIntMap { + public TreeEntityMap() { + mapNameToValue = new TreeMap(); + mapValueToName = new TreeMap(); + } + } + + static class LookupEntityMap extends PrimitiveEntityMap { + private String[] lookupTable; + private int LOOKUP_TABLE_SIZE = 256; + + public String name(int value) { + if (value < LOOKUP_TABLE_SIZE) { + return lookupTable()[value]; + } + return super.name(value); + } + + private String[] lookupTable() { + if (lookupTable == null) { + createLookupTable(); + } + return lookupTable; + } + + private void createLookupTable() { + lookupTable = new String[LOOKUP_TABLE_SIZE]; + for (int i = 0; i < LOOKUP_TABLE_SIZE; ++i) { + lookupTable[i] = super.name(i); + } + } + } + + static class ArrayEntityMap implements EntityMap { + protected int growBy = 100; + protected int size = 0; + protected String[] names; + protected int[] values; + + public ArrayEntityMap() { + names = new String[growBy]; + values = new int[growBy]; + } + + public ArrayEntityMap(int growBy) { + this.growBy = growBy; + names = new String[growBy]; + values = new int[growBy]; + } + + public void add(String name, int value) { + ensureCapacity(size + 1); + names[size] = name; + values[size] = value; + size++; + } + + protected void ensureCapacity(int capacity) { + if (capacity > names.length) { + int newSize = Math.max(capacity, size + growBy); + String[] newNames = new String[newSize]; + System.arraycopy(names, 0, newNames, 0, size); + names = newNames; + int[] newValues = new int[newSize]; + System.arraycopy(values, 0, newValues, 0, size); + values = newValues; + } + } + + public String name(int value) { + for (int i = 0; i < size; ++i) { + if (values[i] == value) { + return names[i]; + } + } + return null; + } + + public int value(String name) { + for (int i = 0; i < size; ++i) { + if (names[i].equals(name)) { + return values[i]; + } + } + return -1; + } + } + + static class BinaryEntityMap extends ArrayEntityMap { + + public BinaryEntityMap() { + } + + public BinaryEntityMap(int growBy) { + super(growBy); + } + + // based on code in java.util.Arrays + private int binarySearch(int key) { + int low = 0; + int high = size - 1; + + while (low <= high) { + int mid = (low + high) >> 1; + int midVal = values[mid]; + + if (midVal < key) + low = mid + 1; + else if (midVal > key) + high = mid - 1; + else + return mid; // key found + } + return -(low + 1); // key not found. + } + + public void add(String name, int value) { + ensureCapacity(size + 1); + int insertAt = binarySearch(value); + if (insertAt > 0) return; // note: this means you can't insert the same value twice + insertAt = -(insertAt + 1); // binarySearch returns it negative and off-by-one + System.arraycopy(values, insertAt, values, insertAt + 1, size - insertAt); + values[insertAt] = value; + System.arraycopy(names, insertAt, names, insertAt + 1, size - insertAt); + names[insertAt] = name; + size++; + } + + public String name(int value) { + int index = binarySearch(value); + if (index < 0) return null; + return names[index]; + } + } + + // package scoped for testing + EntityMap map = new Entities.LookupEntityMap(); + + public void addEntities(String[][] entityArray) { + for (int i = 0; i < entityArray.length; ++i) { + addEntity(entityArray[i][0], Integer.parseInt(entityArray[i][1])); + } + } + + public void addEntity(String name, int value) { + map.add(name, value); + } + + public String entityName(int value) { + return map.name(value); + } + + + public int entityValue(String name) { + return map.value(name); + } + + /** + *

Escapes the characters in a String.

+ * + *

For example, if you have called addEntity("foo", 0xA1), + * escape("\u00A1") will return "&foo;"

+ * + * @param str The String to escape. + * @return A new escaped String. + */ + public String escape(String str) { + //todo: rewrite to use a Writer + StringBuffer buf = new StringBuffer(str.length() * 2); + int i; + for (i = 0; i < str.length(); ++i) { + char ch = str.charAt(i); + String entityName = this.entityName(ch); + if (entityName == null) { + if (ch > 0x7F) { + int intValue = ch; + buf.append("&#"); + buf.append(intValue); + buf.append(';'); + } else { + buf.append(ch); + } + } else { + buf.append('&'); + buf.append(entityName); + buf.append(';'); + } + } + return buf.toString(); + } + + /** + *

Unescapes the entities in a String.

+ * + *

For example, if you have called addEntity("foo", 0xA1), + * unescape("&foo;") will return "\u00A1"

+ * + * @param str The String to escape. + * @return A new escaped String. + */ + public String unescape(String str) { + StringBuffer buf = new StringBuffer(str.length()); + int i; + for (i = 0; i < str.length(); ++i) { + char ch = str.charAt(i); + if (ch == '&') { + int semi = str.indexOf(';', i + 1); + if (semi == -1) { + buf.append(ch); + continue; + } + String entityName = str.substring(i + 1, semi); + int entityValue; + if (entityName.charAt(0) == '#') { + entityValue = Integer.parseInt(entityName.substring(1)); + } else { + entityValue = this.entityValue(entityName); + } + if (entityValue == -1) { + buf.append('&'); + buf.append(entityName); + buf.append(';'); + } else { + buf.append((char) (entityValue)); + } + i = semi; + } else { + buf.append(ch); + } + } + return buf.toString(); + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/IllegalClassException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/IllegalClassException.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/IllegalClassException.java 30 Aug 2012 16:24:42 -0000 1.1 @@ -0,0 +1,100 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang; + +/** + *

Thrown when an object is an instance of an unexpected type (a class or interface).

+ * + * @author Matthew Hawthorne + * @author Gary Gregory + * @since 2.0 + * @version $Id: IllegalClassException.java,v 1.1 2012/08/30 16:24:42 marcin Exp $ + */ +public class IllegalClassException extends IllegalArgumentException { + + /** + *

Instantiates with the specified types (classes or interfaces).

+ * + * @param expected the expected type + * @param actual the actual type + */ + public IllegalClassException(Class expected, Class actual) { + super( + "Expected: " + + safeGetClassName(expected) + + ", actual: " + + safeGetClassName(actual)); + } + + /** + *

Instantiates with the specified message.

+ * + * @param message the exception message + */ + public IllegalClassException(String message) { + super(message); + } + + /** + *

Returns the class name or null if the class is + * null.

+ * + * @param cls a Class + * @return the name of cls, or null if if cls is null. + */ + private static final String safeGetClassName(Class cls) { + return cls == null ? null : cls.getName(); + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/IncompleteArgumentException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/IncompleteArgumentException.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/IncompleteArgumentException.java 30 Aug 2012 16:24:42 -0000 1.1 @@ -0,0 +1,99 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang; + +import java.util.Arrays; + +/** + *

Thrown to indicate an incomplete argument to a method.

+ * + * @author Matthew Hawthorne + * @since 2.0 + * @version $Id: IncompleteArgumentException.java,v 1.1 2012/08/30 16:24:42 marcin Exp $ + */ +public class IncompleteArgumentException extends IllegalArgumentException { + + /** + *

Instantiates with the specified description.

+ * + * @param argName a description of the incomplete argument + */ + public IncompleteArgumentException(String argName) { + super(argName + " is incomplete."); + } + + /** + *

Instantiates with the specified description.

+ * + * @param argName a description of the incomplete argument + * @param items an array describing the arguments missing + */ + public IncompleteArgumentException(String argName, String[] items) { + super( + argName + + " is missing the following items: " + + safeArrayToString(items)); + } + + /** + *

7Converts an array to a string without throwing an exception.

+ * + * @param array an array + * @return the array as a string + */ + private static final String safeArrayToString(Object[] array) { + return array == null ? null : Arrays.asList(array).toString(); + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/IntHashMap.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/IntHashMap.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/IntHashMap.java 30 Aug 2012 16:24:42 -0000 1.1 @@ -0,0 +1,400 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +/* + * Note: originally released under the GNU LGPL v2.1, + * but rereleased by the original author under the ASF license (above). + */ +package org.apache.commons.lang; + +/** + *

A hash map that uses primitive ints for the key rather than objects.

+ * + *

Note that this class is for internal optimization purposes only, and may + * not be supported in future releases of Jakarta Commons Lang. Utilities of + * this sort may be included in future releases of Jakarta Commons Collections.

+ * + * @author Justin Couch + * @author Alex Chaffee (alex@apache.org) + * @author Stephen Colebourne + * @since 2.0 + * @version $Revision: 1.1 $ + * @see java.util.HashMap + */ +class IntHashMap { + + /** + * The hash table data. + */ + private transient Entry table[]; + + /** + * The total number of entries in the hash table. + */ + private transient int count; + + /** + * The table is rehashed when its size exceeds this threshold. (The + * value of this field is (int)(capacity * loadFactor).) + * + * @serial + */ + private int threshold; + + /** + * The load factor for the hashtable. + * + * @serial + */ + private float loadFactor; + + /** + *

Innerclass that acts as a datastructure to create a new entry in the + * table.

+ */ + private static class Entry { + int hash; + int key; + Object value; + Entry next; + + /** + *

Create a new entry with the given values.

+ * + * @param hash The code used to hash the object with + * @param key The key used to enter this in the table + * @param value The value for this key + * @param next A reference to the next entry in the table + */ + protected Entry(int hash, int key, Object value, Entry next) { + this.hash = hash; + this.key = key; + this.value = value; + this.next = next; + } + } + + /** + *

Constructs a new, empty hashtable with a default capacity and load + * factor, which is 20 and 0.75 respectively.

+ */ + public IntHashMap() { + this(20, 0.75f); + } + + /** + *

Constructs a new, empty hashtable with the specified initial capacity + * and default load factor, which is 0.75.

+ * + * @param initialCapacity the initial capacity of the hashtable. + * @throws IllegalArgumentException if the initial capacity is less + * than zero. + */ + public IntHashMap(int initialCapacity) { + this(initialCapacity, 0.75f); + } + + /** + *

Constructs a new, empty hashtable with the specified initial + * capacity and the specified load factor.

+ * + * @param initialCapacity the initial capacity of the hashtable. + * @param loadFactor the load factor of the hashtable. + * @throws IllegalArgumentException if the initial capacity is less + * than zero, or if the load factor is nonpositive. + */ + public IntHashMap(int initialCapacity, float loadFactor) { + super(); + if (initialCapacity < 0) { + throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity); + } + if (loadFactor <= 0) { + throw new IllegalArgumentException("Illegal Load: " + loadFactor); + } + if (initialCapacity == 0) { + initialCapacity = 1; + } + + this.loadFactor = loadFactor; + table = new Entry[initialCapacity]; + threshold = (int) (initialCapacity * loadFactor); + } + + /** + *

Returns the number of keys in this hashtable.

+ * + * @return the number of keys in this hashtable. + */ + public int size() { + return count; + } + + /** + *

Tests if this hashtable maps no keys to values.

+ * + * @return true if this hashtable maps no keys to values; + * false otherwise. + */ + public boolean isEmpty() { + return count == 0; + } + + /** + *

Tests if some key maps into the specified value in this hashtable. + * This operation is more expensive than the containsKey + * method.

+ * + *

Note that this method is identical in functionality to containsValue, + * (which is part of the Map interface in the collections framework).

+ * + * @param value a value to search for. + * @return true if and only if some key maps to the + * value argument in this hashtable as + * determined by the equals method; + * false otherwise. + * @throws NullPointerException if the value is null. + * @see #containsKey(int) + * @see #containsValue(Object) + * @see java.util.Map + */ + public boolean contains(Object value) { + if (value == null) { + throw new NullPointerException(); + } + + Entry tab[] = table; + for (int i = tab.length; i-- > 0;) { + for (Entry e = tab[i]; e != null; e = e.next) { + if (e.value.equals(value)) { + return true; + } + } + } + return false; + } + + /** + *

Returns true if this HashMap maps one or more keys + * to this value.

+ * + *

Note that this method is identical in functionality to contains + * (which predates the Map interface).

+ * + * @param value value whose presence in this HashMap is to be tested. + * @see java.util.Map + * @since JDK1.2 + */ + public boolean containsValue(Object value) { + return contains(value); + } + + /** + *

Tests if the specified object is a key in this hashtable.

+ * + * @param key possible key. + * @return true if and only if the specified object is a + * key in this hashtable, as determined by the equals + * method; false otherwise. + * @see #contains(Object) + */ + public boolean containsKey(int key) { + Entry tab[] = table; + int hash = key; + int index = (hash & 0x7FFFFFFF) % tab.length; + for (Entry e = tab[index]; e != null; e = e.next) { + if (e.hash == hash) { + return true; + } + } + return false; + } + + /** + *

Returns the value to which the specified key is mapped in this map.

+ * + * @param key a key in the hashtable. + * @return the value to which the key is mapped in this hashtable; + * null if the key is not mapped to any value in + * this hashtable. + * @see #put(int, Object) + */ + public Object get(int key) { + Entry tab[] = table; + int hash = key; + int index = (hash & 0x7FFFFFFF) % tab.length; + for (Entry e = tab[index]; e != null; e = e.next) { + if (e.hash == hash) { + return e.value; + } + } + return null; + } + + /** + *

Increases the capacity of and internally reorganizes this + * hashtable, in order to accommodate and access its entries more + * efficiently.

+ * + *

This method is called automatically when the number of keys + * in the hashtable exceeds this hashtable's capacity and load + * factor.

+ */ + protected void rehash() { + int oldCapacity = table.length; + Entry oldMap[] = table; + + int newCapacity = oldCapacity * 2 + 1; + Entry newMap[] = new Entry[newCapacity]; + + threshold = (int) (newCapacity * loadFactor); + table = newMap; + + for (int i = oldCapacity; i-- > 0;) { + for (Entry old = oldMap[i]; old != null;) { + Entry e = old; + old = old.next; + + int index = (e.hash & 0x7FFFFFFF) % newCapacity; + e.next = newMap[index]; + newMap[index] = e; + } + } + } + + /** + *

Maps the specified key to the specified + * value in this hashtable. The key cannot be + * null.

+ * + *

The value can be retrieved by calling the get method + * with a key that is equal to the original key.

+ * + * @param key the hashtable key. + * @param value the value. + * @return the previous value of the specified key in this hashtable, + * or null if it did not have one. + * @throws NullPointerException if the key is null. + * @see #get(int) + */ + public Object put(int key, Object value) { + // Makes sure the key is not already in the hashtable. + Entry tab[] = table; + int hash = key; + int index = (hash & 0x7FFFFFFF) % tab.length; + for (Entry e = tab[index]; e != null; e = e.next) { + if (e.hash == hash) { + Object old = e.value; + e.value = value; + return old; + } + } + + if (count >= threshold) { + // Rehash the table if the threshold is exceeded + rehash(); + + tab = table; + index = (hash & 0x7FFFFFFF) % tab.length; + } + + // Creates the new entry. + Entry e = new Entry(hash, key, value, tab[index]); + tab[index] = e; + count++; + return null; + } + + /** + *

Removes the key (and its corresponding value) from this + * hashtable.

+ * + *

This method does nothing if the key is not present in the + * hashtable.

+ * + * @param key the key that needs to be removed. + * @return the value to which the key had been mapped in this hashtable, + * or null if the key did not have a mapping. + */ + public Object remove(int key) { + Entry tab[] = table; + int hash = key; + int index = (hash & 0x7FFFFFFF) % tab.length; + for (Entry e = tab[index], prev = null; e != null; prev = e, e = e.next) { + if (e.hash == hash) { + if (prev != null) { + prev.next = e.next; + } else { + tab[index] = e.next; + } + count--; + Object oldValue = e.value; + e.value = null; + return oldValue; + } + } + return null; + } + + /** + *

Clears this hashtable so that it contains no keys.

+ */ + public synchronized void clear() { + Entry tab[] = table; + for (int index = tab.length; --index >= 0;) { + tab[index] = null; + } + count = 0; + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/NotImplementedException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/NotImplementedException.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/NotImplementedException.java 30 Aug 2012 16:24:42 -0000 1.1 @@ -0,0 +1,85 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang; + +/** + *

Thrown to indicate that a method has not been implemented.

+ * + * @author Matthew Hawthorne + * @since 2.0 + * @version $Id: NotImplementedException.java,v 1.1 2012/08/30 16:24:42 marcin Exp $ + */ +public class NotImplementedException extends UnsupportedOperationException { + + /** + *

Constructes the exception with the specified class.

+ * + * @param clazz the Class that has not implemented the method + */ + public NotImplementedException(Class clazz) { + super( + "Method is not implemented in class " + + ((clazz == null) ? null : clazz.getName())); + } + + /** + *

Constructs the exception with the specified message.

+ * + * @param msg the exception message. + */ + public NotImplementedException(String msg) { + super(msg); + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/NullArgumentException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/NullArgumentException.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/NullArgumentException.java 30 Aug 2012 16:24:42 -0000 1.1 @@ -0,0 +1,76 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang; + +/** + *

Thrown to indicate that an argument was null and should + * not have been.

+ * + * @author Matthew Hawthorne + * @author Stephen Colebourne + * @since 2.0 + * @version $Id: NullArgumentException.java,v 1.1 2012/08/30 16:24:42 marcin Exp $ + */ +public class NullArgumentException extends IllegalArgumentException { + + /** + *

Instantiates with the given argument name.

+ * + * @param argName the name of the argument that was null. + */ + public NullArgumentException(String argName) { + super(argName + " must not be null."); + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/NumberRange.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/NumberRange.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/NumberRange.java 30 Aug 2012 16:24:42 -0000 1.1 @@ -0,0 +1,257 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang; + +/** + *

Represents a range of {@link Number} objects.

+ * + *

This class uses double comparisons. This means that it + * is unsuitable for dealing with large Long, BigDecimal + * or BigInteger numbers.

+ * + * @author Christopher Elkins + * @author Stephen Colebourne + * @since 1.0 + * @version $Revision: 1.1 $ $Date: 2012/08/30 16:24:42 $ + * + * @deprecated Use one of the Range classes in org.apache.commons.lang.math. + * Class will be removed in Commons Lang 3.0. + * + */ +public final class NumberRange { + + /* The minimum number in this range. */ + private final Number min; + + /* The maximum number in this range. */ + private final Number max; + + + /** + *

Constructs a new NumberRange using + * number as both the minimum and maximum in + * this range.

+ * + * @param num the number to use for this range + * @throws NullPointerException if the number is null + */ + public NumberRange(Number num) { + if (num == null) { + throw new NullPointerException("The number must not be null"); + } + + this.min = num; + this.max = num; + } + + /** + *

Constructs a new NumberRange with the specified + * minimum and maximum numbers.

+ * + *

If the maximum is less than the minimum, the range will be constructed + * from the minimum value to the minimum value, not what you would expect!.

+ * + * @param min the minimum number in this range + * @param max the maximum number in this range + * @throws NullPointerException if either the minimum or maximum number is + * null + */ + public NumberRange(Number min, Number max) { + if (min == null) { + throw new NullPointerException("The minimum value must not be null"); + } else if (max == null) { + throw new NullPointerException("The maximum value must not be null"); + } + + if (max.doubleValue() < min.doubleValue()) { + this.min = this.max = min; + } else { + this.min = min; + this.max = max; + } + } + + /** + *

Returns the minimum number in this range.

+ * + * @return the minimum number in this range + */ + public Number getMinimum() { + return min; + } + + /** + *

Returns the maximum number in this range.

+ * + * @return the maximum number in this range + */ + public Number getMaximum() { + return max; + } + + /** + *

Tests whether the specified number occurs within + * this range using double comparison.

+ * + * @param number the number to test + * @return true if the specified number occurs within this + * range; otherwise, false + */ + public boolean includesNumber(Number number) { + if (number == null) { + return false; + } else { + return !(min.doubleValue() > number.doubleValue()) && + !(max.doubleValue() < number.doubleValue()); + } + } + + /** + *

Tests whether the specified range occurs entirely within this + * range using double comparison.

+ * + * @param range the range to test + * @return true if the specified range occurs entirely within + * this range; otherwise, false + */ + public boolean includesRange(NumberRange range) { + if (range == null) { + return false; + } else { + return includesNumber(range.min) && includesNumber(range.max); + } + } + + /** + *

Tests whether the specified range overlaps with this range + * using double comparison.

+ * + * @param range the range to test + * @return true if the specified range overlaps with this + * range; otherwise, false + */ + public boolean overlaps(NumberRange range) { + if (range == null) { + return false; + } else { + return range.includesNumber(min) || range.includesNumber(max) || + includesRange(range); + } + } + + /** + *

Indicates whether some other Object is + * "equal" to this one.

+ * + * @param obj the reference object with which to compare + * @return true if this object is the same as the obj + * argument; false otherwise + */ + public boolean equals(Object obj) { + if (obj == this) { + return true; + } else if (!(obj instanceof NumberRange)) { + return false; + } else { + NumberRange range = (NumberRange)obj; + return min.equals(range.min) && max.equals(range.max); + } + } + + /** + *

Returns a hash code value for this object.

+ * + * @return a hash code value for this object + */ + public int hashCode() { + int result = 17; + result = 37 * result + min.hashCode(); + result = 37 * result + max.hashCode(); + return result; + } + + /** + *

Returns the string representation of this range.

+ * + *

This string is the string representation of the minimum and + * maximum numbers in the range, separated by a hyphen. If a number + * is negative, then it is enclosed in parentheses.

+ * + * @return the string representation of this range + */ + public String toString() { + StringBuffer sb = new StringBuffer(); + + if (min.doubleValue() < 0) { + sb.append('(') + .append(min) + .append(')'); + } else { + sb.append(min); + } + + sb.append('-'); + + if (max.doubleValue() < 0) { + sb.append('(') + .append(max) + .append(')'); + } else { + sb.append(max); + } + + return sb.toString(); + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/NumberUtils.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/NumberUtils.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/NumberUtils.java 30 Aug 2012 16:24:42 -0000 1.1 @@ -0,0 +1,743 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang; + +import java.math.BigDecimal; +import java.math.BigInteger; + +/** + *

Provides extra functionality for Java Number classes.

+ * + * @author Henri Yandell + * @author Rand McNeely + * @author Stephen Colebourne + * @author Steve Downey + * @author Eric Pugh + * @author Phil Steitz + * @since 1.0 + * @version $Id: NumberUtils.java,v 1.1 2012/08/30 16:24:42 marcin Exp $ + * + * @deprecated Moved to org.apache.commons.lang.math. + * Class will be removed in Commons Lang 3.0. + */ +public final class NumberUtils { + // DEPRECATED CLASS !!! + + /** + *

NumberUtils instances should NOT be constructed in standard programming. + * Instead, the class should be used as NumberUtils.stringToInt("6");.

+ * + *

This constructor is public to permit tools that require a JavaBean instance + * to operate.

+ */ + public NumberUtils() { + } + + //-------------------------------------------------------------------- + + /** + *

Convert a String to an int, returning + * zero if the conversion fails.

+ * + * @param str the string to convert + * @return the int represented by the string, or zero if + * conversion fails + */ + public static int stringToInt(String str) { + return stringToInt(str, 0); + } + + /** + *

Convert a String to an int, returning a + * default value if the conversion fails.

+ * + * @param str the string to convert + * @param defaultValue the default value + * @return the int represented by the string, or the default if conversion fails + */ + public static int stringToInt(String str, int defaultValue) { + try { + return Integer.parseInt(str); + } catch (NumberFormatException nfe) { + return defaultValue; + } + } + + //-------------------------------------------------------------------- + + // must handle Long, Float, Integer, Float, Short, + // BigDecimal, BigInteger and Byte + // useful methods: + // Byte.decode(String) + // Byte.valueOf(String,int radix) + // Byte.valueOf(String) + // Double.valueOf(String) + // Float.valueOf(String) + // new Float(String) + // Integer.valueOf(String,int radix) + // Integer.valueOf(String) + // Integer.decode(String) + // Integer.getInteger(String) + // Integer.getInteger(String,int val) + // Integer.getInteger(String,Integer val) + // new Integer(String) + // new Double(String) + // new Byte(String) + // new Long(String) + // Long.getLong(String) + // Long.getLong(String,int) + // Long.getLong(String,Integer) + // Long.valueOf(String,int) + // Long.valueOf(String) + // new Short(String) + // Short.decode(String) + // Short.valueOf(String,int) + // Short.valueOf(String) + // new BigDecimal(String) + // new BigInteger(String) + // new BigInteger(String,int radix) + // Possible inputs: + // 45 45.5 45E7 4.5E7 Hex Oct Binary xxxF xxxD xxxf xxxd + // plus minus everything. Prolly more. A lot are not separable. + + /** + *

Turns a string value into a java.lang.Number.

+ * + *

First, the value is examined for a type qualifier on the end + * ('f','F','d','D','l','L'). If it is found, it starts + * trying to create succissively larger types from the type specified + * until one is found that can hold the value.

+ * + *

If a type specifier is not found, it will check for a decimal point + * and then try successively larger types from Integer to + * BigInteger and from Float to + * BigDecimal.

+ * + *

If the string starts with 0x or -0x, it + * will be interpreted as a hexadecimal integer. Values with leading + * 0's will not be interpreted as octal.

+ * + * @param val String containing a number + * @return Number created from the string + * @throws NumberFormatException if the value cannot be converted + */ + public static Number createNumber(String val) throws NumberFormatException { + if (val == null) { + return null; + } + if (val.length() == 0) { + throw new NumberFormatException("\"\" is not a valid number."); + } + if (val.startsWith("--")) { + // this is protection for poorness in java.lang.BigDecimal. + // it accepts this as a legal value, but it does not appear + // to be in specification of class. OS X Java parses it to + // a wrong value. + return null; + } + if (val.startsWith("0x") || val.startsWith("-0x")) { + return createInteger(val); + } + char lastChar = val.charAt(val.length() - 1); + String mant; + String dec; + String exp; + int decPos = val.indexOf('.'); + int expPos = val.indexOf('e') + val.indexOf('E') + 1; + + if (decPos > -1) { + + if (expPos > -1) { + if (expPos < decPos) { + throw new NumberFormatException(val + " is not a valid number."); + } + dec = val.substring(decPos + 1, expPos); + } else { + dec = val.substring(decPos + 1); + } + mant = val.substring(0, decPos); + } else { + if (expPos > -1) { + mant = val.substring(0, expPos); + } else { + mant = val; + } + dec = null; + } + if (!Character.isDigit(lastChar)) { + if (expPos > -1 && expPos < val.length() - 1) { + exp = val.substring(expPos + 1, val.length() - 1); + } else { + exp = null; + } + //Requesting a specific type.. + String numeric = val.substring(0, val.length() - 1); + boolean allZeros = isAllZeros(mant) && isAllZeros(exp); + switch (lastChar) { + case 'l' : + case 'L' : + if (dec == null + && exp == null + && isDigits(numeric.substring(1)) + && (numeric.charAt(0) == '-' || Character.isDigit(numeric.charAt(0)))) { + try { + return createLong(numeric); + } catch (NumberFormatException nfe) { + //Too big for a long + } + return createBigInteger(numeric); + + } + throw new NumberFormatException(val + " is not a valid number."); + case 'f' : + case 'F' : + try { + Float f = NumberUtils.createFloat(numeric); + if (!(f.isInfinite() || (f.floatValue() == 0.0F && !allZeros))) { + //If it's too big for a float or the float value = 0 and the string + //has non-zeros in it, then float doens't have the presision we want + return f; + } + + } catch (NumberFormatException nfe) { + } + //Fall through + case 'd' : + case 'D' : + try { + Double d = NumberUtils.createDouble(numeric); + if (!(d.isInfinite() || (d.floatValue() == 0.0D && !allZeros))) { + return d; + } + } catch (NumberFormatException nfe) { + } + try { + return createBigDecimal(numeric); + } catch (NumberFormatException e) { + } + //Fall through + default : + throw new NumberFormatException(val + " is not a valid number."); + + } + } else { + //User doesn't have a preference on the return type, so let's start + //small and go from there... + if (expPos > -1 && expPos < val.length() - 1) { + exp = val.substring(expPos + 1, val.length()); + } else { + exp = null; + } + if (dec == null && exp == null) { + //Must be an int,long,bigint + try { + return createInteger(val); + } catch (NumberFormatException nfe) { + } + try { + return createLong(val); + } catch (NumberFormatException nfe) { + } + return createBigInteger(val); + + } else { + //Must be a float,double,BigDec + boolean allZeros = isAllZeros(mant) && isAllZeros(exp); + try { + Float f = createFloat(val); + if (!(f.isInfinite() || (f.floatValue() == 0.0F && !allZeros))) { + return f; + } + } catch (NumberFormatException nfe) { + } + try { + Double d = createDouble(val); + if (!(d.isInfinite() || (d.doubleValue() == 0.0D && !allZeros))) { + return d; + } + } catch (NumberFormatException nfe) { + } + + return createBigDecimal(val); + + } + + } + } + + /** + *

Utility method for {@link #createNumber(java.lang.String)}.

+ * + *

Returns true if s is null.

+ * + * @param s the String to check + * @return if it is all zeros or null + */ + private static boolean isAllZeros(String s) { + if (s == null) { + return true; + } + for (int i = s.length() - 1; i >= 0; i--) { + if (s.charAt(i) != '0') { + return false; + } + } + return s.length() > 0; + } + + //-------------------------------------------------------------------- + + /** + *

Convert a String to a Float.

+ * + * @param val a String to convert + * @return converted Float + * @throws NumberFormatException if the value cannot be converted + */ + public static Float createFloat(String val) { + return Float.valueOf(val); + } + + /** + *

Convert a String to a Double.

+ * + * @param val a String to convert + * @return converted Double + * @throws NumberFormatException if the value cannot be converted + */ + public static Double createDouble(String val) { + return Double.valueOf(val); + } + + /** + *

Convert a String to a Integer, handling + * hex and octal notations.

+ * + * @param val a String to convert + * @return converted Integer + * @throws NumberFormatException if the value cannot be converted + */ + public static Integer createInteger(String val) { + // decode() handles 0xAABD and 0777 (hex and octal) as well. + return Integer.decode(val); + } + + /** + *

Convert a String to a Long.

+ * + * @param val a String to convert + * @return converted Long + * @throws NumberFormatException if the value cannot be converted + */ + public static Long createLong(String val) { + return Long.valueOf(val); + } + + /** + *

Convert a String to a BigInteger.

+ * + * @param val a String to convert + * @return converted BigInteger + * @throws NumberFormatException if the value cannot be converted + */ + public static BigInteger createBigInteger(String val) { + BigInteger bi = new BigInteger(val); + return bi; + } + + /** + *

Convert a String to a BigDecimal.

+ * + * @param val a String to convert + * @return converted BigDecimal + * @throws NumberFormatException if the value cannot be converted + */ + public static BigDecimal createBigDecimal(String val) { + BigDecimal bd = new BigDecimal(val); + return bd; + } + + //-------------------------------------------------------------------- + + /** + *

Gets the minimum of three long values.

+ * + * @param a value 1 + * @param b value 2 + * @param c value 3 + * @return the smallest of the values + */ + public static long minimum(long a, long b, long c) { + if (b < a) { + a = b; + } + if (c < a) { + a = c; + } + return a; + } + + /** + *

Gets the minimum of three int values.

+ * + * @param a value 1 + * @param b value 2 + * @param c value 3 + * @return the smallest of the values + */ + public static int minimum(int a, int b, int c) { + if (b < a) { + a = b; + } + if (c < a) { + a = c; + } + return a; + } + + /** + *

Gets the maximum of three long values.

+ * + * @param a value 1 + * @param b value 2 + * @param c value 3 + * @return the largest of the values + */ + public static long maximum(long a, long b, long c) { + if (b > a) { + a = b; + } + if (c > a) { + a = c; + } + return a; + } + + /** + *

Gets the maximum of three int values.

+ * + * @param a value 1 + * @param b value 2 + * @param c value 3 + * @return the largest of the values + */ + public static int maximum(int a, int b, int c) { + if (b > a) { + a = b; + } + if (c > a) { + a = c; + } + return a; + } + + //-------------------------------------------------------------------- + + /** + *

Compares two doubles for order.

+ * + *

This method is more comprehensive than the standard Java greater + * than, less than and equals operators.

+ *
    + *
  • It returns -1 if the first value is less than the second. + *
  • It returns +1 if the first value is greater than the second. + *
  • It returns 0 if the values are equal. + *
+ * + *

+ * The ordering is as follows, largest to smallest: + *

    + *
  • NaN + *
  • Positive infinity + *
  • Maximum double + *
  • Normal positve numbers + *
  • +0.0 + *
  • -0.0 + *
  • Normal negative numbers + *
  • Minimum double (-Double.MAX_VALUE) + *
  • Negative infinity + *
+ *

+ * + *

Comparing NaN with NaN will + * return 0.

+ * + * @param lhs the first double + * @param rhs the second double + * @return -1 if lhs is less, +1 if greater, + * 0 if equal to rhs + */ + public static int compare(double lhs, double rhs) { + if (lhs < rhs) { + return -1; + } + if (lhs > rhs) { + return +1; + } + // Need to compare bits to handle 0.0 == -0.0 being true + // compare should put -0.0 < +0.0 + // Two NaNs are also == for compare purposes + // where NaN == NaN is false + long lhsBits = Double.doubleToLongBits(lhs); + long rhsBits = Double.doubleToLongBits(rhs); + if (lhsBits == rhsBits) { + return 0; + } + // Something exotic! A comparison to NaN or 0.0 vs -0.0 + // Fortunately NaN's long is > than everything else + // Also negzeros bits < poszero + // NAN: 9221120237041090560 + // MAX: 9218868437227405311 + // NEGZERO: -9223372036854775808 + if (lhsBits < rhsBits) { + return -1; + } else { + return +1; + } + } + + /** + *

Compares two floats for order.

+ * + *

This method is more comprhensive than the standard Java greater than, + * less than and equals operators.

+ *
    + *
  • It returns -1 if the first value is less than the second. + *
  • It returns +1 if the first value is greater than the second. + *
  • It returns 0 if the values are equal. + *
+ * + *

The ordering is as follows, largest to smallest: + *

    + *
  • NaN + *
  • Positive infinity + *
  • Maximum float + *
  • Normal positve numbers + *
  • +0.0 + *
  • -0.0 + *
  • Normal negative numbers + *
  • Minimum float (-Float.MAX_VALUE) + *
  • Negative infinity + *
+ * + *

Comparing NaN with NaN will return + * 0.

+ * + * @param lhs the first float + * @param rhs the second float + * @return -1 if lhs is less, +1 if greater, + * 0 if equal to rhs + */ + public static int compare(float lhs, float rhs) { + if (lhs < rhs) { + return -1; + } + if (lhs > rhs) { + return +1; + } + //Need to compare bits to handle 0.0 == -0.0 being true + // compare should put -0.0 < +0.0 + // Two NaNs are also == for compare purposes + // where NaN == NaN is false + int lhsBits = Float.floatToIntBits(lhs); + int rhsBits = Float.floatToIntBits(rhs); + if (lhsBits == rhsBits) { + return 0; + } + //Something exotic! A comparison to NaN or 0.0 vs -0.0 + //Fortunately NaN's int is > than everything else + //Also negzeros bits < poszero + //NAN: 2143289344 + //MAX: 2139095039 + //NEGZERO: -2147483648 + if (lhsBits < rhsBits) { + return -1; + } else { + return +1; + } + } + + //-------------------------------------------------------------------- + + /** + *

Checks whether the String contains only + * digit characters.

+ * + *

Null and empty String will return + * false.

+ * + * @param str the String to check + * @return true if str contains only unicode numeric + */ + public static boolean isDigits(String str) { + if ((str == null) || (str.length() == 0)) { + return false; + } + for (int i = 0; i < str.length(); i++) { + if (!Character.isDigit(str.charAt(i))) { + return false; + } + } + return true; + } + + /** + *

Checks whether the String a valid Java number.

+ * + *

Valid numbers include hexadecimal marked with the 0x + * qualifier, scientific notation and numbers marked with a type + * qualifier (e.g. 123L).

+ * + *

Null and empty String will return + * false.

+ * + * @param str the String to check + * @return true if the string is a correctly formatted number + */ + public static boolean isNumber(String str) { + if ((str == null) || (str.length() == 0)) { + return false; + } + char[] chars = str.toCharArray(); + int sz = chars.length; + boolean hasExp = false; + boolean hasDecPoint = false; + boolean allowSigns = false; + boolean foundDigit = false; + // deal with any possible sign up front + int start = (chars[0] == '-') ? 1 : 0; + if (sz > start + 1) { + if (chars[start] == '0' && chars[start + 1] == 'x') { + int i = start + 2; + if (i == sz) { + return false; // str == "0x" + } + // checking hex (it can't be anything else) + for (; i < chars.length; i++) { + if ((chars[i] < '0' || chars[i] > '9') + && (chars[i] < 'a' || chars[i] > 'f') + && (chars[i] < 'A' || chars[i] > 'F')) { + return false; + } + } + return true; + } + } + sz--; // don't want to loop to the last char, check it afterwords + // for type qualifiers + int i = start; + // loop to the next to last char or to the last char if we need another digit to + // make a valid number (e.g. chars[0..5] = "1234E") + while (i < sz || (i < sz + 1 && allowSigns && !foundDigit)) { + if (chars[i] >= '0' && chars[i] <= '9') { + foundDigit = true; + allowSigns = false; + + } else if (chars[i] == '.') { + if (hasDecPoint || hasExp) { + // two decimal points or dec in exponent + return false; + } + hasDecPoint = true; + } else if (chars[i] == 'e' || chars[i] == 'E') { + // we've already taken care of hex. + if (hasExp) { + // two E's + return false; + } + if (!foundDigit) { + return false; + } + hasExp = true; + allowSigns = true; + } else if (chars[i] == '+' || chars[i] == '-') { + if (!allowSigns) { + return false; + } + allowSigns = false; + foundDigit = false; // we need a digit after the E + } else { + return false; + } + i++; + } + if (i < chars.length) { + if (chars[i] >= '0' && chars[i] <= '9') { + // no type qualifier, OK + return true; + } + if (chars[i] == 'e' || chars[i] == 'E') { + // can't have an E at the last byte + return false; + } + if (!allowSigns + && (chars[i] == 'd' + || chars[i] == 'D' + || chars[i] == 'f' + || chars[i] == 'F')) { + return foundDigit; + } + if (chars[i] == 'l' + || chars[i] == 'L') { + // not allowing L with an exponoent + return foundDigit && !hasExp; + } + // last character is illegal + return false; + } + // allowSigns is true iff the val ends in 'E' + // found digit it to make sure weird stuff like '.' and '1E-' doesn't pass + return !allowSigns && foundDigit; + } +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/ObjectUtils.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/ObjectUtils.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/ObjectUtils.java 30 Aug 2012 16:24:42 -0000 1.1 @@ -0,0 +1,293 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang; + +import java.io.Serializable; + +/** + *

Operations on Object.

+ * + *

This class tries to handle null input gracefully. + * An exception will generally not be thrown for a null input. + * Each method documents its behaviour in more detail.

+ * + * @author Nissim Karpenstein + * @author Janek Bogucki + * @author Daniel Rall + * @author Stephen Colebourne + * @author Gary Gregory + * @since 1.0 + * @version $Id: ObjectUtils.java,v 1.1 2012/08/30 16:24:42 marcin Exp $ + */ +public class ObjectUtils { + + /** + *

Singleton used as a null placeholder where + * null has another meaning.

+ * + *

For example, in a HashMap the + * {@link java.util.HashMap#get(java.lang.Object)} method returns + * null if the Map contains + * null or if there is no matching key. The + * Null placeholder can be used to distinguish between + * these two cases.

+ * + *

Another example is Hashtable, where null + * cannot be stored.

+ * + *

This instance is Serializable.

+ */ + public static final Null NULL = new Null(); + + /** + *

ObjectUtils instances should NOT be constructed in + * standard programming. Instead, the class should be used as + * ObjectUtils.defaultIfNull("a","b");.

+ * + *

This constructor is public to permit tools that require a JavaBean instance + * to operate.

+ */ + public ObjectUtils() { + } + + // Defaulting + //----------------------------------------------------------------------- + /** + *

Returns a default value if the object passed is + * null.

+ * + *
+     * ObjectUtils.defaultIfNull(null, null)      = null
+     * ObjectUtils.defaultIfNull(null, "")        = ""
+     * ObjectUtils.defaultIfNull(null, "zz")      = "zz"
+     * ObjectUtils.defaultIfNull("abc", *)        = "abc"
+     * ObjectUtils.defaultIfNull(Boolean.TRUE, *) = Boolean.TRUE
+     * 
+ * + * @param object the Object to test, may be null + * @param defaultValue the default value to return, may be null + * @return object if it is not null, defaultValue otherwise + */ + public static Object defaultIfNull(Object object, Object defaultValue) { + return (object != null ? object : defaultValue); + } + + /** + *

Compares two objects for equality, where either one or both + * objects may be null.

+ * + *
+     * ObjectUtils.equals(null, null)                  = true
+     * ObjectUtils.equals(null, "")                    = false
+     * ObjectUtils.equals("", null)                    = false
+     * ObjectUtils.equals("", "")                      = true
+     * ObjectUtils.equals(Boolean.TRUE, null)          = false
+     * ObjectUtils.equals(Boolean.TRUE, "true")        = false
+     * ObjectUtils.equals(Boolean.TRUE, Boolean.TRUE)  = true
+     * ObjectUtils.equals(Boolean.TRUE, Boolean.FALSE) = false
+     * 
+ * + * @param object1 the first object, may be null + * @param object2 the second object, may be null + * @return true if the values of both objects are the same + */ + public static boolean equals(Object object1, Object object2) { + if (object1 == object2) { + return true; + } + if ((object1 == null) || (object2 == null)) { + return false; + } + return object1.equals(object2); + } + + // Identity ToString + //----------------------------------------------------------------------- + /** + *

Gets the toString that would be produced by Object + * if a class did not override toString itself. null + * will return null.

+ * + *
+     * ObjectUtils.identityToString(null)         = null
+     * ObjectUtils.identityToString("")           = "java.lang.String@1e23"
+     * ObjectUtils.identityToString(Boolean.TRUE) = "java.lang.Boolean@7fa"
+     * 
+ * + * @param object the object to create a toString for, may be + * null + * @return the default toString text, or null if + * null passed in + */ + public static String identityToString(Object object) { + if (object == null) { + return null; + } + return appendIdentityToString(null, object).toString(); + } + + /** + *

Appends the toString that would be produced by Object + * if a class did not override toString itself. null + * will return null.

+ * + *
+     * ObjectUtils.appendIdentityToString(*, null)            = null
+     * ObjectUtils.appendIdentityToString(null, "")           = "java.lang.String@1e23"
+     * ObjectUtils.appendIdentityToString(null, Boolean.TRUE) = "java.lang.Boolean@7fa"
+     * ObjectUtils.appendIdentityToString(buf, Boolean.TRUE)  = buf.append("java.lang.Boolean@7fa")
+     * 
+ * + * @param buffer the buffer to append to, may be null + * @param object the object to create a toString for, may be null + * @return the default toString text, or null if + * null passed in + * @since 2.0 + */ + public static StringBuffer appendIdentityToString(StringBuffer buffer, Object object) { + if (object == null) { + return null; + } + if (buffer == null) { + buffer = new StringBuffer(); + } + return buffer + .append(object.getClass().getName()) + .append('@') + .append(Integer.toHexString(System.identityHashCode(object))); + } + + // ToString + //----------------------------------------------------------------------- + /** + *

Gets the toString of an Object returning + * an empty string ("") if null input.

+ * + *
+     * ObjectUtils.toString(null)         = ""
+     * ObjectUtils.toString("")           = ""
+     * ObjectUtils.toString("bat")        = "bat"
+     * ObjectUtils.toString(Boolean.TRUE) = "true"
+     * 
+ * + * @see StringUtils#defaultString(String) + * @see String#valueOf(Object) + * @param obj the Object to toString, may be null + * @return the passed in Object's toString, or nullStr if null input + * @since 2.0 + */ + public static String toString(Object obj) { + return (obj == null ? "" : obj.toString()); + } + + /** + *

Gets the toString of an Object returning + * a specified text if null input.

+ * + *
+     * ObjectUtils.toString(null, null)           = null
+     * ObjectUtils.toString(null, "null")         = "null"
+     * ObjectUtils.toString("", "null")           = ""
+     * ObjectUtils.toString("bat", "null")        = "bat"
+     * ObjectUtils.toString(Boolean.TRUE, "null") = "true"
+     * 
+ * + * @see StringUtils#defaultString(String,String) + * @see String#valueOf(Object) + * @param obj the Object to toString, may be null + * @param nullStr the String to return if null input, may be null + * @return the passed in Object's toString, or nullStr if null input + * @since 2.0 + */ + public static String toString(Object obj, String nullStr) { + return (obj == null ? nullStr : obj.toString()); + } + + // Null + //----------------------------------------------------------------------- + /** + *

Class used as a null placeholder where null + * has another meaning.

+ * + *

For example, in a HashMap the + * {@link java.util.HashMap#get(java.lang.Object)} method returns + * null if the Map contains + * null or if there is no matching key. The + * Null placeholder can be used to distinguish between + * these two cases.

+ * + *

Another example is Hashtable, where null + * cannot be stored.

+ */ + public static class Null implements Serializable { + // declare serialization compatability with Commons Lang 1.0 + private static final long serialVersionUID = 7092611880189329093L; + + /** + * Restricted constructor - singleton. + */ + Null() { + } + + /** + *

Ensure singleton.

+ * + * @return the singleton value + */ + private Object readResolve() { + return ObjectUtils.NULL; + } + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/RandomStringUtils.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/RandomStringUtils.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/RandomStringUtils.java 30 Aug 2012 16:24:42 -0000 1.1 @@ -0,0 +1,331 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang; + +import java.util.Random; +/** + *

Operations for random Strings.

+ * + * @author GenerationJava Core library + * @author Henri Yandell + * @author Steven Caswell + * @author Stephen Colebourne + * @author Gary Gregory + * @author Phil Steitz + * @since 1.0 + * @version $Id: RandomStringUtils.java,v 1.1 2012/08/30 16:24:42 marcin Exp $ + */ +public class RandomStringUtils { + + /** + *

Random object used by random method. This has to be not local + * to the random method so as to not return the same value in the + * same millisecond.

+ */ + private static final Random RANDOM = new Random(); + + /** + *

RandomStringUtils instances should NOT be constructed in + * standard programming. Instead, the class should be used as + * RandomStringUtils.random(5);.

+ * + *

This constructor is public to permit tools that require a JavaBean instance + * to operate.

+ */ + public RandomStringUtils() { + } + + // Random + //----------------------------------------------------------------------- + /** + *

Creates a random string whose length is the number of characters + * specified.

+ * + *

Characters will be chosen from the set of all characters.

+ * + * @param count the length of random string to create + * @return the random string + */ + public static String random(int count) { + return random(count, false, false); + } + + /** + *

Creates a random string whose length is the number of characters + * specified.

+ * + *

Characters will be chosen from the set of characters whose + * ASCII value is between 32 and 126 (inclusive).

+ * + * @param count the length of random string to create + * @return the random string + */ + public static String randomAscii(int count) { + return random(count, 32, 127, false, false); + } + + /** + *

Creates a random string whose length is the number of characters + * specified.

+ * + *

Characters will be chosen from the set of alphabetic + * characters.

+ * + * @param count the length of random string to create + * @return the random string + */ + public static String randomAlphabetic(int count) { + return random(count, true, false); + } + + /** + *

Creates a random string whose length is the number of characters + * specified.

+ * + *

Characters will be chosen from the set of alpha-numeric + * characters.

+ * + * @param count the length of random string to create + * @return the random string + */ + public static String randomAlphanumeric(int count) { + return random(count, true, true); + } + + /** + *

Creates a random string whose length is the number of characters + * specified.

+ * + *

Characters will be chosen from the set of numeric + * characters.

+ * + * @param count the length of random string to create + * @return the random string + */ + public static String randomNumeric(int count) { + return random(count, false, true); + } + + /** + *

Creates a random string whose length is the number of characters + * specified.

+ * + *

Characters will be chosen from the set of alpha-numeric + * characters as indicated by the arguments.

+ * + * @param count the length of random string to create + * @param letters if true, generated string will include + * alphabetic characters + * @param numbers if true, generatd string will include + * numeric characters + * @return the random string + */ + public static String random(int count, boolean letters, boolean numbers) { + return random(count, 0, 0, letters, numbers); + } + + /** + *

Creates a random string whose length is the number of characters + * specified.

+ * + *

Characters will be chosen from the set of alpha-numeric + * characters as indicated by the arguments.

+ * + * @param count the length of random string to create + * @param start the position in set of chars to start at + * @param end the position in set of chars to end before + * @param letters if true, generated string will include + * alphabetic characters + * @param numbers if true, generated string will include + * numeric characters + * @return the random string + */ + public static String random(int count, int start, int end, boolean letters, boolean numbers) { + return random(count, start, end, letters, numbers, null, RANDOM); + } + + /** + *

Creates a random string based on a variety of options, using + * default source of randomness.

+ * + *

This method has exactly the same semantics as + * {@link #random(int,int,int,boolean,boolean,char[],Random)}, but + * instead of using an externally supplied source of randomness, it uses + * the internal static {@link Random} instance.

+ * + * @param count the length of random string to create + * @param start the position in set of chars to start at + * @param end the position in set of chars to end before + * @param letters only allow letters? + * @param numbers only allow numbers? + * @param chars the set of chars to choose randoms from. + * If null, then it will use the set of all chars. + * @return the random string + * @throws ArrayIndexOutOfBoundsException if there are not + * (end - start) + 1 characters in the set array. + */ + public static String random(int count, int start, int end, boolean letters, boolean numbers, char[] chars) { + return random(count, start, end, letters, numbers, chars, RANDOM); + } + + /** + *

Creates a random string based on a variety of options, using + * supplied source of randomness.

+ * + *

If start and end are both 0, start and end are set + * to ' ' and 'z', the ASCII printable + * characters, will be used, unless letters and numbers are both + * false, in which case, start and end are set to + * 0 and Integer.MAX_VALUE. + * + *

If set is not null, characters between start and + * end are chosen.

+ * + *

This method accepts a user-supplied {@link Random} + * instance to use as a source of randomness. By seeding a single + * {@link Random} instance with a fixed seed and using it for each call, + * the same random sequence of strings can be generated repeatedly + * and predictably.

+ * + * @param count the length of random string to create + * @param start the position in set of chars to start at + * @param end the position in set of chars to end before + * @param letters only allow letters? + * @param numbers only allow numbers? + * @param chars the set of chars to choose randoms from. + * If null, then it will use the set of all chars. + * @param random a source of randomness. + * @return the random string + * @throws ArrayIndexOutOfBoundsException if there are not + * (end - start) + 1 characters in the set array. + * @throws IllegalArgumentException if count < 0. + * @since 2.0 + */ + public static String random(int count, int start, int end, boolean letters, boolean numbers, char[] chars, Random random) { + if (count == 0) { + return ""; + } else if (count < 0) { + throw new IllegalArgumentException("Requested random string length " + count + " is less than 0."); + } + if ((start == 0) && (end == 0)) { + end = 'z' + 1; + start = ' '; + if (!letters && !numbers) { + start = 0; + end = Integer.MAX_VALUE; + } + } + + StringBuffer buffer = new StringBuffer(); + int gap = end - start; + + while (count-- != 0) { + char ch; + if (chars == null) { + ch = (char) (random.nextInt(gap) + start); + } else { + ch = chars[random.nextInt(gap) + start]; + } + if ((letters && numbers && Character.isLetterOrDigit(ch)) + || (letters && Character.isLetter(ch)) + || (numbers && Character.isDigit(ch)) + || (!letters && !numbers)) { + buffer.append(ch); + } else { + count++; + } + } + return buffer.toString(); + } + + /** + *

Creates a random string whose length is the number of characters + * specified.

+ * + *

Characters will be chosen from the set of characters + * specified.

+ * + * @param count the length of random string to create + * @param chars the String containing the set of characters to use, + * may be null + * @return the random string + * @throws IllegalArgumentException if count < 0. + */ + public static String random(int count, String chars) { + if (chars == null) { + return random(count, 0, 0, false, false, null, RANDOM); + } + return random(count, chars.toCharArray()); + } + + /** + *

Creates a random string whose length is the number of characters + * specified.

+ * + *

Characters will be chosen from the set of characters specified.

+ * + * @param count the length of random string to create + * @param chars the character array containing the set of characters to use, + * may be null + * @return the random string + * @throws IllegalArgumentException if count < 0. + */ + public static String random(int count, char[] chars) { + if (chars == null) { + return random(count, 0, 0, false, false, null, RANDOM); + } + return random(count, 0, chars.length, false, false, chars, RANDOM); + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/SerializationException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/SerializationException.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/SerializationException.java 30 Aug 2012 16:24:42 -0000 1.1 @@ -0,0 +1,110 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang; + +import org.apache.commons.lang.exception.NestableRuntimeException; + +/** + *

Exception thrown when the Serialization process fails.

+ * + *

The original error is wrapped within this one.

+ * + * @author Stephen Colebourne + * @since 1.0 + * @version $Id: SerializationException.java,v 1.1 2012/08/30 16:24:42 marcin Exp $ + */ +public class SerializationException extends NestableRuntimeException { + + /** + *

Constructs a new SerializationException without specified + * detail message.

+ */ + public SerializationException() { + super(); + } + + /** + *

Constructs a new SerializationException with specified + * detail message.

+ * + * @param msg The error message. + */ + public SerializationException(String msg) { + super(msg); + } + + /** + *

Constructs a new SerializationException with specified + * nested Throwable.

+ * + * @param cause The Exception or Error + * that caused this exception to be thrown. + */ + public SerializationException(Throwable cause) { + super(cause); + } + + /** + *

Constructs a new SerializationException with specified + * detail message and nested Throwable.

+ * + * @param msg The error message. + * @param cause The Exception or Error + * that caused this exception to be thrown. + */ + public SerializationException(String msg, Throwable cause) { + super(msg, cause); + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/SerializationUtils.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/SerializationUtils.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/SerializationUtils.java 30 Aug 2012 16:24:42 -0000 1.1 @@ -0,0 +1,232 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.io.Serializable; + +/** + *

Assists with the serialization process and performs additional functionality based + * on serialization.

+ *

+ *

    + *
  • Deep clone using serialization + *
  • Serialize managing finally and IOException + *
  • Deserialize managing finally and IOException + *
+ * + *

This class throws exceptions for invalid null inputs. + * Each method documents its behaviour in more detail.

+ * + * @author Nissim Karpenstein + * @author Janek Bogucki + * @author Daniel Rall + * @author Stephen Colebourne + * @author Jeff Varszegi + * @author Gary Gregory + * @since 1.0 + * @version $Id: SerializationUtils.java,v 1.1 2012/08/30 16:24:42 marcin Exp $ + */ +public class SerializationUtils { + + /** + *

SerializationUtils instances should NOT be constructed in standard programming. + * Instead, the class should be used as SerializationUtils.clone(object).

+ * + *

This constructor is public to permit tools that require a JavaBean instance + * to operate.

+ * @since 2.0 + */ + public SerializationUtils() { + super(); + } + + // Clone + //----------------------------------------------------------------------- + /** + *

Deep clone an Object using serialization.

+ * + *

This is many times slower than writing clone methods by hand + * on all objects in your object graph. However, for complex object + * graphs, or for those that don't support deep cloning this can + * be a simple alternative implementation. Of course all the objects + * must be Serializable.

+ * + * @param object the Serializable object to clone + * @return the cloned object + * @throws SerializationException (runtime) if the serialization fails + */ + public static Object clone(Serializable object) { + return deserialize(serialize(object)); + } + + // Serialize + //----------------------------------------------------------------------- + /** + *

Serializes an Object to the specified stream.

+ * + *

The stream will be closed once the object is written. + * This avoids the need for a finally clause, and maybe also exception + * handling, in the application code.

+ * + *

The stream passed in is not buffered internally within this method. + * This is the responsibility of your application if desired.

+ * + * @param obj the object to serialize to bytes, may be null + * @param outputStream the stream to write to, must not be null + * @throws IllegalArgumentException if outputStream is null + * @throws SerializationException (runtime) if the serialization fails + */ + public static void serialize(Serializable obj, OutputStream outputStream) { + if (outputStream == null) { + throw new IllegalArgumentException("The OutputStream must not be null"); + } + ObjectOutputStream out = null; + try { + // stream closed in the finally + out = new ObjectOutputStream(outputStream); + out.writeObject(obj); + + } catch (IOException ex) { + throw new SerializationException(ex); + } finally { + try { + if (out != null) { + out.close(); + } + } catch (IOException ex) { + // ignore; + } + } + } + + /** + *

Serializes an Object to a byte array for + * storage/serialization.

+ * + * @param obj the object to serialize to bytes + * @return a byte[] with the converted Serializable + * @throws SerializationException (runtime) if the serialization fails + */ + public static byte[] serialize(Serializable obj) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(512); + serialize(obj, baos); + return baos.toByteArray(); + } + + // Deserialize + //----------------------------------------------------------------------- + /** + *

Deserializes an Object from the specified stream.

+ * + *

The stream will be closed once the object is written. This + * avoids the need for a finally clause, and maybe also exception + * handling, in the application code.

+ * + *

The stream passed in is not buffered internally within this method. + * This is the responsibility of your application if desired.

+ * + * @param inputStream the serialized object input stream, must not be null + * @return the deserialized object + * @throws IllegalArgumentException if inputStream is null + * @throws SerializationException (runtime) if the serialization fails + */ + public static Object deserialize(InputStream inputStream) { + if (inputStream == null) { + throw new IllegalArgumentException("The InputStream must not be null"); + } + ObjectInputStream in = null; + try { + // stream closed in the finally + in = new ObjectInputStream(inputStream); + return in.readObject(); + + } catch (ClassNotFoundException ex) { + throw new SerializationException(ex); + } catch (IOException ex) { + throw new SerializationException(ex); + } finally { + try { + if (in != null) { + in.close(); + } + } catch (IOException ex) { + // ignore + } + } + } + + /** + *

Deserializes a single Object from an array of bytes.

+ * + * @param objectData the serialized object, must not be null + * @return the deserialized object + * @throws IllegalArgumentException if objectData is null + * @throws SerializationException (runtime) if the serialization fails + */ + public static Object deserialize(byte[] objectData) { + if (objectData == null) { + throw new IllegalArgumentException("The byte[] must not be null"); + } + ByteArrayInputStream bais = new ByteArrayInputStream(objectData); + return deserialize(bais); + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/StringEscapeUtils.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/StringEscapeUtils.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/StringEscapeUtils.java 30 Aug 2012 16:24:42 -0000 1.1 @@ -0,0 +1,552 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang; + +import java.io.IOException; +import java.io.Writer; + +import org.apache.commons.lang.exception.NestableRuntimeException; + +/** + *

Escapes and unescapes Strings for + * Java, Java Script, HTML, XML, and SQL.

+ * + * @author Apache Jakarta Turbine + * @author GenerationJavaCore library + * @author Purple Technology + * @author Henri Yandell + * @author Alexander Day Chaffee + * @author Antony Riley + * @author Helge Tesgaard + * @author Sean Brown + * @author Gary Gregory + * @author Phil Steitz + * @author Pete Gieser + * @since 2.0 + * @version $Id: StringEscapeUtils.java,v 1.1 2012/08/30 16:24:42 marcin Exp $ + */ +public class StringEscapeUtils { + + /** + *

StringEscapeUtils instances should NOT be constructed in + * standard programming.

+ * + *

Instead, the class should be used as: + *

StringEscapeUtils.escapeJava("foo");

+ * + *

This constructor is public to permit tools that require a JavaBean + * instance to operate.

+ */ + public StringEscapeUtils() { + } + + // Java and JavaScript + //-------------------------------------------------------------------------- + /** + *

Escapes the characters in a String using Java String rules.

+ * + *

Deals correctly with quotes and control-chars (tab, backslash, cr, ff, etc.)

+ * + *

So a tab becomes the characters '\\' and + * 't'.

+ * + *

The only difference between Java strings and JavaScript strings + * is that in JavaScript, a single quote must be escaped.

+ * + *

Example: + *

+     * input string: He didn't say, "Stop!"
+     * output string: He didn't say, \"Stop!\"
+     * 
+ *

+ * + * @param str String to escape values in, may be null + * @return String with escaped values, null if null string input + */ + public static String escapeJava(String str) { + return escapeJavaStyleString(str, false); + } + + /** + *

Escapes the characters in a String using Java String rules to + * a Writer.

+ * + *

A null string input has no effect.

+ * + * @see #escapeJava(java.lang.String) + * @param out Writer to write escaped string into + * @param str String to escape values in, may be null + * @throws IllegalArgumentException if the Writer is null + * @throws IOException if error occurs on undelying Writer + */ + public static void escapeJava(Writer out, String str) throws IOException { + escapeJavaStyleString(out, str, false); + } + + /** + *

Escapes the characters in a String using JavaScript String rules.

+ *

Escapes any values it finds into their JavaScript String form. + * Deals correctly with quotes and control-chars (tab, backslash, cr, ff, etc.)

+ * + *

So a tab becomes the characters '\\' and + * 't'.

+ * + *

The only difference between Java strings and JavaScript strings + * is that in JavaScript, a single quote must be escaped.

+ * + *

Example: + *

+     * input string: He didn't say, "Stop!"
+     * output string: He didn\'t say, \"Stop!\"
+     * 
+ *

+ * + * @param str String to escape values in, may be null + * @return String with escaped values, null if null string input + */ + public static String escapeJavaScript(String str) { + return escapeJavaStyleString(str, true); + } + + /** + *

Escapes the characters in a String using JavaScript String rules + * to a Writer.

+ * + *

A null string input has no effect.

+ * + * @see #escapeJavaScript(java.lang.String) + * @param out Writer to write escaped string into + * @param str String to escape values in, may be null + * @throws IllegalArgumentException if the Writer is null + * @throws IOException if error occurs on undelying Writer + **/ + public static void escapeJavaScript(Writer out, String str) throws IOException { + escapeJavaStyleString(out, str, true); + } + + private static String escapeJavaStyleString(String str, boolean escapeSingleQuotes) { + if (str == null) { + return null; + } + try { + StringPrintWriter writer = new StringPrintWriter(str.length() * 2); + escapeJavaStyleString(writer, str, escapeSingleQuotes); + return writer.getString(); + } catch (IOException ioe) { + // this should never ever happen while writing to a StringWriter + ioe.printStackTrace(); + return null; + } + } + + private static void escapeJavaStyleString(Writer out, String str, boolean escapeSingleQuote) throws IOException { + if (out == null) { + throw new IllegalArgumentException("The Writer must not be null"); + } + if (str == null) { + return; + } + int sz; + sz = str.length(); + for (int i = 0; i < sz; i++) { + char ch = str.charAt(i); + + // handle unicode + if (ch > 0xfff) { + out.write("\\u" + hex(ch)); + } else if (ch > 0xff) { + out.write("\\u0" + hex(ch)); + } else if (ch > 0x7f) { + out.write("\\u00" + hex(ch)); + } else if (ch < 32) { + switch (ch) { + case '\b': + out.write('\\'); + out.write('b'); + break; + case '\n': + out.write('\\'); + out.write('n'); + break; + case '\t': + out.write('\\'); + out.write('t'); + break; + case '\f': + out.write('\\'); + out.write('f'); + break; + case '\r': + out.write('\\'); + out.write('r'); + break; + default : + if (ch > 0xf) { + out.write("\\u00" + hex(ch)); + } else { + out.write("\\u000" + hex(ch)); + } + break; + } + } else { + switch (ch) { + case '\'': + if (escapeSingleQuote) out.write('\\'); + out.write('\''); + break; + case '"': + out.write('\\'); + out.write('"'); + break; + case '\\': + out.write('\\'); + out.write('\\'); + break; + default : + out.write(ch); + break; + } + } + } + } + + /** + *

Returns an upper case hexadecimal String for the given + * character.

+ * + * @param ch The character to convert. + * @return An upper case hexadecimal String + */ + private static String hex(char ch) { + return Integer.toHexString(ch).toUpperCase(); + } + + /** + *

Unescapes any Java literals found in the String. + * For example, it will turn a sequence of '\' and + * 'n' into a newline character, unless the '\' + * is preceded by another '\'.

+ * + * @param str the String to unescape, may be null + * @return a new unescaped String, null if null string input + */ + public static String unescapeJava(String str) { + if (str == null) { + return null; + } + try { + StringPrintWriter writer = new StringPrintWriter(str.length()); + unescapeJava(writer, str); + return writer.getString(); + } catch (IOException ioe) { + // this should never ever happen while writing to a StringWriter + ioe.printStackTrace(); + return null; + } + } + + /** + *

Unescapes any Java literals found in the String to a + * Writer.

+ * + *

For example, it will turn a sequence of '\' and + * 'n' into a newline character, unless the '\' + * is preceded by another '\'.

+ * + *

A null string input has no effect.

+ * + * @param out the Writer used to output unescaped characters + * @param str the String to unescape, may be null + * @throws IllegalArgumentException if the Writer is null + * @throws IOException if error occurs on undelying Writer + */ + public static void unescapeJava(Writer out, String str) throws IOException { + if (out == null) { + throw new IllegalArgumentException("The Writer must not be null"); + } + if (str == null) { + return; + } + int sz = str.length(); + StringBuffer unicode = new StringBuffer(4); + boolean hadSlash = false; + boolean inUnicode = false; + for (int i = 0; i < sz; i++) { + char ch = str.charAt(i); + if (inUnicode) { + // if in unicode, then we're reading unicode + // values in somehow + unicode.append(ch); + if (unicode.length() == 4) { + // unicode now contains the four hex digits + // which represents our unicode chacater + try { + int value = Integer.parseInt(unicode.toString(), 16); + out.write((char) value); + unicode.setLength(0); + inUnicode = false; + hadSlash = false; + } catch (NumberFormatException nfe) { + throw new NestableRuntimeException("Unable to parse unicode value: " + unicode, nfe); + } + } + continue; + } + if (hadSlash) { + // handle an escaped value + hadSlash = false; + switch (ch) { + case '\\': + out.write('\\'); + break; + case '\'': + out.write('\''); + break; + case '\"': + out.write('"'); + break; + case 'r': + out.write('\r'); + break; + case 'f': + out.write('\f'); + break; + case 't': + out.write('\t'); + break; + case 'n': + out.write('\n'); + break; + case 'b': + out.write('\b'); + break; + case 'u': + { + // uh-oh, we're in unicode country.... + inUnicode = true; + break; + } + default : + out.write(ch); + break; + } + continue; + } else if (ch == '\\') { + hadSlash = true; + continue; + } + out.write(ch); + } + if (hadSlash) { + // then we're in the weird case of a \ at the end of the + // string, let's output it anyway. + out.write('\\'); + } + } + + /** + *

Unescapes any JavaScript literals found in the String.

+ * + *

For example, it will turn a sequence of '\' and 'n' + * into a newline character, unless the '\' is preceded by another + * '\'.

+ * + * @see #unescapeJava(String) + * @param str the String to unescape, may be null + * @return A new unescaped String, null if null string input + */ + public static String unescapeJavaScript(String str) { + return unescapeJava(str); + } + + /** + *

Unescapes any JavaScript literals found in the String to a + * Writer.

+ * + *

For example, it will turn a sequence of '\' and 'n' + * into a newline character, unless the '\' is preceded by another + * '\'.

+ * + *

A null string input has no effect.

+ * + * @see #unescapeJava(Writer,String) + * @param out the Writer used to output unescaped characters + * @param str the String to unescape, may be null + * @throws IllegalArgumentException if the Writer is null + * @throws IOException if error occurs on undelying Writer + */ + public static void unescapeJavaScript(Writer out, String str) throws IOException { + unescapeJava(out, str); + } + + // HTML and XML + //-------------------------------------------------------------------------- + /** + *

Escapes the characters in a String using HTML entities.

+ * + *

+ * For example: "bread" & "butter" => &quot;bread&quot; &amp; &quot;butter&quot;. + *

+ * + *

Supports all known HTML 4.0 entities, including funky accents.

+ * + * @param str the String to escape, may be null + * @return a new escaped String, null if null string input + * + * @see #unescapeHtml(String) + * @see
ISO Entities + * @see
HTML 3.2 Character Entities for ISO Latin-1 + * @see
HTML 4.0 Character entity references + * @see
HTML 4.01 Character References + * @see
HTML 4.01 Code positions + **/ + public static String escapeHtml(String str) { + if (str == null) { + return null; + } + //todo: add a version that takes a Writer + //todo: rewrite underlying method to use a Writer instead of a StringBuffer + return Entities.HTML40.escape(str); + } + + /** + *

Unescapes a string containing entity escapes to a string + * containing the actual Unicode characters corresponding to the + * escapes. Supports HTML 4.0 entities.

+ * + *

For example, the string "&lt;Fran&ccedil;ais&gt;" + * will become "<Français>"

+ * + *

If an entity is unrecognized, it is left alone, and inserted + * verbatim into the result string. e.g. "&gt;&zzzz;x" will + * become ">&zzzz;x".

+ * + * @param str the String to unescape, may be null + * @return a new unescaped String, null if null string input + * @see #escapeHtml(String) + **/ + public static String unescapeHtml(String str) { + if (str == null) { + return null; + } + return Entities.HTML40.unescape(str); + } + + /** + *

Escapes the characters in a String using XML entities.

+ * + *

For example: "bread" & "butter" => + * &quot;bread&quot; &amp; &quot;butter&quot;. + *

+ * + *

Supports only the four basic XML entities (gt, lt, quot, amp). + * Does not support DTDs or external entities.

+ * + * @param str the String to escape, may be null + * @return a new escaped String, null if null string input + * @see #unescapeXml(java.lang.String) + **/ + public static String escapeXml(String str) { + if (str == null) { + return null; + } + return Entities.XML.escape(str); + } + + /** + *

Unescapes a string containing XML entity escapes to a string + * containing the actual Unicode characters corresponding to the + * escapes.

+ * + *

Supports only the four basic XML entities (gt, lt, quot, amp). + * Does not support DTDs or external entities.

+ * + * @param str the String to unescape, may be null + * @return a new unescaped String, null if null string input + * @see #escapeXml(String) + **/ + public static String unescapeXml(String str) { + if (str == null) { + return null; + } + return Entities.XML.unescape(str); + } + + /** + *

Escapes the characters in a String to be suitable to pass to + * an SQL query.

+ * + *

For example, + *

statement.executeQuery("SELECT * FROM MOVIES WHERE TITLE='" + 
+     *   StringEscapeUtils.escapeSql("McHale's Navy") + 
+     *   "'");
+ *

+ * + *

At present, this method only turns single-quotes into doubled single-quotes + * ("McHale's Navy" => "McHale''s Navy"). It does not + * handle the cases of percent (%) or underscore (_) for use in LIKE clauses.

+ * + * see http://www.jguru.com/faq/view.jsp?EID=8881 + * @param str the string to escape, may be null + * @return a new String, escaped for SQL, null if null string input + */ + public static String escapeSql(String str) { + if (str == null) { + return null; + } + return StringUtils.replace(str, "'", "''"); + } + +} + Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/StringPrintWriter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/Attic/StringPrintWriter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/StringPrintWriter.java 30 Aug 2012 16:24:42 -0000 1.1 @@ -0,0 +1,97 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang; + +import java.io.PrintWriter; +import java.io.StringWriter; + +/** + *

A PrintWriter that maintains a String as its backing store.

+ * + *

Usage: + *

+ * StringPrintWriter out = new StringPrintWriter();
+ * printTo(out);
+ * System.out.println( out.getString() );
+ * 
+ *

+ * + * @author Alex Chaffee + * @author Scott Stanchfield + * @since 2.0 + */ +class StringPrintWriter extends PrintWriter { + + public StringPrintWriter() { + super(new StringWriter()); + } + + public StringPrintWriter(int initialSize) { + super(new StringWriter(initialSize)); + } + + /** + *

Since toString() returns information *about* this object, we + * want a separate method to extract just the contents of the + * internal buffer as a String.

+ * + * @return the contents of the internal string buffer + */ + public String getString() { + flush(); + return ((StringWriter) out).toString(); + } + +} + Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/StringUtils.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/StringUtils.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/StringUtils.java 30 Aug 2012 16:24:42 -0000 1.1 @@ -0,0 +1,4304 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + *

Operations on {@link java.lang.String} that are + * null safe.

+ * + *
    + *
  • IsEmpty/IsBlank + * - checks if a String contains text
  • + *
  • Trim/Strip + * - removes leading and trailing whitespace
  • + *
  • Equals + * - compares two strings null-safe
  • + *
  • IndexOf/LastIndexOf/Contains + * - null-safe index-of checks + *
  • IndexOfAny/LastIndexOfAny/IndexOfAnyBut/LastIndexOfAnyBut + * - index-of any of a set of Strings
  • + *
  • ContainsOnly/ContainsNone + * - does String contains only/none of these characters
  • + *
  • Substring/Left/Right/Mid + * - null-safe substring extractions
  • + *
  • SubstringBefore/SubstringAfter/SubstringBetween + * - substring extraction relative to other strings
  • + *
  • Split/Join + * - splits a String into an array of substrings and vice versa
  • + *
  • Replace/Delete/Overlay + * - Searches a String and replaces one String with another
  • + *
  • Chomp/Chop + * - removes the last part of a String
  • + *
  • LeftPad/RightPad/Center/Repeat + * - pads a String
  • + *
  • UpperCase/LowerCase/SwapCase/Capitalize/Uncapitalize + * - changes the case of a String
  • + *
  • CountMatches + * - counts the number of occurrances of one String in another
  • + *
  • IsAlpha/IsNumeric/IsWhitespace + * - checks the characters in a String
  • + *
  • DefaultString + * - protects against a null input String
  • + *
  • Reverse/ReverseDelimited + * - reverses a String
  • + *
  • Abbreviate + * - abbreviates a string using ellipsis
  • + *
  • Difference + * - compares two Strings and reports on their differences
  • + *
  • LevensteinDistance + * - the number of changes needed to change one String into another
  • + *
+ * + *

The StringUtils class defines certain words related to + * String handling.

+ * + *
    + *
  • null - null
  • + *
  • empty - a zero-length string ("")
  • + *
  • space - the space character (' ', char 32)
  • + *
  • whitespace - the characters defined by {@link Character#isWhitespace(char)}
  • + *
  • trim - the characters <= 32 as in {@link String#trim()}
  • + *
+ * + *

StringUtils handles null input Strings quietly. + * That is to say that a null input will return null. + * Where a boolean or int is being returned + * details vary by method.

+ * + *

A side effect of the null handling is that a + * NullPointerException should be considered a bug in + * StringUtils (except for deprecated methods).

+ * + *

Methods in this class give sample code to explain their operation. + * The symbol * is used to indicate any input including null.

+ * + * @see java.lang.String + * @author Apache Jakarta Turbine + * @author GenerationJavaCore + * @author Jon S. Stevens + * @author Daniel Rall + * @author Greg Coladonato + * @author Henri Yandell + * @author Ed Korthof + * @author Rand McNeely + * @author Stephen Colebourne + * @author Fredrik Westermarck + * @author Holger Krauth + * @author Alexander Day Chaffee + * @author Henning P. Schmiedehausen + * @author Arun Mammen Thomas + * @author Gary Gregory + * @author Phil Steitz + * @since 1.0 + * @version $Id: StringUtils.java,v 1.1 2012/08/30 16:24:42 marcin Exp $ + */ +public class StringUtils { + // Performance testing notes (JDK 1.4, Jul03, scolebourne) + // Whitespace: + // Character.isWhitespace() is faster than WHITESPACE.indexOf() + // where WHITESPACE is a string of all whitespace characters + // + // Character access: + // String.charAt(n) versus toCharArray(), then array[n] + // String.charAt(n) is about 15% worse for a 10K string + // They are about equal for a length 50 string + // String.charAt(n) is about 4 times better for a length 3 string + // String.charAt(n) is best bet overall + // + // Append: + // String.concat about twice as fast as StringBuffer.append + // (not sure who tested this) + + /** + * The empty String "". + * @since 2.0 + */ + public static final String EMPTY = ""; + + /** + *

The maximum size to which the padding constant(s) can expand.

+ */ + private static final int PAD_LIMIT = 8192; + + /** + *

An array of Strings used for padding.

+ * + *

Used for efficient space padding. The length of each String expands as needed.

+ */ + private static final String[] PADDING = new String[Character.MAX_VALUE]; + + static { + // space padding is most common, start with 64 chars + PADDING[32] = " "; + } + + /** + *

StringUtils instances should NOT be constructed in + * standard programming. Instead, the class should be used as + * StringUtils.trim(" foo ");.

+ * + *

This constructor is public to permit tools that require a JavaBean + * instance to operate.

+ */ + public StringUtils() { + } + + // Empty checks + //----------------------------------------------------------------------- + /** + *

Checks if a String is empty ("") or null.

+ * + *
+     * StringUtils.isEmpty(null)      = true
+     * StringUtils.isEmpty("")        = true
+     * StringUtils.isEmpty(" ")       = false
+     * StringUtils.isEmpty("bob")     = false
+     * StringUtils.isEmpty("  bob  ") = false
+     * 
+ * + *

NOTE: This method changed in Lang version 2.0. + * It no longer trims the String. + * That functionality is available in isBlank().

+ * + * @param str the String to check, may be null + * @return true if the String is empty or null + */ + public static boolean isEmpty(String str) { + return (str == null || str.length() == 0); + } + + /** + *

Checks if a String is not empty ("") and not null.

+ * + *
+     * StringUtils.isNotEmpty(null)      = false
+     * StringUtils.isNotEmpty("")        = false
+     * StringUtils.isNotEmpty(" ")       = true
+     * StringUtils.isNotEmpty("bob")     = true
+     * StringUtils.isNotEmpty("  bob  ") = true
+     * 
+ * + * @param str the String to check, may be null + * @return true if the String is not empty and not null + */ + public static boolean isNotEmpty(String str) { + return (str != null && str.length() > 0); + } + + /** + *

Checks if a String is whitespace, empty ("") or null.

+ * + *
+     * StringUtils.isBlank(null)      = true
+     * StringUtils.isBlank("")        = true
+     * StringUtils.isBlank(" ")       = true
+     * StringUtils.isBlank("bob")     = false
+     * StringUtils.isBlank("  bob  ") = false
+     * 
+ * + * @param str the String to check, may be null + * @return true if the String is null, empty or whitespace + * @since 2.0 + */ + public static boolean isBlank(String str) { + int strLen; + if (str == null || (strLen = str.length()) == 0) { + return true; + } + for (int i = 0; i < strLen; i++) { + if ((Character.isWhitespace(str.charAt(i)) == false) ) { + return false; + } + } + return true; + } + + /** + *

Checks if a String is not empty (""), not null and not whitespace only.

+ * + *
+     * StringUtils.isNotBlank(null)      = false
+     * StringUtils.isNotBlank("")        = false
+     * StringUtils.isNotBlank(" ")       = false
+     * StringUtils.isNotBlank("bob")     = true
+     * StringUtils.isNotBlank("  bob  ") = true
+     * 
+ * + * @param str the String to check, may be null + * @return true if the String is + * not empty and not null and not whitespace + * @since 2.0 + */ + public static boolean isNotBlank(String str) { + int strLen; + if (str == null || (strLen = str.length()) == 0) { + return false; + } + for (int i = 0; i < strLen; i++) { + if ((Character.isWhitespace(str.charAt(i)) == false) ) { + return true; + } + } + return false; + } + + // Trim + //----------------------------------------------------------------------- + /** + *

Removes control characters (char <= 32) from both + * ends of this String, handling null by returning + * an empty String ("").

+ * + *
+     * StringUtils.clean(null)          = ""
+     * StringUtils.clean("")            = ""
+     * StringUtils.clean("abc")         = "abc"
+     * StringUtils.clean("    abc    ") = "abc"
+     * StringUtils.clean("     ")       = ""
+     * 
+ * + * @see java.lang.String#trim() + * @param str the String to clean, may be null + * @return the trimmed text, never null + * @deprecated Use the clearer named {@link #trimToEmpty(String)}. + * Method will be removed in Commons Lang 3.0. + */ + public static String clean(String str) { + return (str == null ? EMPTY : str.trim()); + } + + /** + *

Removes control characters (char <= 32) from both + * ends of this String, handling null by returning + * null.

+ * + *

The String is trimmed using {@link String#trim()}. + * Trim removes start and end characters <= 32. + * To strip whitespace use {@link #strip(String)}.

+ * + *

To trim your choice of characters, use the + * {@link #strip(String, String)} methods.

+ * + *
+     * StringUtils.trim(null)          = null
+     * StringUtils.trim("")            = ""
+     * StringUtils.trim("     ")       = ""
+     * StringUtils.trim("abc")         = "abc"
+     * StringUtils.trim("    abc    ") = "abc"
+     * 
+ * + * @param str the String to be trimmed, may be null + * @return the trimmed string, null if null String input + */ + public static String trim(String str) { + return (str == null ? null : str.trim()); + } + + /** + *

Removes control characters (char <= 32) from both + * ends of this String returning null if the String is + * empty ("") after the trim or if it is null. + * + *

The String is trimmed using {@link String#trim()}. + * Trim removes start and end characters <= 32. + * To strip whitespace use {@link #stripToNull(String)}.

+ * + *
+     * StringUtils.trimToNull(null)          = null
+     * StringUtils.trimToNull("")            = null
+     * StringUtils.trimToNull("     ")       = null
+     * StringUtils.trimToNull("abc")         = "abc"
+     * StringUtils.trimToNull("    abc    ") = "abc"
+     * 
+ * + * @param str the String to be trimmed, may be null + * @return the trimmed String, + * null if only chars <= 32, empty or null String input + * @since 2.0 + */ + public static String trimToNull(String str) { + String ts = trim(str); + return (ts == null || ts.length() == 0 ? null : ts); + } + + /** + *

Removes control characters (char <= 32) from both + * ends of this String returning an empty String ("") if the String + * is empty ("") after the trim or if it is null. + * + *

The String is trimmed using {@link String#trim()}. + * Trim removes start and end characters <= 32. + * To strip whitespace use {@link #stripToEmpty(String)}.

+ * + *
+     * StringUtils.trimToEmpty(null)          = ""
+     * StringUtils.trimToEmpty("")            = ""
+     * StringUtils.trimToEmpty("     ")       = ""
+     * StringUtils.trimToEmpty("abc")         = "abc"
+     * StringUtils.trimToEmpty("    abc    ") = "abc"
+     * 
+ * + * @param str the String to be trimmed, may be null + * @return the trimmed String, or an empty String if null input + * @since 2.0 + */ + public static String trimToEmpty(String str) { + return (str == null ? EMPTY : str.trim()); + } + + // Stripping + //----------------------------------------------------------------------- + /** + *

Strips whitespace from the start and end of a String.

+ * + *

This is similar to {@link #trim(String)} but removes whitespace. + * Whitespace is defined by {@link Character#isWhitespace(char)}.

+ * + *

A null input String returns null.

+ * + *
+     * StringUtils.strip(null)     = null
+     * StringUtils.strip("")       = ""
+     * StringUtils.strip("   ")    = ""
+     * StringUtils.strip("abc")    = "abc"
+     * StringUtils.strip("  abc")  = "abc"
+     * StringUtils.strip("abc  ")  = "abc"
+     * StringUtils.strip(" abc ")  = "abc"
+     * StringUtils.strip(" ab c ") = "ab c"
+     * 
+ * + * @param str the String to remove whitespace from, may be null + * @return the stripped String, null if null String input + */ + public static String strip(String str) { + return strip(str, null); + } + + /** + *

Strips whitespace from the start and end of a String returning + * null if the String is empty ("") after the strip.

+ * + *

This is similar to {@link #trimToNull(String)} but removes whitespace. + * Whitespace is defined by {@link Character#isWhitespace(char)}.

+ * + *
+     * StringUtils.strip(null)     = null
+     * StringUtils.strip("")       = null
+     * StringUtils.strip("   ")    = null
+     * StringUtils.strip("abc")    = "abc"
+     * StringUtils.strip("  abc")  = "abc"
+     * StringUtils.strip("abc  ")  = "abc"
+     * StringUtils.strip(" abc ")  = "abc"
+     * StringUtils.strip(" ab c ") = "ab c"
+     * 
+ * + * @param str the String to be stripped, may be null + * @return the stripped String, + * null if whitespace, empty or null String input + * @since 2.0 + */ + public static String stripToNull(String str) { + if (str == null) { + return null; + } + str = strip(str, null); + return (str.length() == 0 ? null : str); + } + + /** + *

Strips whitespace from the start and end of a String returning + * an empty String if null input.

+ * + *

This is similar to {@link #trimToEmpty(String)} but removes whitespace. + * Whitespace is defined by {@link Character#isWhitespace(char)}.

+ * + *
+     * StringUtils.strip(null)     = ""
+     * StringUtils.strip("")       = ""
+     * StringUtils.strip("   ")    = ""
+     * StringUtils.strip("abc")    = "abc"
+     * StringUtils.strip("  abc")  = "abc"
+     * StringUtils.strip("abc  ")  = "abc"
+     * StringUtils.strip(" abc ")  = "abc"
+     * StringUtils.strip(" ab c ") = "ab c"
+     * 
+ * + * @param str the String to be stripped, may be null + * @return the trimmed String, or an empty String if null input + * @since 2.0 + */ + public static String stripToEmpty(String str) { + return (str == null ? EMPTY : strip(str, null)); + } + + /** + *

Strips any of a set of characters from the start and end of a String. + * This is similar to {@link String#trim()} but allows the characters + * to be stripped to be controlled.

+ * + *

A null input String returns null. + * An empty string ("") input returns the empty string.

+ * + *

If the stripChars String is null, whitespace is + * stripped as defined by {@link Character#isWhitespace(char)}. + * Alternatively use {@link #strip(String)}.

+ * + *
+     * StringUtils.strip(null, *)          = null
+     * StringUtils.strip("", *)            = ""
+     * StringUtils.strip("abc", null)      = "abc"
+     * StringUtils.strip("  abc", null)    = "abc"
+     * StringUtils.strip("abc  ", null)    = "abc"
+     * StringUtils.strip(" abc ", null)    = "abc"
+     * StringUtils.strip("  abcyx", "xyz") = "  abc"
+     * 
+ * + * @param str the String to remove characters from, may be null + * @param stripChars the characters to remove, null treated as whitespace + * @return the stripped String, null if null String input + */ + public static String strip(String str, String stripChars) { + if (str == null || str.length() == 0) { + return str; + } + str = stripStart(str, stripChars); + return stripEnd(str, stripChars); + } + + /** + *

Strips any of a set of characters from the start of a String.

+ * + *

A null input String returns null. + * An empty string ("") input returns the empty string.

+ * + *

If the stripChars String is null, whitespace is + * stripped as defined by {@link Character#isWhitespace(char)}.

+ * + *
+     * StringUtils.stripStart(null, *)          = null
+     * StringUtils.stripStart("", *)            = ""
+     * StringUtils.stripStart("abc", "")        = "abc"
+     * StringUtils.stripStart("abc", null)      = "abc"
+     * StringUtils.stripStart("  abc", null)    = "abc"
+     * StringUtils.stripStart("abc  ", null)    = "abc  "
+     * StringUtils.stripStart(" abc ", null)    = "abc "
+     * StringUtils.stripStart("yxabc  ", "xyz") = "abc  "
+     * 
+ * + * @param str the String to remove characters from, may be null + * @param stripChars the characters to remove, null treated as whitespace + * @return the stripped String, null if null String input + */ + public static String stripStart(String str, String stripChars) { + int strLen; + if (str == null || (strLen = str.length()) == 0) { + return str; + } + int start = 0; + if (stripChars == null) { + while ((start != strLen) && Character.isWhitespace(str.charAt(start))) { + start++; + } + } else if (stripChars.length() == 0) { + return str; + } else { + while ((start != strLen) && (stripChars.indexOf(str.charAt(start)) != -1)) { + start++; + } + } + return str.substring(start); + } + + /** + *

Strips any of a set of characters from the end of a String.

+ * + *

A null input String returns null. + * An empty string ("") input returns the empty string.

+ * + *

If the stripChars String is null, whitespace is + * stripped as defined by {@link Character#isWhitespace(char)}.

+ * + *
+     * StringUtils.stripEnd(null, *)          = null
+     * StringUtils.stripEnd("", *)            = ""
+     * StringUtils.stripEnd("abc", "")        = "abc"
+     * StringUtils.stripEnd("abc", null)      = "abc"
+     * StringUtils.stripEnd("  abc", null)    = "  abc"
+     * StringUtils.stripEnd("abc  ", null)    = "abc"
+     * StringUtils.stripEnd(" abc ", null)    = " abc"
+     * StringUtils.stripEnd("  abcyx", "xyz") = "  abc"
+     * 
+ * + * @param str the String to remove characters from, may be null + * @param stripChars the characters to remove, null treated as whitespace + * @return the stripped String, null if null String input + */ + public static String stripEnd(String str, String stripChars) { + int end; + if (str == null || (end = str.length()) == 0) { + return str; + } + + if (stripChars == null) { + while ((end != 0) && Character.isWhitespace(str.charAt(end - 1))) { + end--; + } + } else if (stripChars.length() == 0) { + return str; + } else { + while ((end != 0) && (stripChars.indexOf(str.charAt(end - 1)) != -1)) { + end--; + } + } + return str.substring(0, end); + } + + // StripAll + //----------------------------------------------------------------------- + /** + *

Strips whitespace from the start and end of every String in an array. + * Whitespace is defined by {@link Character#isWhitespace(char)}.

+ * + *

A new array is returned each time, except for length zero. + * A null array will return null. + * An empty array will return itself. + * A null array entry will be ignored.

+ * + *
+     * StringUtils.stripAll(null)             = null
+     * StringUtils.stripAll([])               = []
+     * StringUtils.stripAll(["abc", "  abc"]) = ["abc", "abc"]
+     * StringUtils.stripAll(["abc  ", null])  = ["abc", null]
+     * 
+ * + * @param strs the array to remove whitespace from, may be null + * @return the stripped Strings, null if null array input + */ + public static String[] stripAll(String[] strs) { + return stripAll(strs, null); + } + + /** + *

Strips any of a set of characters from the start and end of every + * String in an array.

+ * Whitespace is defined by {@link Character#isWhitespace(char)}.

+ * + *

A new array is returned each time, except for length zero. + * A null array will return null. + * An empty array will return itself. + * A null array entry will be ignored. + * A null stripChars will strip whitespace as defined by + * {@link Character#isWhitespace(char)}.

+ * + *
+     * StringUtils.stripAll(null, *)                = null
+     * StringUtils.stripAll([], *)                  = []
+     * StringUtils.stripAll(["abc", "  abc"], null) = ["abc", "abc"]
+     * StringUtils.stripAll(["abc  ", null], null)  = ["abc", null]
+     * StringUtils.stripAll(["abc  ", null], "yz")  = ["abc  ", null]
+     * StringUtils.stripAll(["yabcz", null], "yz")  = ["abc", null]
+     * 
+ * + * @param strs the array to remove characters from, may be null + * @param stripChars the characters to remove, null treated as whitespace + * @return the stripped Strings, null if null array input + */ + public static String[] stripAll(String[] strs, String stripChars) { + int strsLen; + if (strs == null || (strsLen = strs.length) == 0) { + return strs; + } + String[] newArr = new String[strsLen]; + for (int i = 0; i < strsLen; i++) { + newArr[i] = strip(strs[i], stripChars); + } + return newArr; + } + + // Equals + //----------------------------------------------------------------------- + /** + *

Compares two Strings, returning true if they are equal.

+ * + *

nulls are handled without exceptions. Two null + * references are considered to be equal. The comparison is case sensitive.

+ * + *
+     * StringUtils.equals(null, null)   = true
+     * StringUtils.equals(null, "abc")  = false
+     * StringUtils.equals("abc", null)  = false
+     * StringUtils.equals("abc", "abc") = true
+     * StringUtils.equals("abc", "ABC") = false
+     * 
+ * + * @see java.lang.String#equals(Object) + * @param str1 the first String, may be null + * @param str2 the second String, may be null + * @return true if the Strings are equal, case sensitive, or + * both null + */ + public static boolean equals(String str1, String str2) { + return (str1 == null ? str2 == null : str1.equals(str2)); + } + + /** + *

Compares two Strings, returning true if they are equal ignoring + * the case.

+ * + *

nulls are handled without exceptions. Two null + * references are considered equal. Comparison is case insensitive.

+ * + *
+     * StringUtils.equalsIgnoreCase(null, null)   = true
+     * StringUtils.equalsIgnoreCase(null, "abc")  = false
+     * StringUtils.equalsIgnoreCase("abc", null)  = false
+     * StringUtils.equalsIgnoreCase("abc", "abc") = true
+     * StringUtils.equalsIgnoreCase("abc", "ABC") = true
+     * 
+ * + * @see java.lang.String#equalsIgnoreCase(String) + * @param str1 the first String, may be null + * @param str2 the second String, may be null + * @return true if the Strings are equal, case insensitive, or + * both null + */ + public static boolean equalsIgnoreCase(String str1, String str2) { + return (str1 == null ? str2 == null : str1.equalsIgnoreCase(str2)); + } + + // IndexOf + //----------------------------------------------------------------------- + /** + *

Finds the first index within a String, handling null. + * This method uses {@link String#indexOf(int)}.

+ * + *

A null or empty ("") String will return -1.

+ * + *
+     * StringUtils.indexOf(null, *)         = -1
+     * StringUtils.indexOf("", *)           = -1
+     * StringUtils.indexOf("aabaabaa", 'a') = 0
+     * StringUtils.indexOf("aabaabaa", 'b') = 2
+     * 
+ * + * @param str the String to check, may be null + * @param searchChar the character to find + * @return the first index of the search character, + * -1 if no match or null string input + * @since 2.0 + */ + public static int indexOf(String str, char searchChar) { + if (str == null || str.length() == 0) { + return -1; + } + return str.indexOf(searchChar); + } + + /** + *

Finds the first index within a String from a start position, + * handling null. + * This method uses {@link String#indexOf(int, int)}.

+ * + *

A null or empty ("") String will return -1. + * A negative start position is treated as zero. + * A start position greater than the string length returns -1.

+ * + *
+     * StringUtils.indexOf(null, *, *)          = -1
+     * StringUtils.indexOf("", *, *)            = -1
+     * StringUtils.indexOf("aabaabaa", 'b', 0)  = 2
+     * StringUtils.indexOf("aabaabaa", 'b', 3)  = 5
+     * StringUtils.indexOf("aabaabaa", 'b', 9)  = -1
+     * StringUtils.indexOf("aabaabaa", 'b', -1) = 2
+     * 
+ * + * @param str the String to check, may be null + * @param searchChar the character to find + * @param startPos the start position, negative treated as zero + * @return the first index of the search character, + * -1 if no match or null string input + * @since 2.0 + */ + public static int indexOf(String str, char searchChar, int startPos) { + if (str == null || str.length() == 0) { + return -1; + } + return str.indexOf(searchChar, startPos); + } + + /** + *

Finds the first index within a String, handling null. + * This method uses {@link String#indexOf(String)}.

+ * + *

A null String will return -1.

+ * + *
+     * StringUtils.indexOf(null, *)          = -1
+     * StringUtils.indexOf(*, null)          = -1
+     * StringUtils.indexOf("", "")           = 0
+     * StringUtils.indexOf("aabaabaa", "a")  = 0
+     * StringUtils.indexOf("aabaabaa", "b")  = 2
+     * StringUtils.indexOf("aabaabaa", "ab") = 1
+     * StringUtils.indexOf("aabaabaa", "")   = 0
+     * 
+ * + * @param str the String to check, may be null + * @param searchStr the String to find, may be null + * @return the first index of the search String, + * -1 if no match or null string input + * @since 2.0 + */ + public static int indexOf(String str, String searchStr) { + if (str == null || searchStr == null) { + return -1; + } + return str.indexOf(searchStr); + } + + /** + *

Finds the first index within a String, handling null. + * This method uses {@link String#indexOf(String, int)}.

+ * + *

A null String will return -1. + * A negative start position is treated as zero. + * An empty ("") search String always matches. + * A start position greater than the string length only matches + * an empty search String.

+ * + *
+     * StringUtils.indexOf(null, *, *)          = -1
+     * StringUtils.indexOf(*, null, *)          = -1
+     * StringUtils.indexOf("", "", 0)           = 0
+     * StringUtils.indexOf("aabaabaa", "a", 0)  = 0
+     * StringUtils.indexOf("aabaabaa", "b", 0)  = 2
+     * StringUtils.indexOf("aabaabaa", "ab", 0) = 1
+     * StringUtils.indexOf("aabaabaa", "b", 3)  = 5
+     * StringUtils.indexOf("aabaabaa", "b", 9)  = -1
+     * StringUtils.indexOf("aabaabaa", "b", -1) = 2
+     * StringUtils.indexOf("aabaabaa", "", 2)   = 2
+     * StringUtils.indexOf("abc", "", 9)        = 3
+     * 
+ * + * @param str the String to check, may be null + * @param searchStr the String to find, may be null + * @param startPos the start position, negative treated as zero + * @return the first index of the search String, + * -1 if no match or null string input + * @since 2.0 + */ + public static int indexOf(String str, String searchStr, int startPos) { + if (str == null || searchStr == null) { + return -1; + } + // JDK1.2/JDK1.3 have a bug, when startPos > str.length for "", hence + if (searchStr.length() == 0 && startPos >= str.length()) { + return str.length(); + } + return str.indexOf(searchStr, startPos); + } + + // LastIndexOf + //----------------------------------------------------------------------- + /** + *

Finds the last index within a String, handling null. + * This method uses {@link String#lastIndexOf(int)}.

+ * + *

A null or empty ("") String will return -1.

+ * + *
+     * StringUtils.lastIndexOf(null, *)         = -1
+     * StringUtils.lastIndexOf("", *)           = -1
+     * StringUtils.lastIndexOf("aabaabaa", 'a') = 7
+     * StringUtils.lastIndexOf("aabaabaa", 'b') = 5
+     * 
+ * + * @param str the String to check, may be null + * @param searchChar the character to find + * @return the last index of the search character, + * -1 if no match or null string input + * @since 2.0 + */ + public static int lastIndexOf(String str, char searchChar) { + if (str == null || str.length() == 0) { + return -1; + } + return str.lastIndexOf(searchChar); + } + + /** + *

Finds the last index within a String from a start position, + * handling null. + * This method uses {@link String#lastIndexOf(int, int)}.

+ * + *

A null or empty ("") String will return -1. + * A negative start position returns -1. + * A start position greater than the string length searches the whole string.

+ * + *
+     * StringUtils.lastIndexOf(null, *, *)          = -1
+     * StringUtils.lastIndexOf("", *,  *)           = -1
+     * StringUtils.lastIndexOf("aabaabaa", 'b', 8)  = 5
+     * StringUtils.lastIndexOf("aabaabaa", 'b', 4)  = 2
+     * StringUtils.lastIndexOf("aabaabaa", 'b', 0)  = -1
+     * StringUtils.lastIndexOf("aabaabaa", 'b', 9)  = 5
+     * StringUtils.lastIndexOf("aabaabaa", 'b', -1) = -1
+     * StringUtils.lastIndexOf("aabaabaa", 'a', 0)  = 0
+     * 
+ * + * @param str the String to check, may be null + * @param searchChar the character to find + * @param startPos the start position + * @return the last index of the search character, + * -1 if no match or null string input + * @since 2.0 + */ + public static int lastIndexOf(String str, char searchChar, int startPos) { + if (str == null || str.length() == 0) { + return -1; + } + return str.lastIndexOf(searchChar, startPos); + } + + /** + *

Finds the last index within a String, handling null. + * This method uses {@link String#lastIndexOf(String)}.

+ * + *

A null String will return -1.

+ * + *
+     * StringUtils.lastIndexOf(null, *)          = -1
+     * StringUtils.lastIndexOf(*, null)          = -1
+     * StringUtils.lastIndexOf("", "")           = 0
+     * StringUtils.lastIndexOf("aabaabaa", "a")  = 0
+     * StringUtils.lastIndexOf("aabaabaa", "b")  = 2
+     * StringUtils.lastIndexOf("aabaabaa", "ab") = 1
+     * StringUtils.lastIndexOf("aabaabaa", "")   = 8
+     * 
+ * + * @param str the String to check, may be null + * @param searchStr the String to find, may be null + * @return the last index of the search String, + * -1 if no match or null string input + * @since 2.0 + */ + public static int lastIndexOf(String str, String searchStr) { + if (str == null || searchStr == null) { + return -1; + } + return str.lastIndexOf(searchStr); + } + + /** + *

Finds the first index within a String, handling null. + * This method uses {@link String#lastIndexOf(String, int)}.

+ * + *

A null String will return -1. + * A negative start position returns -1. + * An empty ("") search String always matches unless the start position is negative. + * A start position greater than the string length searches the whole string.

+ * + *
+     * StringUtils.lastIndexOf(null, *, *)          = -1
+     * StringUtils.lastIndexOf(*, null, *)          = -1
+     * StringUtils.lastIndexOf("aabaabaa", "a", 8)  = 7
+     * StringUtils.lastIndexOf("aabaabaa", "b", 8)  = 5
+     * StringUtils.lastIndexOf("aabaabaa", "ab", 8) = 4
+     * StringUtils.lastIndexOf("aabaabaa", "b", 9)  = 5
+     * StringUtils.lastIndexOf("aabaabaa", "b", -1) = -1
+     * StringUtils.lastIndexOf("aabaabaa", "a", 0)  = 0
+     * StringUtils.lastIndexOf("aabaabaa", "b", 0)  = -1
+     * 
+ * + * @param str the String to check, may be null + * @param searchStr the String to find, may be null + * @param startPos the start position, negative treated as zero + * @return the first index of the search String, + * -1 if no match or null string input + * @since 2.0 + */ + public static int lastIndexOf(String str, String searchStr, int startPos) { + if (str == null || searchStr == null) { + return -1; + } + return str.lastIndexOf(searchStr, startPos); + } + + // Contains + //----------------------------------------------------------------------- + /** + *

Checks if String contains a search character, handling null. + * This method uses {@link String#indexOf(int)}.

+ * + *

A null or empty ("") String will return false.

+ * + *
+     * StringUtils.contains(null, *)    = false
+     * StringUtils.contains("", *)      = false
+     * StringUtils.contains("abc", 'a') = true
+     * StringUtils.contains("abc", 'z') = false
+     * 
+ * + * @param str the String to check, may be null + * @param searchChar the character to find + * @return true if the String contains the search character, + * false if not or null string input + * @since 2.0 + */ + public static boolean contains(String str, char searchChar) { + if (str == null || str.length() == 0) { + return false; + } + return (str.indexOf(searchChar) >= 0); + } + + /** + *

Find the first index within a String, handling null. + * This method uses {@link String#indexOf(int)}.

+ * + *

A null String will return false.

+ * + *
+     * StringUtils.contains(null, *)     = false
+     * StringUtils.contains(*, null)     = false
+     * StringUtils.contains("", "")      = true
+     * StringUtils.contains("abc", "")   = true
+     * StringUtils.contains("abc", "a")  = true
+     * StringUtils.contains("abc", "z")  = false
+     * 
+ * + * @param str the String to check, may be null + * @param searchStr the String to find, may be null + * @return true if the String contains the search character, + * false if not or null string input + * @since 2.0 + */ + public static boolean contains(String str, String searchStr) { + if (str == null || searchStr == null) { + return false; + } + return (str.indexOf(searchStr) >= 0); + } + + // IndexOfAny chars + //----------------------------------------------------------------------- + /** + *

Search a String to find the first index of any + * character in the given set of characters.

+ * + *

A null String will return -1. + * A null or zero length search array will return -1.

+ * + *
+     * StringUtils.indexOfAny(null, *)                = -1
+     * StringUtils.indexOfAny("", *)                  = -1
+     * StringUtils.indexOfAny(*, null)                = -1
+     * StringUtils.indexOfAny(*, [])                  = -1
+     * StringUtils.indexOfAny("zzabyycdxx",['z','a']) = 0
+     * StringUtils.indexOfAny("zzabyycdxx",['b','y']) = 3
+     * StringUtils.indexOfAny("aba", ['z'])           = -1
+     * 
+ * + * @param str the String to check, may be null + * @param searchChars the chars to search for, may be null + * @return the index of any of the chars, -1 if no match or null input + * @since 2.0 + */ + public static int indexOfAny(String str, char[] searchChars) { + if (str == null || str.length() == 0 || searchChars == null || searchChars.length == 0) { + return -1; + } + for (int i = 0; i < str.length(); i ++) { + char ch = str.charAt(i); + for (int j = 0; j < searchChars.length; j++) { + if (searchChars[j] == ch) { + return i; + } + } + } + return -1; + } + + /** + *

Search a String to find the first index of any + * character in the given set of characters.

+ * + *

A null String will return -1. + * A null search string will return -1.

+ * + *
+     * StringUtils.indexOfAny(null, *)            = -1
+     * StringUtils.indexOfAny("", *)              = -1
+     * StringUtils.indexOfAny(*, null)            = -1
+     * StringUtils.indexOfAny(*, "")              = -1
+     * StringUtils.indexOfAny("zzabyycdxx", "za") = 0
+     * StringUtils.indexOfAny("zzabyycdxx", "by") = 3
+     * StringUtils.indexOfAny("aba","z")          = -1
+     * 
+ * + * @param str the String to check, may be null + * @param searchChars the chars to search for, may be null + * @return the index of any of the chars, -1 if no match or null input + * @since 2.0 + */ + public static int indexOfAny(String str, String searchChars) { + if (str == null || str.length() == 0 || searchChars == null || searchChars.length() == 0) { + return -1; + } + return indexOfAny(str, searchChars.toCharArray()); + } + + // IndexOfAnyBut chars + //----------------------------------------------------------------------- + /** + *

Search a String to find the first index of any + * character not in the given set of characters.

+ * + *

A null String will return -1. + * A null or zero length search array will return -1.

+ * + *
+     * StringUtils.indexOfAnyBut(null, *)           = -1
+     * StringUtils.indexOfAnyBut("", *)             = -1
+     * StringUtils.indexOfAnyBut(*, null)           = -1
+     * StringUtils.indexOfAnyBut(*, [])             = -1
+     * StringUtils.indexOfAnyBut("zzabyycdxx",'za') = 3
+     * StringUtils.indexOfAnyBut("zzabyycdxx", '')  = 0
+     * StringUtils.indexOfAnyBut("aba", 'ab')       = -1
+     * 
+ * + * @param str the String to check, may be null + * @param searchChars the chars to search for, may be null + * @return the index of any of the chars, -1 if no match or null input + * @since 2.0 + */ + public static int indexOfAnyBut(String str, char[] searchChars) { + if (str == null || str.length() == 0 || searchChars == null || searchChars.length == 0) { + return -1; + } + outer: for (int i = 0; i < str.length(); i ++) { + char ch = str.charAt(i); + for (int j = 0; j < searchChars.length; j++) { + if (searchChars[j] == ch) { + continue outer; + } + } + return i; + } + return -1; + } + + /** + *

Search a String to find the first index of any + * character not in the given set of characters.

+ * + *

A null String will return -1. + * A null search string will return -1.

+ * + *
+     * StringUtils.indexOfAnyBut(null, *)            = -1
+     * StringUtils.indexOfAnyBut("", *)              = -1
+     * StringUtils.indexOfAnyBut(*, null)            = -1
+     * StringUtils.indexOfAnyBut(*, "")              = -1
+     * StringUtils.indexOfAnyBut("zzabyycdxx", "za") = 3
+     * StringUtils.indexOfAnyBut("zzabyycdxx", "")   = 0
+     * StringUtils.indexOfAnyBut("aba","ab")         = -1
+     * 
+ * + * @param str the String to check, may be null + * @param searchChars the chars to search for, may be null + * @return the index of any of the chars, -1 if no match or null input + * @since 2.0 + */ + public static int indexOfAnyBut(String str, String searchChars) { + if (str == null || str.length() == 0 || searchChars == null || searchChars.length() == 0) { + return -1; + } + for (int i = 0; i < str.length(); i++) { + if (searchChars.indexOf(str.charAt(i)) < 0) { + return i; + } + } + return -1; + } + + // ContainsOnly + //----------------------------------------------------------------------- + /** + *

Checks if the String contains only certain characters.

+ * + *

A null String will return false. + * A null valid character array will return false. + * An empty String ("") always returns true.

+ * + *
+     * StringUtils.containsOnly(null, *)       = false
+     * StringUtils.containsOnly(*, null)       = false
+     * StringUtils.containsOnly("", *)         = true
+     * StringUtils.containsOnly("ab", '')      = false
+     * StringUtils.containsOnly("abab", 'abc') = true
+     * StringUtils.containsOnly("ab1", 'abc')  = false
+     * StringUtils.containsOnly("abz", 'abc')  = false
+     * 
+ * + * @param str the String to check, may be null + * @param valid an array of valid chars, may be null + * @return true if it only contains valid chars and is non-null + */ + public static boolean containsOnly(String str, char[] valid) { + // All these pre-checks are to maintain API with an older version + if ( (valid == null) || (str == null) ) { + return false; + } + if (str.length() == 0) { + return true; + } + if (valid.length == 0) { + return false; + } + return indexOfAnyBut(str, valid) == -1; + } + + /** + *

Checks if the String contains only certain characters.

+ * + *

A null String will return false. + * A null valid character String will return false. + * An empty String ("") always returns true.

+ * + *
+     * StringUtils.containsOnly(null, *)       = false
+     * StringUtils.containsOnly(*, null)       = false
+     * StringUtils.containsOnly("", *)         = true
+     * StringUtils.containsOnly("ab", "")      = false
+     * StringUtils.containsOnly("abab", "abc") = true
+     * StringUtils.containsOnly("ab1", "abc")  = false
+     * StringUtils.containsOnly("abz", "abc")  = false
+     * 
+ * + * @param str the String to check, may be null + * @param validChars a String of valid chars, may be null + * @return true if it only contains valid chars and is non-null + * @since 2.0 + */ + public static boolean containsOnly(String str, String validChars) { + if (str == null || validChars == null) { + return false; + } + return containsOnly(str, validChars.toCharArray()); + } + + // ContainsNone + //----------------------------------------------------------------------- + /** + *

Checks that the String does not contain certain characters.

+ * + *

A null String will return true. + * A null invalid character array will return true. + * An empty String ("") always returns true.

+ * + *
+     * StringUtils.containsNone(null, *)       = true
+     * StringUtils.containsNone(*, null)       = true
+     * StringUtils.containsNone("", *)         = true
+     * StringUtils.containsNone("ab", '')      = true
+     * StringUtils.containsNone("abab", 'xyz') = true
+     * StringUtils.containsNone("ab1", 'xyz')  = true
+     * StringUtils.containsNone("abz", 'xyz')  = false
+     * 
+ * + * @param str the String to check, may be null + * @param invalidChars an array of invalid chars, may be null + * @return true if it contains none of the invalid chars, or is null + * @since 2.0 + */ + public static boolean containsNone(String str, char[] invalidChars) { + if (str == null || invalidChars == null) { + return true; + } + int strSize = str.length(); + int validSize = invalidChars.length; + for (int i = 0; i < strSize; i++) { + char ch = str.charAt(i); + for (int j = 0; j < validSize; j++) { + if (invalidChars[j] == ch) { + return false; + } + } + } + return true; + } + + /** + *

Checks that the String does not contain certain characters.

+ * + *

A null String will return true. + * A null invalid character array will return true. + * An empty String ("") always returns true.

+ * + *
+     * StringUtils.containsNone(null, *)       = true
+     * StringUtils.containsNone(*, null)       = true
+     * StringUtils.containsNone("", *)         = true
+     * StringUtils.containsNone("ab", "")      = true
+     * StringUtils.containsNone("abab", "xyz") = true
+     * StringUtils.containsNone("ab1", "xyz")  = true
+     * StringUtils.containsNone("abz", "xyz")  = false
+     * 
+ * + * @param str the String to check, may be null + * @param invalidChars a String of invalid chars, may be null + * @return true if it contains none of the invalid chars, or is null + * @since 2.0 + */ + public static boolean containsNone(String str, String invalidChars) { + if (str == null || invalidChars == null) { + return true; + } + return containsNone(str, invalidChars.toCharArray()); + } + + // IndexOfAny strings + //----------------------------------------------------------------------- + /** + *

Find the first index of any of a set of potential substrings.

+ * + *

A null String will return -1. + * A null or zero length search array will return -1. + * A null search array entry will be ignored, but a search + * array containing "" will return 0 if str is not + * null. This method uses {@link String#indexOf(String)}.

+ * + *
+     * StringUtils.indexOfAny(null, *)                     = -1
+     * StringUtils.indexOfAny(*, null)                     = -1
+     * StringUtils.indexOfAny(*, [])                       = -1
+     * StringUtils.indexOfAny("zzabyycdxx", ["ab","cd"])   = 2
+     * StringUtils.indexOfAny("zzabyycdxx", ["cd","ab"])   = 2
+     * StringUtils.indexOfAny("zzabyycdxx", ["mn","op"])   = -1
+     * StringUtils.indexOfAny("zzabyycdxx", ["zab","aby"]) = 1
+     * StringUtils.indexOfAny("zzabyycdxx", [""])          = 0
+     * StringUtils.indexOfAny("", [""])                    = 0
+     * StringUtils.indexOfAny("", ["a"])                   = -1
+     * 
+ * + * @param str the String to check, may be null + * @param searchStrs the Strings to search for, may be null + * @return the first index of any of the searchStrs in str, -1 if no match + */ + public static int indexOfAny(String str, String[] searchStrs) { + if ((str == null) || (searchStrs == null)) { + return -1; + } + int sz = searchStrs.length; + + // String's can't have a MAX_VALUEth index. + int ret = Integer.MAX_VALUE; + + int tmp = 0; + for (int i = 0; i < sz; i++) { + String search = searchStrs[i]; + if (search == null) { + continue; + } + tmp = str.indexOf(search); + 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.

+ * + *

A null String will return -1. + * A null search array will return -1. + * A null or zero length search array entry will be ignored, + * but a search array containing "" will return the length of str + * if str is not null. This method uses {@link String#indexOf(String)}

+ * + *
+     * StringUtils.lastIndexOfAny(null, *)                   = -1
+     * StringUtils.lastIndexOfAny(*, null)                   = -1
+     * StringUtils.lastIndexOfAny(*, [])                     = -1
+     * StringUtils.lastIndexOfAny(*, [null])                 = -1
+     * StringUtils.lastIndexOfAny("zzabyycdxx", ["ab","cd"]) = 6
+     * StringUtils.lastIndexOfAny("zzabyycdxx", ["cd","ab"]) = 6
+     * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn","op"]) = -1
+     * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn","op"]) = -1
+     * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn",""])   = 10
+     * 
+ * + * @param str the String to check, may be null + * @param searchStrs the Strings to search for, may be null + * @return the last index of any of the Strings, -1 if no match + */ + public static int lastIndexOfAny(String str, String[] searchStrs) { + if ((str == null) || (searchStrs == null)) { + return -1; + } + int sz = searchStrs.length; + int ret = -1; + int tmp = 0; + for (int i = 0; i < sz; i++) { + String search = searchStrs[i]; + if (search == null) { + continue; + } + tmp = str.lastIndexOf(search); + if (tmp > ret) { + ret = tmp; + } + } + return ret; + } + + // Substring + //----------------------------------------------------------------------- + /** + *

Gets a substring from the specified String avoiding exceptions.

+ * + *

A negative start position can be used to start n + * characters from the end of the String.

+ * + *

A null String will return null. + * An empty ("") String will return "".

+ * + *
+     * StringUtils.substring(null, *)   = null
+     * StringUtils.substring("", *)     = ""
+     * StringUtils.substring("abc", 0)  = "abc"
+     * StringUtils.substring("abc", 2)  = "c"
+     * StringUtils.substring("abc", 4)  = ""
+     * StringUtils.substring("abc", -2) = "bc"
+     * StringUtils.substring("abc", -4) = "abc"
+     * 
+ * + * @param str the String to get the substring from, may be null + * @param start the position to start from, negative means + * count back from the end of the String by this many characters + * @return substring from start position, null if null String input + */ + public static String substring(String str, int start) { + if (str == null) { + return null; + } + + // handle negatives, which means last n characters + if (start < 0) { + start = str.length() + start; // remember start is negative + } + + if (start < 0) { + start = 0; + } + if (start > str.length()) { + return EMPTY; + } + + return str.substring(start); + } + + /** + *

Gets a substring from the specified String avoiding exceptions.

+ * + *

A negative start position can be used to start/end n + * characters from the end of the String.

+ * + *

The returned substring starts with the character in the start + * position and ends before the end position. All postion counting is + * zero-based -- i.e., to start at the beginning of the string use + * start = 0. Negative start and end positions can be used to + * specify offsets relative to the end of the String.

+ * + *

If start is not strictly to the left of end, "" + * is returned.

+ * + *
+     * StringUtils.substring(null, *, *)    = null
+     * StringUtils.substring("", * ,  *)    = "";
+     * StringUtils.substring("abc", 0, 2)   = "ab"
+     * StringUtils.substring("abc", 2, 0)   = ""
+     * StringUtils.substring("abc", 2, 4)   = "c"
+     * StringUtils.substring("abc", 4, 6)   = ""
+     * StringUtils.substring("abc", 2, 2)   = ""
+     * StringUtils.substring("abc", -2, -1) = "b"
+     * StringUtils.substring("abc", -4, 2)  = "ab"
+     * 
+ * + * @param str the String to get the substring from, may be null + * @param start the position to start from, negative means + * count back from the end of the String by this many characters + * @param end the position to end at (exclusive), negative means + * count back from the end of the String by this many characters + * @return substring from start position to end positon, + * null if null String input + */ + public static String substring(String str, int start, int end) { + if (str == null) { + return null; + } + + // handle negatives + if (end < 0) { + end = str.length() + end; // remember end is negative + } + if (start < 0) { + start = str.length() + start; // remember start is negative + } + + // check length next + if (end > str.length()) { + end = str.length(); + } + + // if start is greater than end, return "" + if (start > end) { + return EMPTY; + } + + if (start < 0) { + start = 0; + } + if (end < 0) { + end = 0; + } + + return str.substring(start, end); + } + + // Left/Right/Mid + //----------------------------------------------------------------------- + /** + *

Gets the leftmost len characters of a String.

+ * + *

If len characters are not available, or the + * String is null, the String will be returned without + * an exception. An exception is thrown if len is negative.

+ * + *
+     * StringUtils.left(null, *)    = null
+     * StringUtils.left(*, -ve)     = ""
+     * StringUtils.left("", *)      = ""
+     * StringUtils.left("abc", 0)   = ""
+     * StringUtils.left("abc", 2)   = "ab"
+     * StringUtils.left("abc", 4)   = "abc"
+     * 
+ * + * @param str the String to get the leftmost characters from, may be null + * @param len the length of the required String, must be zero or positive + * @return the leftmost characters, null if null String input + */ + public static String left(String str, int len) { + if (str == null) { + return null; + } + if (len < 0) { + return EMPTY; + } + if (str.length() <= len) { + return str; + } else { + return str.substring(0, len); + } + } + + /** + *

Gets the rightmost len characters of a String.

+ * + *

If len characters are not available, or the String + * is null, the String will be returned without an + * an exception. An exception is thrown if len is negative.

+ * + *
+     * StringUtils.right(null, *)    = null
+     * StringUtils.right(*, -ve)     = ""
+     * StringUtils.right("", *)      = ""
+     * StringUtils.right("abc", 0)   = ""
+     * StringUtils.right("abc", 2)   = "bc"
+     * StringUtils.right("abc", 4)   = "abc"
+     * 
+ * + * @param str the String to get the rightmost characters from, may be null + * @param len the length of the required String, must be zero or positive + * @return the rightmost characters, null if null String input + */ + public static String right(String str, int len) { + if (str == null) { + return null; + } + if (len < 0) { + return EMPTY; + } + if (str.length() <= len) { + return str; + } else { + return str.substring(str.length() - len); + } + } + + /** + *

Gets len characters from the middle of a String.

+ * + *

If len characters are not available, the remainder + * of the String will be returned without an exception. If the + * String is null, null will be returned. + * An exception is thrown if len is negative.

+ * + *
+     * StringUtils.mid(null, *, *)    = null
+     * StringUtils.mid(*, *, -ve)     = ""
+     * StringUtils.mid("", 0, *)      = ""
+     * StringUtils.mid("abc", 0, 2)   = "ab"
+     * StringUtils.mid("abc", 0, 4)   = "abc"
+     * StringUtils.mid("abc", 2, 4)   = "c"
+     * StringUtils.mid("abc", 4, 2)   = ""
+     * StringUtils.mid("abc", -2, 2)  = "ab"
+     * 
+ * + * @param str the String to get the characters from, may be null + * @param pos the position to start from, negative treated as zero + * @param len the length of the required String, must be zero or positive + * @return the middle characters, null if null String input + */ + public static String mid(String str, int pos, int len) { + if (str == null) { + return null; + } + if (len < 0 || pos > str.length()) { + return EMPTY; + } + if (pos < 0) { + pos = 0; + } + if (str.length() <= (pos + len)) { + return str.substring(pos); + } else { + return str.substring(pos, pos + len); + } + } + + // SubStringAfter/SubStringBefore + //----------------------------------------------------------------------- + /** + *

Gets the substring before the first occurance of a separator. + * The separator is not returned.

+ * + *

A null string input will return null. + * An empty ("") string input will return the empty string. + * A null separator will return the input string.

+ * + *
+     * StringUtils.substringBefore(null, *)      = null
+     * StringUtils.substringBefore("", *)        = ""
+     * StringUtils.substringBefore("abc", "a")   = ""
+     * StringUtils.substringBefore("abcba", "b") = "a"
+     * StringUtils.substringBefore("abc", "c")   = "ab"
+     * StringUtils.substringBefore("abc", "d")   = "abc"
+     * StringUtils.substringBefore("abc", "")    = ""
+     * StringUtils.substringBefore("abc", null)  = "abc"
+     * 
+ * + * @param str the String to get a substring from, may be null + * @param separator the String to search for, may be null + * @return the substring before the first occurance of the separator, + * null if null String input + * @since 2.0 + */ + public static String substringBefore(String str, String separator) { + if (str == null || separator == null || str.length() == 0) { + return str; + } + if (separator.length() == 0) { + return EMPTY; + } + int pos = str.indexOf(separator); + if (pos == -1) { + return str; + } + return str.substring(0, pos); + } + + /** + *

Gets the substring after the first occurance of a separator. + * The separator is not returned.

+ * + *

A null string input will return null. + * An empty ("") string input will return the empty string. + * A null separator will return the empty string if the + * input string is not null.

+ * + *
+     * StringUtils.substringAfter(null, *)      = null
+     * StringUtils.substringAfter("", *)        = ""
+     * StringUtils.substringAfter(*, null)      = ""
+     * StringUtils.substringAfter("abc", "a")   = "bc"
+     * StringUtils.substringAfter("abcba", "b") = "cba"
+     * StringUtils.substringAfter("abc", "c")   = ""
+     * StringUtils.substringAfter("abc", "d")   = ""
+     * StringUtils.substringAfter("abc", "")    = "abc"
+     * 
+ * + * @param str the String to get a substring from, may be null + * @param separator the String to search for, may be null + * @return the substring after the first occurance of the separator, + * null if null String input + * @since 2.0 + */ + public static String substringAfter(String str, String separator) { + if (str == null || str.length() == 0) { + return str; + } + if (separator == null) { + return EMPTY; + } + int pos = str.indexOf(separator); + if (pos == -1) { + return EMPTY; + } + return str.substring(pos + separator.length()); + } + + /** + *

Gets the substring before the last occurance of a separator. + * The separator is not returned.

+ * + *

A null string input will return null. + * An empty ("") string input will return the empty string. + * An empty or null separator will return the input string.

+ * + *
+     * StringUtils.substringBeforeLast(null, *)      = null
+     * StringUtils.substringBeforeLast("", *)        = ""
+     * StringUtils.substringBeforeLast("abcba", "b") = "abc"
+     * StringUtils.substringBeforeLast("abc", "c")   = "ab"
+     * StringUtils.substringBeforeLast("a", "a")     = ""
+     * StringUtils.substringBeforeLast("a", "z")     = "a"
+     * StringUtils.substringBeforeLast("a", null)    = "a"
+     * StringUtils.substringBeforeLast("a", "")      = "a"
+     * 
+ * + * @param str the String to get a substring from, may be null + * @param separator the String to search for, may be null + * @return the substring before the last occurance of the separator, + * null if null String input + * @since 2.0 + */ + public static String substringBeforeLast(String str, String separator) { + if (str == null || separator == null || str.length() == 0 || separator.length() == 0) { + return str; + } + int pos = str.lastIndexOf(separator); + if (pos == -1) { + return str; + } + return str.substring(0, pos); + } + + /** + *

Gets the substring after the last occurance of a separator. + * The separator is not returned.

+ * + *

A null string input will return null. + * An empty ("") string input will return the empty string. + * An empty or null separator will return the empty string if + * the input string is not null.

+ * + *
+     * StringUtils.substringAfterLast(null, *)      = null
+     * StringUtils.substringAfterLast("", *)        = ""
+     * StringUtils.substringAfterLast(*, "")        = ""
+     * StringUtils.substringAfterLast(*, null)      = ""
+     * StringUtils.substringAfterLast("abc", "a")   = "bc"
+     * StringUtils.substringAfterLast("abcba", "b") = "a"
+     * StringUtils.substringAfterLast("abc", "c")   = ""
+     * StringUtils.substringAfterLast("a", "a")     = ""
+     * StringUtils.substringAfterLast("a", "z")     = ""
+     * 
+ * + * @param str the String to get a substring from, may be null + * @param separator the String to search for, may be null + * @return the substring after the last occurance of the separator, + * null if null String input + * @since 2.0 + */ + public static String substringAfterLast(String str, String separator) { + if (str == null || str.length() == 0) { + return str; + } + if (separator == null || separator.length() == 0) { + return EMPTY; + } + int pos = str.lastIndexOf(separator); + if (pos == -1 || pos == (str.length() - separator.length())) { + return EMPTY; + } + return str.substring(pos + separator.length()); + } + + // Substring between + //----------------------------------------------------------------------- + /** + *

Gets the String that is nested in between two instances of the + * same String.

+ * + *

A null input String returns null. + * A null tag returns null.

+ * + *
+     * StringUtils.substringBetween(null, *)            = null
+     * StringUtils.substringBetween("", "")             = ""
+     * StringUtils.substringBetween("", "tag")          = null
+     * StringUtils.substringBetween("tagabctag", null)  = null
+     * StringUtils.substringBetween("tagabctag", "")    = ""
+     * StringUtils.substringBetween("tagabctag", "tag") = "abc"
+     * 
+ * + * @param str the String containing the substring, may be null + * @param tag the String before and after the substring, may be null + * @return the substring, null if no match + * @since 2.0 + */ + public static String substringBetween(String str, String tag) { + return substringBetween(str, tag, tag); + } + + /** + *

Gets the String that is nested in between two Strings. + * Only the first match is returned.

+ * + *

A null input String returns null. + * A null open/close returns null (no match). + * An empty ("") open/close returns an empty string.

+ * + *
+     * StringUtils.substringBetween(null, *, *)          = null
+     * StringUtils.substringBetween("", "", "")          = ""
+     * StringUtils.substringBetween("", "", "tag")       = null
+     * StringUtils.substringBetween("", "tag", "tag")    = null
+     * StringUtils.substringBetween("yabcz", null, null) = null
+     * StringUtils.substringBetween("yabcz", "", "")     = ""
+     * StringUtils.substringBetween("yabcz", "y", "z")   = "abc"
+     * StringUtils.substringBetween("yabczyabcz", "y", "z")   = "abc"
+     * 
+ * + * @param str the String containing the substring, may be null + * @param open the String before the substring, may be null + * @param close the String after the substring, may be null + * @return the substring, null if no match + * @since 2.0 + */ + public static String substringBetween(String str, String open, String close) { + if (str == null || open == null || close == null) { + return null; + } + int start = str.indexOf(open); + if (start != -1) { + int end = str.indexOf(close, start + open.length()); + if (end != -1) { + return str.substring(start + open.length(), end); + } + } + return null; + } + + // Nested extraction + //----------------------------------------------------------------------- + /** + *

Gets the String that is nested in between two instances of the + * same String.

+ * + *

A null input String returns null. + * A null tag returns null.

+ * + *
+     * StringUtils.getNestedString(null, *)            = null
+     * StringUtils.getNestedString("", "")             = ""
+     * StringUtils.getNestedString("", "tag")          = null
+     * StringUtils.getNestedString("tagabctag", null)  = null
+     * StringUtils.getNestedString("tagabctag", "")    = ""
+     * StringUtils.getNestedString("tagabctag", "tag") = "abc"
+     * 
+ * + * @param str the String containing nested-string, may be null + * @param tag the String before and after nested-string, may be null + * @return the nested String, null if no match + * @deprecated Use the better named {@link #substringBetween(String, String)}. + * Method will be removed in Commons Lang 3.0. + */ + public static String getNestedString(String str, String tag) { + return substringBetween(str, tag, tag); + } + + /** + *

Gets the String that is nested in between two Strings. + * Only the first match is returned.

+ * + *

A null input String returns null. + * A null open/close returns null (no match). + * An empty ("") open/close returns an empty string.

+ * + *
+     * StringUtils.getNestedString(null, *, *)          = null
+     * StringUtils.getNestedString("", "", "")          = ""
+     * StringUtils.getNestedString("", "", "tag")       = null
+     * StringUtils.getNestedString("", "tag", "tag")    = null
+     * StringUtils.getNestedString("yabcz", null, null) = null
+     * StringUtils.getNestedString("yabcz", "", "")     = ""
+     * StringUtils.getNestedString("yabcz", "y", "z")   = "abc"
+     * StringUtils.getNestedString("yabczyabcz", "y", "z")   = "abc"
+     * 
+ * + * @param str the String containing nested-string, may be null + * @param open the String before nested-string, may be null + * @param close the String after nested-string, may be null + * @return the nested String, null if no match + * @deprecated Use the better named {@link #substringBetween(String, String, String)}. + * Method will be removed in Commons Lang 3.0. + */ + public static String getNestedString(String str, String open, String close) { + return substringBetween(str, open, close); + } + + // Splitting + //----------------------------------------------------------------------- + /** + *

Splits the provided text into an array, using whitespace as the + * separator. + * Whitespace is defined by {@link Character#isWhitespace(char)}.

+ * + *

The separator is not included in the returned String array. + * Adjacent separators are treated as one separator.

+ * + *

A null input String returns null.

+ * + *
+     * StringUtils.split(null)       = null
+     * StringUtils.split("")         = []
+     * StringUtils.split("abc def")  = ["abc", "def"]
+     * StringUtils.split("abc  def") = ["abc", "def"]
+     * StringUtils.split(" abc ")    = ["abc"]
+     * 
+ * + * @param str the String to parse, may be null + * @return an array of parsed Strings, null if null String input + */ + public static String[] split(String str) { + return split(str, null, -1); + } + + /** + *

Splits the provided text into an array, separator specified. + * This is an alternative to using StringTokenizer.

+ * + *

The separator is not included in the returned String array. + * Adjacent separators are treated as one separator.

+ * + *

A null input String returns null.

+ * + *
+     * StringUtils.split(null, *)         = null
+     * StringUtils.split("", *)           = []
+     * StringUtils.split("a.b.c", '.')    = ["a", "b", "c"]
+     * StringUtils.split("a..b.c", '.')   = ["a", "b", "c"]
+     * StringUtils.split("a:b:c", '.')    = ["a:b:c"]
+     * StringUtils.split("a\tb\nc", null) = ["a", "b", "c"]
+     * StringUtils.split("a b c", ' ')    = ["a", "b", "c"]
+     * 
+ * + * @param str the String to parse, may be null + * @param separatorChar the character used as the delimiter, + * null splits on whitespace + * @return an array of parsed Strings, null if null String input + * @since 2.0 + */ + public static String[] split(String str, char separatorChar) { + // Performance tuned for 2.0 (JDK1.4) + + if (str == null) { + return null; + } + int len = str.length(); + if (len == 0) { + return ArrayUtils.EMPTY_STRING_ARRAY; + } + List list = new ArrayList(); + int i =0, start = 0; + boolean match = false; + while (i < len) { + if (str.charAt(i) == separatorChar) { + if (match) { + list.add(str.substring(start, i)); + match = false; + } + start = ++i; + continue; + } + match = true; + i++; + } + if (match) { + list.add(str.substring(start, i)); + } + return (String[]) list.toArray(new String[list.size()]); + } + + /** + *

Splits the provided text into an array, separators specified. + * This is an alternative to using StringTokenizer.

+ * + *

The separator is not included in the returned String array. + * Adjacent separators are treated as one separator.

+ * + *

A null input String returns null. + * A null separatorChars splits on whitespace.

+ * + *
+     * StringUtils.split(null, *)         = null
+     * StringUtils.split("", *)           = []
+     * StringUtils.split("abc def", null) = ["abc", "def"]
+     * StringUtils.split("abc def", " ")  = ["abc", "def"]
+     * StringUtils.split("abc  def", " ") = ["abc", "def"]
+     * StringUtils.split("ab:cd:ef", ":") = ["ab", "cd", "ef"]
+     * 
+ * + * @param str the String to parse, may be null + * @param separatorChars the characters used as the delimiters, + * null splits on whitespace + * @return an array of parsed Strings, null if null String input + */ + public static String[] split(String str, String separatorChars) { + return split(str, separatorChars, -1); + } + + /** + *

Splits the provided text into an array, separators specified. + * This is an alternative to using StringTokenizer.

+ * + *

The separator is not included in the returned String array. + * Adjacent separators are treated as one separator.

+ * + *

A null input String returns null. + * A null separatorChars splits on whitespace.

+ * + *
+     * StringUtils.split(null, *, *)            = null
+     * StringUtils.split("", *, *)              = []
+     * StringUtils.split("ab de fg", null, 0)   = ["ab", "cd", "ef"]
+     * StringUtils.split("ab   de fg", null, 0) = ["ab", "cd", "ef"]
+     * StringUtils.split("ab:cd:ef", ":", 0)    = ["ab", "cd", "ef"]
+     * StringUtils.split("ab:cd:ef", ":", 2)    = ["ab", "cdef"]
+     * 
+ * + * @param str the String to parse, may be null + * @param separatorChars the characters used as the delimiters, + * null splits on whitespace + * @param max the maximum number of elements to include in the + * array. A zero or negative value implies no limit + * @return an array of parsed Strings, null if null String input + */ + public static String[] split(String str, String separatorChars, int max) { + // Performance tuned for 2.0 (JDK1.4) + // Direct code is quicker than StringTokenizer. + // Also, StringTokenizer uses isSpace() not isWhitespace() + + if (str == null) { + return null; + } + int len = str.length(); + if (len == 0) { + return ArrayUtils.EMPTY_STRING_ARRAY; + } + List list = new ArrayList(); + int sizePlus1 = 1; + int i =0, start = 0; + boolean match = false; + if (separatorChars == null) { + // Null separator means use whitespace + while (i < len) { + if (Character.isWhitespace(str.charAt(i))) { + if (match) { + if (sizePlus1++ == max) { + i = len; + } + list.add(str.substring(start, i)); + match = false; + } + start = ++i; + continue; + } + match = true; + i++; + } + } else if (separatorChars.length() == 1) { + // Optimise 1 character case + char sep = separatorChars.charAt(0); + while (i < len) { + if (str.charAt(i) == sep) { + if (match) { + if (sizePlus1++ == max) { + i = len; + } + list.add(str.substring(start, i)); + match = false; + } + start = ++i; + continue; + } + match = true; + i++; + } + } else { + // standard case + while (i < len) { + if (separatorChars.indexOf(str.charAt(i)) >= 0) { + if (match) { + if (sizePlus1++ == max) { + i = len; + } + list.add(str.substring(start, i)); + match = false; + } + start = ++i; + continue; + } + match = true; + i++; + } + } + if (match) { + list.add(str.substring(start, i)); + } + return (String[]) list.toArray(new String[list.size()]); + } + + // Joining + //----------------------------------------------------------------------- + /** + *

Concatenates elements of an array into a single String. + * Null objects or empty strings within the array are represented by + * empty strings.

+ * + *
+     * StringUtils.concatenate(null)            = null
+     * StringUtils.concatenate([])              = ""
+     * StringUtils.concatenate([null])          = ""
+     * StringUtils.concatenate(["a", "b", "c"]) = "abc"
+     * StringUtils.concatenate([null, "", "a"]) = "a"
+     * 
+ * + * @param array the array of values to concatenate, may be null + * @return the concatenated String, null if null array input + * @deprecated Use the better named {@link #join(Object[])} instead. + * Method will be removed in Commons Lang 3.0. + */ + public static String concatenate(Object[] array) { + return join(array, null); + } + + /** + *

Joins the elements of the provided array into a single String + * containing the provided list of elements.

+ * + *

No separator is added to the joined String. + * Null objects or empty strings within the array are represented by + * empty strings.

+ * + *
+     * StringUtils.join(null)            = null
+     * StringUtils.join([])              = ""
+     * StringUtils.join([null])          = ""
+     * StringUtils.join(["a", "b", "c"]) = "abc"
+     * StringUtils.join([null, "", "a"]) = "a"
+     * 
+ * + * @param array the array of values to join together, may be null + * @return the joined String, null if null array input + * @since 2.0 + */ + public static String join(Object[] array) { + return join(array, null); + } + + /** + *

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. + * Null objects or empty strings within the array are represented by + * empty strings.

+ * + *
+     * StringUtils.join(null, *)               = null
+     * StringUtils.join([], *)                 = ""
+     * StringUtils.join([null], *)             = ""
+     * StringUtils.join(["a", "b", "c"], ';')  = "a;b;c"
+     * StringUtils.join(["a", "b", "c"], null) = "abc"
+     * StringUtils.join([null, "", "a"], ';')  = ";;a"
+     * 
+ * + * @param array the array of values to join together, may be null + * @param separator the separator character to use + * @return the joined String, null if null array input + * @since 2.0 + */ + public static String join(Object[] array, char separator) { + if (array == null) { + return null; + } + int arraySize = array.length; + int bufSize = (arraySize == 0 ? 0 : ((array[0] == null ? 16 : array[0].toString().length()) + 1) * arraySize); + StringBuffer buf = new StringBuffer(bufSize); + + for (int i = 0; i < arraySize; i++) { + if (i > 0) { + buf.append(separator); + } + if (array[i] != null) { + buf.append(array[i]); + } + } + return buf.toString(); + } + + /** + *

Joins the elements of the provided array into a single String + * containing the provided list of elements.

+ * + *

No delimiter is added before or after the list. + * A null separator is the same as an empty String (""). + * Null objects or empty strings within the array are represented by + * empty strings.

+ * + *
+     * StringUtils.join(null, *)                = null
+     * StringUtils.join([], *)                  = ""
+     * StringUtils.join([null], *)              = ""
+     * StringUtils.join(["a", "b", "c"], "--")  = "a--b--c"
+     * StringUtils.join(["a", "b", "c"], null)  = "abc"
+     * StringUtils.join(["a", "b", "c"], "")    = "abc"
+     * StringUtils.join([null, "", "a"], ',')   = ",,a"
+     * 
+ * + * @param array the array of values to join together, may be null + * @param separator the separator character to use, null treated as "" + * @return the joined String, null if null array input + */ + public static String join(Object[] array, String separator) { + if (array == null) { + return null; + } + if (separator == null) { + separator = EMPTY; + } + int arraySize = array.length; + + // ArraySize == 0: Len = 0 + // ArraySize > 0: Len = NofStrings *(len(firstString) + len(separator)) + // (Assuming that all Strings are roughly equally long) + int bufSize + = ((arraySize == 0) ? 0 + : arraySize * ((array[0] == null ? 16 : array[0].toString().length()) + + ((separator != null) ? separator.length(): 0))); + + StringBuffer buf = new StringBuffer(bufSize); + + for (int i = 0; i < arraySize; i++) { + if ((separator != null) && (i > 0)) { + buf.append(separator); + } + if (array[i] != null) { + buf.append(array[i]); + } + } + return buf.toString(); + } + + /** + *

Joins the elements of the provided Iterator into + * a single String containing the provided elements.

+ * + *

No delimiter is added before or after the list. Null objects or empty + * strings within the iteration are represented by empty strings.

+ * + *

See the examples here: {@link #join(Object[],char)}.

+ * + * @param iterator the Iterator of values to join together, may be null + * @param separator the separator character to use + * @return the joined String, null if null iterator input + * @since 2.0 + */ + public static String join(Iterator iterator, char separator) { + if (iterator == null) { + return null; + } + StringBuffer buf = new StringBuffer(256); // Java default is 16, probably too small + while (iterator.hasNext()) { + Object obj = iterator.next(); + if (obj != null) { + buf.append(obj); + } + if (iterator.hasNext()) { + buf.append(separator); + } + } + return buf.toString(); + } + + /** + *

Joins the elements of the provided Iterator into + * a single String containing the provided elements.

+ * + *

No delimiter is added before or after the list. + * A null separator is the same as an empty String ("").

+ * + *

See the examples here: {@link #join(Object[],String)}.

+ * + * @param iterator the Iterator of values to join together, may be null + * @param separator the separator character to use, null treated as "" + * @return the joined String, null if null iterator input + */ + public static String join(Iterator iterator, String separator) { + if (iterator == null) { + return null; + } + StringBuffer buf = new StringBuffer(256); // Java default is 16, probably too small + while (iterator.hasNext()) { + Object obj = iterator.next(); + if (obj != null) { + buf.append(obj); + } + if ((separator != null) && iterator.hasNext()) { + buf.append(separator); + } + } + return buf.toString(); + } + + // Delete + //----------------------------------------------------------------------- + /** + *

Deletes all 'space' characters from a String as defined by + * {@link Character#isSpace(char)}.

+ * + *

This is the only StringUtils method that uses the + * isSpace definition. You are advised to use + * {@link #deleteWhitespace(String)} instead as whitespace is much + * better localized.

+ * + *
+     * StringUtils.deleteSpaces(null)           = null
+     * StringUtils.deleteSpaces("")             = ""
+     * StringUtils.deleteSpaces("abc")          = "abc"
+     * StringUtils.deleteSpaces(" \t  abc \n ") = "abc"
+     * StringUtils.deleteSpaces("ab  c")        = "abc"
+     * StringUtils.deleteSpaces("a\nb\tc     ") = "abc"
+     * 
+ * + *

Spaces are defined as {' ', '\t', '\r', '\n', '\b'} + * in line with the deprecated isSpace method.

+ * + * @param str the String to delete spaces from, may be null + * @return the String without 'spaces', null if null String input + * @deprecated Use the better localized {@link #deleteWhitespace(String)}. + * Method will be removed in Commons Lang 3.0. + */ + public static String deleteSpaces(String str) { + if (str == null) { + return null; + } + return CharSetUtils.delete(str, " \t\r\n\b"); + } + + /** + *

Deletes all whitespaces from a String as defined by + * {@link Character#isWhitespace(char)}.

+ * + *
+     * StringUtils.deleteWhitespace(null)         = null
+     * StringUtils.deleteWhitespace("")           = ""
+     * StringUtils.deleteWhitespace("abc")        = "abc"
+     * StringUtils.deleteWhitespace("   ab  c  ") = "abc"
+     * 
+ * + * @param str the String to delete whitespace from, may be null + * @return the String without whitespaces, null if null String input + */ + public static String deleteWhitespace(String str) { + if (str == null) { + return null; + } + int sz = str.length(); + StringBuffer buffer = new StringBuffer(sz); + for (int i = 0; i < sz; i++) { + if (!Character.isWhitespace(str.charAt(i))) { + buffer.append(str.charAt(i)); + } + } + return buffer.toString(); + } + + // Replacing + //----------------------------------------------------------------------- + /** + *

Replaces a String with another String inside a larger String, once.

+ * + *

A null reference passed to this method is a no-op.

+ * + *
+     * StringUtils.replaceOnce(null, *, *)        = null
+     * StringUtils.replaceOnce("", *, *)          = ""
+     * StringUtils.replaceOnce("aba", null, null) = "aba"
+     * StringUtils.replaceOnce("aba", null, null) = "aba"
+     * StringUtils.replaceOnce("aba", "a", null)  = "aba"
+     * StringUtils.replaceOnce("aba", "a", "")    = "aba"
+     * StringUtils.replaceOnce("aba", "a", "z")   = "zba"
+     * 
+ * + * @see #replace(String text, String repl, String with, int max) + * @param text text to search and replace in, may be null + * @param repl the String to search for, may be null + * @param with the String to replace with, may be null + * @return the text with any replacements processed, + * null if null String input + */ + public static String replaceOnce(String text, String repl, String with) { + return replace(text, repl, with, 1); + } + + /** + *

Replaces all occurances of a String within another String.

+ * + *

A null reference passed to this method is a no-op.

+ * + *
+     * StringUtils.replace(null, *, *)        = null
+     * StringUtils.replace("", *, *)          = ""
+     * StringUtils.replace("aba", null, null) = "aba"
+     * StringUtils.replace("aba", null, null) = "aba"
+     * StringUtils.replace("aba", "a", null)  = "aba"
+     * StringUtils.replace("aba", "a", "")    = "aba"
+     * StringUtils.replace("aba", "a", "z")   = "zbz"
+     * 
+ * + * @see #replace(String text, String repl, String with, int max) + * @param text text to search and replace in, may be null + * @param repl the String to search for, may be null + * @param with the String to replace with, may be null + * @return the text with any replacements processed, + * null if null String input + */ + public static String replace(String text, String repl, String with) { + return replace(text, repl, with, -1); + } + + /** + *

Replaces a String with another String inside a larger String, + * for the first max values of the search String.

+ * + *

A null reference passed to this method is a no-op.

+ * + *
+     * StringUtils.replace(null, *, *, *)         = null
+     * StringUtils.replace("", *, *, *)           = ""
+     * StringUtils.replace("abaa", null, null, 1) = "abaa"
+     * StringUtils.replace("abaa", null, null, 1) = "abaa"
+     * StringUtils.replace("abaa", "a", null, 1)  = "abaa"
+     * StringUtils.replace("abaa", "a", "", 1)    = "abaa"
+     * StringUtils.replace("abaa", "a", "z", 0)   = "abaa"
+     * StringUtils.replace("abaa", "a", "z", 1)   = "zbaa"
+     * StringUtils.replace("abaa", "a", "z", 2)   = "zbza"
+     * StringUtils.replace("abaa", "a", "z", -1)  = "zbzz"
+     * 
+ * + * @param text text to search and replace in, may be null + * @param repl the String to search for, may be null + * @param with the String to replace with, may be null + * @param max maximum number of values to replace, or -1 if no maximum + * @return the text with any replacements processed, + * null if null String input + */ + public static String replace(String text, String repl, String with, int max) { + if (text == null || repl == null || with == null || repl.length() == 0 || max == 0) { + return text; + } + + StringBuffer buf = new StringBuffer(text.length()); + int start = 0, end = 0; + while ((end = text.indexOf(repl, start)) != -1) { + buf.append(text.substring(start, end)).append(with); + start = end + repl.length(); + + if (--max == 0) { + break; + } + } + buf.append(text.substring(start)); + return buf.toString(); + } + + // Replace, character based + //----------------------------------------------------------------------- + /** + *

Replaces all occurrances of a character in a String with another. + * This is a null-safe version of {@link String#replace(char, char)}.

+ * + *

A null string input returns null. + * An empty ("") string input returns an empty string.

+ * + *
+     * StringUtils.replaceChars(null, *, *)        = null
+     * StringUtils.replaceChars("", *, *)          = ""
+     * StringUtils.replaceChars("abcba", 'b', 'y') = "aycya"
+     * StringUtils.replaceChars("abcba", 'z', 'y') = "abcba"
+     * 
+ * + * @param str String to replace characters in, may be null + * @param searchChar the character to search for, may be null + * @param replaceChar the character to replace, may be null + * @return modified String, null if null string input + * @since 2.0 + */ + public static String replaceChars(String str, char searchChar, char replaceChar) { + if (str == null) { + return null; + } + return str.replace(searchChar, replaceChar); + } + + /** + *

Replaces multiple characters in a String in one go. + * This method can also be used to delete characters.

+ * + *

For example:
+ * replaceChars("hello", "ho", "jy") = jelly.

+ * + *

A null string input returns null. + * An empty ("") string input returns an empty string. + * A null or empty set of search characters returns the input string.

+ * + *

The length of the search characters should normally equal the length + * of the replace characters. + * If the search characters is longer, then the extra search characters + * are deleted. + * If the search characters is shorter, then the extra replace characters + * are ignored.

+ * + *
+     * StringUtils.replaceChars(null, *, *)           = null
+     * StringUtils.replaceChars("", *, *)             = ""
+     * StringUtils.replaceChars("abc", null, *)       = "abc"
+     * StringUtils.replaceChars("abc", "", *)         = "abc"
+     * StringUtils.replaceChars("abc", "b", null)     = "ac"
+     * StringUtils.replaceChars("abc", "b", "")       = "ac"
+     * StringUtils.replaceChars("abcba", "bc", "yz")  = "ayzya"
+     * StringUtils.replaceChars("abcba", "bc", "y")   = "ayya"
+     * StringUtils.replaceChars("abcba", "bc", "yzx") = "ayzya"
+     * 
+ * + * @param str String to replace characters in, may be null + * @param searchChars a set of characters to search for, may be null + * @param replaceChars a set of characters to replace, may be null + * @return modified String, null if null string input + * @since 2.0 + */ + public static String replaceChars(String str, String searchChars, String replaceChars) { + if (str == null || str.length() == 0 || searchChars == null || searchChars.length()== 0) { + return str; + } + char[] chars = str.toCharArray(); + int len = chars.length; + boolean modified = false; + for (int i = 0, isize = searchChars.length(); i < isize; i++) { + char searchChar = searchChars.charAt(i); + if (replaceChars == null || i >= replaceChars.length()) { + // delete + int pos = 0; + for (int j = 0; j < len; j++) { + if (chars[j] != searchChar) { + chars[pos++] = chars[j]; + } else { + modified = true; + } + } + len = pos; + } else { + // replace + for (int j = 0; j < len; j++) { + if (chars[j] == searchChar) { + chars[j] = replaceChars.charAt(i); + modified = true; + } + } + } + } + if (modified == false) { + return str; + } + return new String(chars, 0, len); + } + + // Overlay + //----------------------------------------------------------------------- + /** + *

Overlays part of a String with another String.

+ * + *
+     * StringUtils.overlayString(null, *, *, *)           = NullPointerException
+     * StringUtils.overlayString(*, null, *, *)           = NullPointerException
+     * StringUtils.overlayString("", "abc", 0, 0)         = "abc"
+     * StringUtils.overlayString("abcdef", null, 2, 4)    = "abef"
+     * StringUtils.overlayString("abcdef", "", 2, 4)      = "abef"
+     * StringUtils.overlayString("abcdef", "zzzz", 2, 4)  = "abzzzzef"
+     * StringUtils.overlayString("abcdef", "zzzz", 4, 2)  = "abcdzzzzcdef"
+     * StringUtils.overlayString("abcdef", "zzzz", -1, 4) = IndexOutOfBoundsException
+     * StringUtils.overlayString("abcdef", "zzzz", 2, 8)  = IndexOutOfBoundsException
+     * 
+ * + * @param text the String to do overlaying in, may be null + * @param overlay the String to overlay, may be null + * @param start the position to start overlaying at, must be valid + * @param end the position to stop overlaying before, must be valid + * @return overlayed String, null if null String input + * @throws NullPointerException if text or overlay is null + * @throws IndexOutOfBoundsException if either position is invalid + * @deprecated Use better named {@link #overlay(String, String, int, int)} instead. + * Method will be removed in Commons Lang 3.0. + */ + public static String overlayString(String text, String overlay, int start, int end) { + return new StringBuffer(start + overlay.length() + text.length() - end + 1) + .append(text.substring(0, start)) + .append(overlay) + .append(text.substring(end)) + .toString(); + } + + /** + *

Overlays part of a String with another String.

+ * + *

A null string input returns null. + * A negative index is treated as zero. + * An index greater than the string length is treated as the string length. + * The start index is always the smaller of the two indices.

+ * + *
+     * StringUtils.overlay(null, *, *, *)            = null
+     * StringUtils.overlay("", "abc", 0, 0)          = "abc"
+     * StringUtils.overlay("abcdef", null, 2, 4)     = "abef"
+     * StringUtils.overlay("abcdef", "", 2, 4)       = "abef"
+     * StringUtils.overlay("abcdef", "", 4, 2)       = "abef"
+     * StringUtils.overlay("abcdef", "zzzz", 2, 4)   = "abzzzzef"
+     * StringUtils.overlay("abcdef", "zzzz", 4, 2)   = "abzzzzef"
+     * StringUtils.overlay("abcdef", "zzzz", -1, 4)  = "zzzzef"
+     * StringUtils.overlay("abcdef", "zzzz", 2, 8)   = "abzzzz"
+     * StringUtils.overlay("abcdef", "zzzz", -2, -3) = "zzzzabcdef"
+     * StringUtils.overlay("abcdef", "zzzz", 8, 10)  = "abcdefzzzz"
+     * 
+ * + * @param str the String to do overlaying in, may be null + * @param overlay the String to overlay, may be null + * @param start the position to start overlaying at + * @param end the position to stop overlaying before + * @return overlayed String, null if null String input + * @since 2.0 + */ + public static String overlay(String str, String overlay, int start, int end) { + if (str == null) { + return null; + } + if (overlay == null) { + overlay = EMPTY; + } + int len = str.length(); + if (start < 0) { + start = 0; + } + if (start > len) { + start = len; + } + if (end < 0) { + end = 0; + } + if (end > len) { + end = len; + } + if (start > end) { + int temp = start; + start = end; + end = temp; + } + return new StringBuffer(len + start - end + overlay.length() + 1) + .append(str.substring(0, start)) + .append(overlay) + .append(str.substring(end)) + .toString(); + } + + // Chomping + //----------------------------------------------------------------------- + /** + *

Removes one newline from end of a String if it's there, + * otherwise leave it alone. A newline is "\n", + * "\r", or "\r\n".

+ * + *

NOTE: This method changed in 2.0. + * It now more closely matches Perl chomp.

+ * + *
+     * StringUtils.chomp(null)          = null
+     * StringUtils.chomp("")            = ""
+     * StringUtils.chomp("abc \r")      = "abc "
+     * StringUtils.chomp("abc\n")       = "abc"
+     * StringUtils.chomp("abc\r\n")     = "abc"
+     * StringUtils.chomp("abc\r\n\r\n") = "abc\r\n"
+     * StringUtils.chomp("abc\n\r")     = "abc\n"
+     * StringUtils.chomp("abc\n\rabc")  = "abc\n\rabc"
+     * StringUtils.chomp("\r")          = ""
+     * StringUtils.chomp("\n")          = ""
+     * StringUtils.chomp("\r\n")        = ""
+     * 
+ * + * @param str the String to chomp a newline from, may be null + * @return String without newline, null if null String input + */ + public static String chomp(String str) { + if (str == null || str.length() == 0) { + return str; + } + + if (str.length() == 1) { + char ch = str.charAt(0); + if (ch == '\r' || ch == '\n') { + return EMPTY; + } else { + return str; + } + } + + int lastIdx = str.length() - 1; + char last = str.charAt(lastIdx); + + if (last == '\n') { + if (str.charAt(lastIdx - 1) == '\r') { + lastIdx--; + } + } else if (last == '\r') { + + } else { + lastIdx++; + } + return str.substring(0, lastIdx); + } + + /** + *

Removes separator from the end of + * str if it's there, otherwise leave it alone.

+ * + *

NOTE: This method changed in version 2.0. + * It now more closely matches Perl chomp. + * For the previous behavior, use {@link #substringBeforeLast(String, String)}. + * This method uses {@link String#endsWith(String)}.

+ * + *
+     * StringUtils.chomp(null, *)         = null
+     * StringUtils.chomp("", *)           = ""
+     * StringUtils.chomp("foobar", "bar") = "foo"
+     * StringUtils.chomp("foobar", "baz") = "foobar"
+     * StringUtils.chomp("foo", "foo")    = ""
+     * StringUtils.chomp("foo ", "foo")   = "foo"
+     * StringUtils.chomp(" foo", "foo")   = " "
+     * StringUtils.chomp("foo", "foooo")  = "foo"
+     * StringUtils.chomp("foo", "")       = "foo"
+     * StringUtils.chomp("foo", null)     = "foo"
+     * 
+ * + * @param str the String to chomp from, may be null + * @param separator separator String, may be null + * @return String without trailing separator, null if null String input + */ + public static String chomp(String str, String separator) { + if (str == null || str.length() == 0 || separator == null) { + return str; + } + if (str.endsWith(separator)) { + return str.substring(0, str.length() - separator.length()); + } + return str; + } + + /** + *

Remove any "\n" if and only if it is at the end + * of the supplied String.

+ * + * @param str the String to chomp from, must not be null + * @return String without chomped ending + * @throws NullPointerException if str is null + * @deprecated Use {@link #chomp(String)} instead. + * Method will be removed in Commons Lang 3.0. + */ + public static String chompLast(String str) { + return chompLast(str, "\n"); + } + + /** + *

Remove a value if and only if the String ends with that value.

+ * + * @param str the String to chomp from, must not be null + * @param sep the String to chomp, must not be null + * @return String without chomped ending + * @throws NullPointerException if str or sep is null + * @deprecated Use {@link #chomp(String,String)} instead. + * Method will be removed in Commons Lang 3.0. + */ + public static String chompLast(String str, String sep) { + if (str.length() == 0) { + return str; + } + String sub = str.substring(str.length() - sep.length()); + if (sep.equals(sub)) { + return str.substring(0, str.length() - sep.length()); + } else { + return str; + } + } + + /** + *

Remove everything and return the last value of a supplied String, and + * everything after it from a String.

+ * + * @param str the String to chomp from, must not be null + * @param sep the String to chomp, must not be null + * @return String chomped + * @throws NullPointerException if str or sep is null + * @deprecated Use {@link #substringAfterLast(String, String)} instead + * (although this doesn't include the separator) + * Method will be removed in Commons Lang 3.0. + */ + public static String getChomp(String str, String sep) { + int idx = str.lastIndexOf(sep); + if (idx == str.length() - sep.length()) { + return sep; + } else if (idx != -1) { + return str.substring(idx); + } else { + return EMPTY; + } + } + + /** + *

Remove the first value of a supplied String, and everything before it + * from a String.

+ * + * @param str the String to chomp from, must not be null + * @param sep the String to chomp, must not be null + * @return String without chomped beginning + * @throws NullPointerException if str or sep is null + * @deprecated Use {@link #substringAfter(String,String)} instead. + * Method will be removed in Commons Lang 3.0. + */ + public static String prechomp(String str, String sep) { + int idx = str.indexOf(sep); + if (idx != -1) { + return str.substring(idx + sep.length()); + } else { + return str; + } + } + + /** + *

Remove and return everything before the first value of a + * supplied String from another String.

+ * + * @param str the String to chomp from, must not be null + * @param sep the String to chomp, must not be null + * @return String prechomped + * @throws NullPointerException if str or sep is null + * @deprecated Use {@link #substringBefore(String,String)} instead + * (although this doesn't include the separator). + * Method will be removed in Commons Lang 3.0. + */ + public static String getPrechomp(String str, String sep) { + int idx = str.indexOf(sep); + if (idx != -1) { + return str.substring(0, idx + sep.length()); + } else { + return EMPTY; + } + } + + // Chopping + //----------------------------------------------------------------------- + /** + *

Remove the last character from a String.

+ * + *

If the String ends in \r\n, then remove both + * of them.

+ * + *
+     * StringUtils.chop(null)          = null
+     * StringUtils.chop("")            = ""
+     * StringUtils.chop("abc \r")      = "abc "
+     * StringUtils.chop("abc\n")       = "abc"
+     * StringUtils.chop("abc\r\n")     = "abc"
+     * StringUtils.chop("abc")         = "ab"
+     * StringUtils.chop("abc\nabc")    = "abc\nab"
+     * StringUtils.chop("a")           = ""
+     * StringUtils.chop("\r")          = ""
+     * StringUtils.chop("\n")          = ""
+     * StringUtils.chop("\r\n")        = ""
+     * 
+ * + * @param str the String to chop last character from, may be null + * @return String without last character, null if null String input + */ + public static String chop(String str) { + if (str == null) { + return null; + } + int strLen = str.length(); + if (strLen < 2) { + return EMPTY; + } + int lastIdx = strLen - 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; + } + + /** + *

Removes \n from end of a String if it's there. + * If a \r precedes it, then remove that too.

+ * + * @param str the String to chop a newline from, must not be null + * @return String without newline + * @throws NullPointerException if str is null + * @deprecated Use {@link #chomp(String)} instead. + * Method will be removed in Commons Lang 3.0. + */ + public static String chopNewline(String str) { + int lastIdx = str.length() - 1; + if (lastIdx <= 0) { + return EMPTY; + } + char last = str.charAt(lastIdx); + if (last == '\n') { + if (str.charAt(lastIdx - 1) == '\r') { + lastIdx--; + } + } else { + lastIdx++; + } + return str.substring(0, lastIdx); + } + + + // Conversion + //----------------------------------------------------------------------- + /** + *

Escapes any values it finds into their String form.

+ * + *

So a tab becomes the characters '\\' and + * 't'.

+ * + *

As of Lang 2.0, this calls {@link StringEscapeUtils#escapeJava(String)} + * behind the scenes. + *

+ * @see StringEscapeUtils#escapeJava(java.lang.String) + * @param str String to escape values in + * @return String with escaped values + * @throws NullPointerException if str is null + * @deprecated Use {@link StringEscapeUtils#escapeJava(String)} + * This method will be removed in Commons Lang 3.0 + */ + public static String escape(String str) { + return StringEscapeUtils.escapeJava(str); + } + + // Padding + //----------------------------------------------------------------------- + /** + *

Repeat a String repeat times to form a + * new String.

+ * + *
+     * StringUtils.repeat(null, 2) = null
+     * StringUtils.repeat("", 0)   = ""
+     * StringUtils.repeat("", 2)   = ""
+     * StringUtils.repeat("a", 3)  = "aaa"
+     * StringUtils.repeat("ab", 2) = "abab"
+     * StringUtils.repeat("a", -2) = ""
+     * 
+ * + * @param str the String to repeat, may be null + * @param repeat number of times to repeat str, negative treated as zero + * @return a new String consisting of the original String repeated, + * null if null String input + */ + public static String repeat(String str, int repeat) { + // Performance tuned for 2.0 (JDK1.4) + + if (str == null) { + return null; + } + if (repeat <= 0) { + return EMPTY; + } + int inputLength = str.length(); + if (repeat == 1 || inputLength == 0) { + return str; + } + if (inputLength == 1 && repeat <= PAD_LIMIT) { + return padding(repeat, str.charAt(0)); + } + + int outputLength = inputLength * repeat; + switch (inputLength) { + case 1: + char ch = str.charAt(0); + char[] output1 = new char[outputLength]; + for (int i = repeat - 1; i >= 0; i--) { + output1[i] = ch; + } + return new String(output1); + case 2: + char ch0 = str.charAt(0); + char ch1 = str.charAt(1); + char[] output2 = new char[outputLength]; + for (int i = repeat * 2 - 2; i >= 0; i--,i--) { + output2[i] = ch0; + output2[i + 1] = ch1; + } + return new String(output2); + default: + StringBuffer buf = new StringBuffer(outputLength); + for (int i = 0; i < repeat; i++) { + buf.append(str); + } + return buf.toString(); + } + } + + /** + *

Returns padding using the specified delimiter repeated + * to a given length.

+ * + *
+     * StringUtils.padding(0, 'e')  = ""
+     * StringUtils.padding(3, 'e')  = "eee"
+     * StringUtils.padding(-2, 'e') = IndexOutOfBoundsException
+     * 
+ * + * @param repeat number of times to repeat delim + * @param padChar character to repeat + * @return String with repeated character + * @throws IndexOutOfBoundsException if repeat < 0 + */ + private static String padding(int repeat, char padChar) { + // be careful of synchronization in this method + // we are assuming that get and set from an array index is atomic + String pad = PADDING[padChar]; + if (pad == null) { + pad = String.valueOf(padChar); + } + while (pad.length() < repeat) { + pad = pad.concat(pad); + } + PADDING[padChar] = pad; + return pad.substring(0, repeat); + } + + /** + *

Right pad a String with spaces (' ').

+ * + *

The String is padded to the size of size.

+ * + *
+     * StringUtils.rightPad(null, *)   = null
+     * StringUtils.rightPad("", 3)     = "   "
+     * StringUtils.rightPad("bat", 3)  = "bat"
+     * StringUtils.rightPad("bat", 5)  = "bat  "
+     * StringUtils.rightPad("bat", 1)  = "bat"
+     * StringUtils.rightPad("bat", -1) = "bat"
+     * 
+ * + * @param str the String to pad out, may be null + * @param size the size to pad to + * @return right padded String or original String if no padding is necessary, + * null if null String input + */ + public static String rightPad(String str, int size) { + return rightPad(str, size, ' '); + } + + /** + *

Right pad a String with a specified character.

+ * + *

The String is padded to the size of size.

+ * + *
+     * StringUtils.rightPad(null, *, *)     = null
+     * StringUtils.rightPad("", 3, 'z')     = "zzz"
+     * StringUtils.rightPad("bat", 3, 'z')  = "bat"
+     * StringUtils.rightPad("bat", 5, 'z')  = "batzz"
+     * StringUtils.rightPad("bat", 1, 'z')  = "bat"
+     * StringUtils.rightPad("bat", -1, 'z') = "bat"
+     * 
+ * + * @param str the String to pad out, may be null + * @param size the size to pad to + * @param padChar the character to pad with + * @return right padded String or original String if no padding is necessary, + * null if null String input + * @since 2.0 + */ + public static String rightPad(String str, int size, char padChar) { + if (str == null) { + return null; + } + int pads = size - str.length(); + if (pads <= 0) { + return str; // returns original String when possible + } + if (pads > PAD_LIMIT) { + return rightPad(str, size, String.valueOf(padChar)); + } + return str.concat(padding(pads, padChar)); + } + + /** + *

Right pad a String with a specified String.

+ * + *

The String is padded to the size of size.

+ * + *
+     * StringUtils.rightPad(null, *, *)      = null
+     * StringUtils.rightPad("", 3, "z")      = "zzz"
+     * StringUtils.rightPad("bat", 3, "yz")  = "bat"
+     * StringUtils.rightPad("bat", 5, "yz")  = "batyz"
+     * StringUtils.rightPad("bat", 8, "yz")  = "batyzyzy"
+     * StringUtils.rightPad("bat", 1, "yz")  = "bat"
+     * StringUtils.rightPad("bat", -1, "yz") = "bat"
+     * StringUtils.rightPad("bat", 5, null)  = "bat  "
+     * StringUtils.rightPad("bat", 5, "")    = "bat  "
+     * 
+ * + * @param str the String to pad out, may be null + * @param size the size to pad to + * @param padStr the String to pad with, null or empty treated as single space + * @return right padded String or original String if no padding is necessary, + * null if null String input + */ + public static String rightPad(String str, int size, String padStr) { + if (str == null) { + return null; + } + if (padStr == null || padStr.length() == 0) { + padStr = " "; + } + int padLen = padStr.length(); + int strLen = str.length(); + int pads = size - strLen; + if (pads <= 0) { + return str; // returns original String when possible + } + if (padLen == 1 && pads <= PAD_LIMIT) { + return rightPad(str, size, padStr.charAt(0)); + } + + if (pads == padLen) { + return str.concat(padStr); + } else if (pads < padLen) { + return str.concat(padStr.substring(0, pads)); + } else { + char[] padding = new char[pads]; + char[] padChars = padStr.toCharArray(); + for (int i = 0; i < pads; i++) { + padding[i] = padChars[i % padLen]; + } + return str.concat(new String(padding)); + } + } + + /** + *

Left pad a String with spaces (' ').

+ * + *

The String is padded to the size of size.

+ * + *
+     * StringUtils.leftPad(null, *)   = null
+     * StringUtils.leftPad("", 3)     = "   "
+     * StringUtils.leftPad("bat", 3)  = "bat"
+     * StringUtils.leftPad("bat", 5)  = "  bat"
+     * StringUtils.leftPad("bat", 1)  = "bat"
+     * StringUtils.leftPad("bat", -1) = "bat"
+     * 
+ * + * @param str the String to pad out, may be null + * @param size the size to pad to + * @return left padded String or original String if no padding is necessary, + * null if null String input + */ + public static String leftPad(String str, int size) { + return leftPad(str, size, ' '); + } + + /** + *

Left pad a String with a specified character.

+ * + *

Pad to a size of size.

+ * + *
+     * StringUtils.leftPad(null, *, *)     = null
+     * StringUtils.leftPad("", 3, 'z')     = "zzz"
+     * StringUtils.leftPad("bat", 3, 'z')  = "bat"
+     * StringUtils.leftPad("bat", 5, 'z')  = "zzbat"
+     * StringUtils.leftPad("bat", 1, 'z')  = "bat"
+     * StringUtils.leftPad("bat", -1, 'z') = "bat"
+     * 
+ * + * @param str the String to pad out, may be null + * @param size the size to pad to + * @param padChar the character to pad with + * @return left padded String or original String if no padding is necessary, + * null if null String input + * @since 2.0 + */ + public static String leftPad(String str, int size, char padChar) { + if (str == null) { + return null; + } + int pads = size - str.length(); + if (pads <= 0) { + return str; // returns original String when possible + } + if (pads > PAD_LIMIT) { + return leftPad(str, size, String.valueOf(padChar)); + } + return padding(pads, padChar).concat(str); + } + + /** + *

Left pad a String with a specified String.

+ * + *

Pad to a size of size.

+ * + *
+     * StringUtils.leftPad(null, *, *)      = null
+     * StringUtils.leftPad("", 3, "z")      = "zzz"
+     * StringUtils.leftPad("bat", 3, "yz")  = "bat"
+     * StringUtils.leftPad("bat", 5, "yz")  = "yzbat"
+     * StringUtils.leftPad("bat", 8, "yz")  = "yzyzybat"
+     * StringUtils.leftPad("bat", 1, "yz")  = "bat"
+     * StringUtils.leftPad("bat", -1, "yz") = "bat"
+     * StringUtils.leftPad("bat", 5, null)  = "  bat"
+     * StringUtils.leftPad("bat", 5, "")    = "  bat"
+     * 
+ * + * @param str the String to pad out, may be null + * @param size the size to pad to + * @param padStr the String to pad with, null or empty treated as single space + * @return left padded String or original String if no padding is necessary, + * null if null String input + */ + public static String leftPad(String str, int size, String padStr) { + if (str == null) { + return null; + } + if (padStr == null || padStr.length() == 0) { + padStr = " "; + } + int padLen = padStr.length(); + int strLen = str.length(); + int pads = size - strLen; + if (pads <= 0) { + return str; // returns original String when possible + } + if (padLen == 1 && pads <= PAD_LIMIT) { + return leftPad(str, size, padStr.charAt(0)); + } + + if (pads == padLen) { + return padStr.concat(str); + } else if (pads < padLen) { + return padStr.substring(0, pads).concat(str); + } else { + char[] padding = new char[pads]; + char[] padChars = padStr.toCharArray(); + for (int i = 0; i < pads; i++) { + padding[i] = padChars[i % padLen]; + } + return new String(padding).concat(str); + } + } + + // Centering + //----------------------------------------------------------------------- + /** + *

Centers a String in a larger String of size size + * using the space character (' ').

+ * + *

If the size is less than the String length, the String is returned. + * A null String returns null. + * A negative size is treated as zero.

+ * + *

Equivalent to center(str, size, " ").

+ * + *
+     * StringUtils.center(null, *)   = null
+     * StringUtils.center("", 4)     = "    "
+     * StringUtils.center("ab", -1)  = "ab"
+     * StringUtils.center("ab", 4)   = " ab "
+     * StringUtils.center("abcd", 2) = "abcd"
+     * StringUtils.center("a", 4)    = " a  "
+     * 
+ * + * @param str the String to center, may be null + * @param size the int size of new String, negative treated as zero + * @return centered String, null if null String input + */ + public static String center(String str, int size) { + return center(str, size, ' '); + } + + /** + *

Centers a String in a larger String of size size. + * Uses a supplied character as the value to pad the String with.

+ * + *

If the size is less than the String length, the String is returned. + * A null String returns null. + * A negative size is treated as zero.

+ * + *
+     * StringUtils.center(null, *, *)     = null
+     * StringUtils.center("", 4, ' ')     = "    "
+     * StringUtils.center("ab", -1, ' ')  = "ab"
+     * StringUtils.center("ab", 4, ' ')   = " ab"
+     * StringUtils.center("abcd", 2, ' ') = "abcd"
+     * StringUtils.center("a", 4, ' ')    = " a  "
+     * StringUtils.center("a", 4, 'y')    = "yayy"
+     * 
+ * + * @param str the String to center, may be null + * @param size the int size of new String, negative treated as zero + * @param padChar the character to pad the new String with + * @return centered String, null if null String input + * @since 2.0 + */ + public static String center(String str, int size, char padChar) { + if (str == null || size <= 0) { + return str; + } + int strLen = str.length(); + int pads = size - strLen; + if (pads <= 0) { + return str; + } + str = leftPad(str, strLen + pads / 2, padChar); + str = rightPad(str, size, padChar); + return str; + } + + /** + *

Centers a String in a larger String of size size. + * Uses a supplied String as the value to pad the String with.

+ * + *

If the size is less than the String length, the String is returned. + * A null String returns null. + * A negative size is treated as zero.

+ * + *
+     * StringUtils.center(null, *, *)     = null
+     * StringUtils.center("", 4, " ")     = "    "
+     * StringUtils.center("ab", -1, " ")  = "ab"
+     * StringUtils.center("ab", 4, " ")   = " ab"
+     * StringUtils.center("abcd", 2, " ") = "abcd"
+     * StringUtils.center("a", 4, " ")    = " a  "
+     * StringUtils.center("a", 4, "yz")   = "yayz"
+     * StringUtils.center("abc", 7, null) = "  abc  "
+     * StringUtils.center("abc", 7, "")   = "  abc  "
+     * 
+ * + * @param str the String to center, may be null + * @param size the int size of new String, negative treated as zero + * @param padStr the String to pad the new String with, must not be null or empty + * @return centered String, null if null String input + * @throws IllegalArgumentException if padStr is null or empty + */ + public static String center(String str, int size, String padStr) { + if (str == null || size <= 0) { + return str; + } + if (padStr == null || padStr.length() == 0) { + padStr = " "; + } + int strLen = str.length(); + int pads = size - strLen; + if (pads <= 0) { + return str; + } + str = leftPad(str, strLen + pads / 2, padStr); + str = rightPad(str, size, padStr); + return str; + } + + // Case conversion + //----------------------------------------------------------------------- + /** + *

Converts a String to upper case as per {@link String#toUpperCase()}.

+ * + *

A null input String returns null.

+ * + *
+     * StringUtils.upperCase(null)  = null
+     * StringUtils.upperCase("")    = ""
+     * StringUtils.upperCase("aBc") = "ABC"
+     * 
+ * + * @param str the String to upper case, may be null + * @return the upper cased String, null if null String input + */ + public static String upperCase(String str) { + if (str == null) { + return null; + } + return str.toUpperCase(); + } + + /** + *

Converts a String to lower case as per {@link String#toLowerCase()}.

+ * + *

A null input String returns null.

+ * + *
+     * StringUtils.lowerCase(null)  = null
+     * StringUtils.lowerCase("")    = ""
+     * StringUtils.lowerCase("aBc") = "abc"
+     * 
+ * + * @param str the String to lower case, may be null + * @return the lower cased String, null if null String input + */ + public static String lowerCase(String str) { + if (str == null) { + return null; + } + return str.toLowerCase(); + } + + /** + *

Capitalizes a String changing the first letter to title case as + * per {@link Character#toTitleCase(char)}. No other letters are changed.

+ * + *

For a word based alorithm, see {@link WordUtils#capitalize(String)}. + * A null input String returns null.

+ * + *
+     * StringUtils.capitalize(null)  = null
+     * StringUtils.capitalize("")    = ""
+     * StringUtils.capitalize("cat") = "Cat"
+     * StringUtils.capitalize("cAt") = "CAt"
+     * 
+ * + * @param str the String to capitalize, may be null + * @return the capitalized String, null if null String input + * @see WordUtils#capitalize(String) + * @see #uncapitalize(String) + * @since 2.0 + */ + public static String capitalize(String str) { + int strLen; + if (str == null || (strLen = str.length()) == 0) { + return str; + } + return new StringBuffer(strLen) + .append(Character.toTitleCase(str.charAt(0))) + .append(str.substring(1)) + .toString(); + } + + /** + *

Capitalizes a String changing the first letter to title case as + * per {@link Character#toTitleCase(char)}. No other letters are changed.

+ * + * @param str the String to capitalize, may be null + * @return the capitalized String, null if null String input + * @deprecated Use the standardly named {@link #capitalize(String)}. + * Method will be removed in Commons Lang 3.0. + */ + public static String capitalise(String str) { + return capitalize(str); + } + + /** + *

Uncapitalizes a String changing the first letter to title case as + * per {@link Character#toLowerCase(char)}. No other letters are changed.

+ * + *

For a word based alorithm, see {@link WordUtils#uncapitalize(String)}. + * A null input String returns null.

+ * + *
+     * StringUtils.uncapitalize(null)  = null
+     * StringUtils.uncapitalize("")    = ""
+     * StringUtils.uncapitalize("Cat") = "cat"
+     * StringUtils.uncapitalize("CAT") = "cAT"
+     * 
+ * + * @param str the String to uncapitalize, may be null + * @return the uncapitalized String, null if null String input + * @see WordUtils#uncapitalize(String) + * @see #capitalize(String) + * @since 2.0 + */ + public static String uncapitalize(String str) { + int strLen; + if (str == null || (strLen = str.length()) == 0) { + return str; + } + return new StringBuffer(strLen) + .append(Character.toLowerCase(str.charAt(0))) + .append(str.substring(1)) + .toString(); + } + + /** + *

Uncapitalizes a String changing the first letter to title case as + * per {@link Character#toLowerCase(char)}. No other letters are changed.

+ * + * @param str the String to uncapitalize, may be null + * @return the uncapitalized String, null if null String input + * @deprecated Use the standardly named {@link #uncapitalize(String)}. + * Method will be removed in Commons Lang 3.0. + */ + public static String uncapitalise(String str) { + return uncapitalize(str); + } + + /** + *

Swaps the case of a String changing upper and title case to + * lower case, and lower case to upper case.

+ * + *
    + *
  • Upper case character converts to Lower case
  • + *
  • Title case character converts to Lower case
  • + *
  • Lower case character converts to Upper case
  • + *
+ * + *

For a word based alorithm, see {@link WordUtils#swapCase(String)}. + * A null input String returns null.

+ * + *
+     * StringUtils.swapCase(null)                 = null
+     * StringUtils.swapCase("")                   = ""
+     * StringUtils.swapCase("The dog has a BONE") = "tHE DOG HAS A bone"
+     * 
+ * + *

NOTE: This method changed in Lang version 2.0. + * It no longer performs a word based alorithm. + * If you only use ASCII, you will notice no change. + * That functionality is available in WordUtils.

+ * + * @param str the String to swap case, may be null + * @return the changed String, null if null String input + */ + public static String swapCase(String str) { + int strLen; + if (str == null || (strLen = str.length()) == 0) { + return str; + } + StringBuffer buffer = new StringBuffer(strLen); + + char ch = 0; + for (int i = 0; i < strLen; i++) { + ch = str.charAt(i); + if (Character.isUpperCase(ch)) { + ch = Character.toLowerCase(ch); + } else if (Character.isTitleCase(ch)) { + ch = Character.toLowerCase(ch); + } else if (Character.isLowerCase(ch)) { + ch = Character.toUpperCase(ch); + } + buffer.append(ch); + } + return buffer.toString(); + } + + /** + *

Capitalizes all the whitespace separated words in a String. + * Only the first letter of each word is changed.

+ * + *

Whitespace is defined by {@link Character#isWhitespace(char)}. + * A null input String returns null.

+ * + * @param str the String to capitalize, may be null + * @return capitalized String, null if null String input + * @deprecated Use the relocated {@link WordUtils#capitalize(String)}. + * Method will be removed in Commons Lang 3.0. + */ + public static String capitaliseAllWords(String str) { + return WordUtils.capitalize(str); + } + + // Count matches + //----------------------------------------------------------------------- + /** + *

Counts how many times the substring appears in the larger String.

+ * + *

A null or empty ("") String input returns 0.

+ * + *
+     * StringUtils.countMatches(null, *)       = 0
+     * StringUtils.countMatches("", *)         = 0
+     * StringUtils.countMatches("abba", null)  = 0
+     * StringUtils.countMatches("abba", "")    = 0
+     * StringUtils.countMatches("abba", "a")   = 2
+     * StringUtils.countMatches("abba", "ab")  = 1
+     * StringUtils.countMatches("abba", "xxx") = 0
+     * 
+ * + * @param str the String to check, may be null + * @param sub the substring to count, may be null + * @return the number of occurances, 0 if either String is null + */ + public static int countMatches(String str, String sub) { + if (str == null || str.length() == 0 || sub == null || sub.length() == 0) { + return 0; + } + int count = 0; + int idx = 0; + while ((idx = str.indexOf(sub, idx)) != -1) { + count++; + idx += sub.length(); + } + return count; + } + + // Character Tests + //----------------------------------------------------------------------- + /** + *

Checks if the String contains only unicode letters.

+ * + *

null will return false. + * An empty String ("") will return true.

+ * + *
+     * StringUtils.isAlpha(null)   = false
+     * StringUtils.isAlpha("")     = true
+     * StringUtils.isAlpha("  ")   = false
+     * StringUtils.isAlpha("abc")  = true
+     * StringUtils.isAlpha("ab2c") = false
+     * StringUtils.isAlpha("ab-c") = false
+     * 
+ * + * @param str the String to check, may be null + * @return true if only contains letters, and is non-null + */ + public static boolean isAlpha(String str) { + if (str == null) { + return false; + } + int sz = str.length(); + for (int i = 0; i < sz; i++) { + if (Character.isLetter(str.charAt(i)) == false) { + return false; + } + } + return true; + } + + /** + *

Checks if the String contains only unicode letters and + * space (' ').

+ * + *

null will return false + * An empty String ("") will return true.

+ * + *
+     * StringUtils.isAlphaSpace(null)   = false
+     * StringUtils.isAlphaSpace("")     = true
+     * StringUtils.isAlphaSpace("  ")   = true
+     * StringUtils.isAlphaSpace("abc")  = true
+     * StringUtils.isAlphaSpace("ab c") = true
+     * StringUtils.isAlphaSpace("ab2c") = false
+     * StringUtils.isAlphaSpace("ab-c") = false
+     * 
+ * + * @param str the String to check, may be null + * @return true if only contains letters and space, + * and is non-null + */ + public static boolean isAlphaSpace(String str) { + if (str == null) { + return false; + } + int sz = str.length(); + for (int i = 0; i < sz; i++) { + if ((Character.isLetter(str.charAt(i)) == false) && + (str.charAt(i) != ' ')) { + return false; + } + } + return true; + } + + /** + *

Checks if the String contains only unicode letters or digits.

+ * + *

null will return false. + * An empty String ("") will return true.

+ * + *
+     * StringUtils.isAlphanumeric(null)   = false
+     * StringUtils.isAlphanumeric("")     = true
+     * StringUtils.isAlphanumeric("  ")   = false
+     * StringUtils.isAlphanumeric("abc")  = true
+     * StringUtils.isAlphanumeric("ab c") = false
+     * StringUtils.isAlphanumeric("ab2c") = true
+     * StringUtils.isAlphanumeric("ab-c") = false
+     * 
+ * + * @param str the String to check, may be null + * @return true if only contains letters or digits, + * and is non-null + */ + public static boolean isAlphanumeric(String str) { + if (str == null) { + return false; + } + int sz = str.length(); + for (int i = 0; i < sz; i++) { + if (Character.isLetterOrDigit(str.charAt(i)) == false) { + return false; + } + } + return true; + } + + /** + *

Checks if the String contains only unicode letters, digits + * or space (' ').

+ * + *

null will return false. + * An empty String ("") will return true.

+ * + *
+     * StringUtils.isAlphanumeric(null)   = false
+     * StringUtils.isAlphanumeric("")     = true
+     * StringUtils.isAlphanumeric("  ")   = true
+     * StringUtils.isAlphanumeric("abc")  = true
+     * StringUtils.isAlphanumeric("ab c") = true
+     * StringUtils.isAlphanumeric("ab2c") = true
+     * StringUtils.isAlphanumeric("ab-c") = false
+     * 
+ * + * @param str the String to check, may be null + * @return true if only contains letters, digits or space, + * and is non-null + */ + public static boolean isAlphanumericSpace(String str) { + if (str == null) { + return false; + } + int sz = str.length(); + for (int i = 0; i < sz; i++) { + if ((Character.isLetterOrDigit(str.charAt(i)) == false) && + (str.charAt(i) != ' ')) { + return false; + } + } + return true; + } + + /** + *

Checks if the String contains only unicode digits. + * A decimal point is not a unicode digit and returns false.

+ * + *

null will return false. + * An empty String ("") will return true.

+ * + *
+     * StringUtils.isNumeric(null)   = false
+     * StringUtils.isNumeric("")     = true
+     * StringUtils.isNumeric("  ")   = false
+     * StringUtils.isNumeric("123")  = true
+     * StringUtils.isNumeric("12 3") = false
+     * StringUtils.isNumeric("ab2c") = false
+     * StringUtils.isNumeric("12-3") = false
+     * StringUtils.isNumeric("12.3") = false
+     * 
+ * + * @param str the String to check, may be null + * @return true if only contains digits, and is non-null + */ + public static boolean isNumeric(String str) { + if (str == null) { + return false; + } + int sz = str.length(); + for (int i = 0; i < sz; i++) { + if (Character.isDigit(str.charAt(i)) == false) { + return false; + } + } + return true; + } + + /** + *

Checks if the String contains only unicode digits or space + * (' '). + * A decimal point is not a unicode digit and returns false.

+ * + *

null will return false. + * An empty String ("") will return true.

+ * + *
+     * StringUtils.isNumeric(null)   = false
+     * StringUtils.isNumeric("")     = true
+     * StringUtils.isNumeric("  ")   = true
+     * StringUtils.isNumeric("123")  = true
+     * StringUtils.isNumeric("12 3") = true
+     * StringUtils.isNumeric("ab2c") = false
+     * StringUtils.isNumeric("12-3") = false
+     * StringUtils.isNumeric("12.3") = false
+     * 
+ * + * @param str the String to check, may be null + * @return true if only contains digits or space, + * and is non-null + */ + public static boolean isNumericSpace(String str) { + if (str == null) { + return false; + } + int sz = str.length(); + for (int i = 0; i < sz; i++) { + if ((Character.isDigit(str.charAt(i)) == false) && + (str.charAt(i) != ' ')) { + return false; + } + } + return true; + } + + /** + *

Checks if the String contains only whitespace.

+ * + *

null will return false. + * An empty String ("") will return true.

+ * + *
+     * StringUtils.isWhitespace(null)   = false
+     * StringUtils.isWhitespace("")     = true
+     * StringUtils.isWhitespace("  ")   = true
+     * StringUtils.isWhitespace("abc")  = false
+     * StringUtils.isWhitespace("ab2c") = false
+     * StringUtils.isWhitespace("ab-c") = false
+     * 
+ * + * @param str the String to check, may be null + * @return true if only contains whitespace, and is non-null + * @since 2.0 + */ + public static boolean isWhitespace(String str) { + if (str == null) { + return false; + } + int sz = str.length(); + for (int i = 0; i < sz; i++) { + if ((Character.isWhitespace(str.charAt(i)) == false) ) { + return false; + } + } + return true; + } + + // Defaults + //----------------------------------------------------------------------- + /** + *

Returns either the passed in String, + * or if the String is null, an empty String ("").

+ * + *
+     * StringUtils.defaultString(null)  = ""
+     * StringUtils.defaultString("")    = ""
+     * StringUtils.defaultString("bat") = "bat"
+     * 
+ * + * @see ObjectUtils#toString(Object) + * @see String#valueOf(Object) + * @param str the String to check, may be null + * @return the passed in String, or the empty String if it + * was null + */ + public static String defaultString(String str) { + return (str == null ? EMPTY : str); + } + + /** + *

Returns either the passed in String, + * or if the String is null, an empty String ("").

+ * + *
+     * StringUtils.defaultString(null, "null")  = "null"
+     * StringUtils.defaultString("", "null")    = ""
+     * StringUtils.defaultString("bat", "null") = "bat"
+     * 
+ * + * @see ObjectUtils#toString(Object,String) + * @see String#valueOf(Object) + * @param str the String to check, may be null + * @param defaultStr the default String to return + * if the input is null, may be null + * @return the passed in String, or the default if it was null + */ + public static String defaultString(String str, String defaultStr) { + return (str == null ? defaultStr : str); + } + + // Reversing + //----------------------------------------------------------------------- + /** + *

Reverses a String as per {@link StringBuffer#reverse()}.

+ * + *

null String returns null.

+ * + *
+     * StringUtils.reverse(null)  = null
+     * StringUtils.reverse("")    = ""
+     * StringUtils.reverse("bat") = "tab"
+     * 
+ * + * @param str the String to reverse, may be null + * @return the reversed String, null if null String input + */ + public static String reverse(String str) { + if (str == null) { + return null; + } + return new StringBuffer(str).reverse().toString(); + } + + /** + *

Reverses a String that is delimited by a specific character.

+ * + *

The Strings between the delimiters are not reversed. + * Thus java.lang.String becomes String.lang.java (if the delimiter + * is '.').

+ * + *
+     * StringUtils.reverseDelimited(null, *)      = null
+     * StringUtils.reverseDelimited("", *)        = ""
+     * StringUtils.reverseDelimited("a.b.c", 'x') = "a.b.c"
+     * StringUtils.reverseDelimited("a.b.c", ".") = "c.b.a"
+     * 
+ * + * @param str the String to reverse, may be null + * @param separatorChar the separator character to use + * @return the reversed String, null if null String input + * @since 2.0 + */ + public static String reverseDelimited(String str, char separatorChar) { + if (str == null) { + return null; + } + // could implement manually, but simple way is to reuse other, + // probably slower, methods. + String[] strs = split(str, separatorChar); + ArrayUtils.reverse(strs); + return join(strs, separatorChar); + } + + /** + *

Reverses a String that is delimited by a specific character.

+ * + *

The Strings between the delimiters are not reversed. + * Thus java.lang.String becomes String.lang.java (if the delimiter + * is ".").

+ * + *
+     * StringUtils.reverseDelimitedString(null, *)       = null
+     * StringUtils.reverseDelimitedString("",*)          = ""
+     * StringUtils.reverseDelimitedString("a.b.c", null) = "a.b.c"
+     * StringUtils.reverseDelimitedString("a.b.c", ".")  = "c.b.a"
+     * 
+ * + * @param str the String to reverse, may be null + * @param separatorChars the separator characters to use, null treated as whitespace + * @return the reversed String, null if null String input + * @deprecated Use {@link #reverseDelimited(String, char)} instead. + * This method is broken as the join doesn't know which char to use. + * Method will be removed in Commons Lang 3.0. + * + */ + public static String reverseDelimitedString(String str, String separatorChars) { + if (str == null) { + return null; + } + // could implement manually, but simple way is to reuse other, + // probably slower, methods. + String[] strs = split(str, separatorChars); + ArrayUtils.reverse(strs); + if (separatorChars == null) { + return join(strs, ' '); + } + return join(strs, separatorChars); + } + + // Abbreviating + //----------------------------------------------------------------------- + /** + *

Abbreviates a String using ellipses. This will turn + * "Now is the time for all good men" into "Now is the time for..."

+ * + *

Specifically: + *

    + *
  • If str is less than maxWidth characters + * long, return it.
  • + *
  • Else abbreviate it to (substring(str, 0, max-3) + "...").
  • + *
  • If maxWidth is less than 4, throw an + * IllegalArgumentException.
  • + *
  • In no case will it return a String of length greater than + * maxWidth.
  • + *
+ *

+ * + *
+     * StringUtils.abbreviate(null, *)      = null
+     * StringUtils.abbreviate("", 4)        = ""
+     * StringUtils.abbreviate("abcdefg", 6) = "abc..."
+     * StringUtils.abbreviate("abcdefg", 7) = "abcdefg"
+     * StringUtils.abbreviate("abcdefg", 8) = "abcdefg"
+     * StringUtils.abbreviate("abcdefg", 4) = "a..."
+     * StringUtils.abbreviate("abcdefg", 3) = IllegalArgumentException
+     * 
+ * + * @param str the String to check, may be null + * @param maxWidth maximum length of result String, must be at least 4 + * @return abbreviated String, null if null String input + * @throws IllegalArgumentException if the width is too small + * @since 2.0 + */ + public static String abbreviate(String str, int maxWidth) { + return abbreviate(str, 0, maxWidth); + } + + /** + *

Abbreviates a String using ellipses. This will turn + * "Now is the time for all good men" into "...is the time for..."

+ * + *

Works like abbreviate(String, int), but allows you to specify + * a "left edge" offset. Note that this left edge is not necessarily going to + * be the leftmost character in the result, or the first character following the + * ellipses, but it will appear somewhere in the result. + * + *

In no case will it return a String of length greater than + * maxWidth.

+ * + *
+     * StringUtils.abbreviate(null, *, *)                = null
+     * StringUtils.abbreviate("", 0, 4)                  = ""
+     * StringUtils.abbreviate("abcdefghijklmno", -1, 10) = "abcdefg..."
+     * StringUtils.abbreviate("abcdefghijklmno", 0, 10)  = "abcdefg..."
+     * StringUtils.abbreviate("abcdefghijklmno", 1, 10)  = "abcdefg..."
+     * StringUtils.abbreviate("abcdefghijklmno", 4, 10)  = "abcdefg..."
+     * StringUtils.abbreviate("abcdefghijklmno", 5, 10)  = "...fghi..."
+     * StringUtils.abbreviate("abcdefghijklmno", 6, 10)  = "...ghij..."
+     * StringUtils.abbreviate("abcdefghijklmno", 8, 10)  = "...ijklmno"
+     * StringUtils.abbreviate("abcdefghijklmno", 10, 10) = "...ijklmno"
+     * StringUtils.abbreviate("abcdefghijklmno", 12, 10) = "...ijklmno"
+     * StringUtils.abbreviate("abcdefghij", 0, 3)        = IllegalArgumentException
+     * StringUtils.abbreviate("abcdefghij", 5, 6)        = IllegalArgumentException
+     * 
+ * + * @param str the String to check, may be null + * @param offset left edge of source String + * @param maxWidth maximum length of result String, must be at least 4 + * @return abbreviated String, null if null String input + * @throws IllegalArgumentException if the width is too small + * @since 2.0 + */ + public static String abbreviate(String str, int offset, int maxWidth) { + if (str == null) { + return null; + } + if (maxWidth < 4) { + throw new IllegalArgumentException("Minimum abbreviation width is 4"); + } + if (str.length() <= maxWidth) { + return str; + } + if (offset > str.length()) { + offset = str.length(); + } + if ((str.length() - offset) < (maxWidth - 3)) { + offset = str.length() - (maxWidth - 3); + } + if (offset <= 4) { + return str.substring(0, maxWidth - 3) + "..."; + } + if (maxWidth < 7) { + throw new IllegalArgumentException("Minimum abbreviation width with offset is 7"); + } + if ((offset + (maxWidth - 3)) < str.length()) { + return "..." + abbreviate(str.substring(offset), maxWidth - 3); + } + return "..." + str.substring(str.length() - (maxWidth - 3)); + } + + // Difference + //----------------------------------------------------------------------- + /** + *

Compares two Strings, and returns the portion where they differ. + * (More precisely, return the remainder of the second String, + * starting from where it's different from the first.)

+ * + *

For example, + * difference("i am a machine", "i am a robot") -> "robot".

+ * + *
+     * StringUtils.difference(null, null) = null
+     * StringUtils.difference("", "") = ""
+     * StringUtils.difference("", "abc") = "abc"
+     * StringUtils.difference("abc", "") = ""
+     * StringUtils.difference("abc", "abc") = ""
+     * StringUtils.difference("ab", "abxyz") = "xyz"
+     * StringUtils.difference("abcde", "abxyz") = "xyz"
+     * StringUtils.difference("abcde", "xyz") = "xyz"
+     * 
+ * + * @param str1 the first String, may be null + * @param str2 the second String, may be null + * @return the portion of str2 where it differs from str1; returns the + * empty String if they are equal + * @since 2.0 + */ + public static String difference(String str1, String str2) { + if (str1 == null) { + return str2; + } + if (str2 == null) { + return str1; + } + int at = indexOfDifference(str1, str2); + if (at == -1) { + return EMPTY; + } + return str2.substring(at); + } + + /** + *

Compares two Strings, and returns the index at which the + * Strings begin to differ.

+ * + *

For example, + * indexOfDifference("i am a machine", "i am a robot") -> 7

+ * + *
+     * StringUtils.indexOfDifference(null, null) = -1
+     * StringUtils.indexOfDifference("", "") = -1
+     * StringUtils.indexOfDifference("", "abc") = 0
+     * StringUtils.indexOfDifference("abc", "") = 0
+     * StringUtils.indexOfDifference("abc", "abc") = -1
+     * StringUtils.indexOfDifference("ab", "abxyz") = 2
+     * StringUtils.indexOfDifference("abcde", "abxyz") = 2
+     * StringUtils.indexOfDifference("abcde", "xyz") = 0
+     * 
+ * + * @param str1 the first String, may be null + * @param str2 the second String, may be null + * @return the index where str2 and str1 begin to differ; -1 if they are equal + * @since 2.0 + */ + public static int indexOfDifference(String str1, String str2) { + if (str1 == str2) { + return -1; + } + if (str1 == null || str2 == null) { + return 0; + } + int i; + for (i = 0; i < str1.length() && i < str2.length(); ++i) { + if (str1.charAt(i) != str2.charAt(i)) { + break; + } + } + if (i < str2.length() || i < str1.length()) { + return i; + } + return -1; + } + + + // Misc + //----------------------------------------------------------------------- + /** + *

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 (deletion, + * insertion or substitution).

+ * + *

This implementation of the Levenshtein distance algorithm + * is from http://www.merriampark.com/ld.htm

+ * + *
+     * StringUtils.getLevenshteinDistance(null, *)             = IllegalArgumentException
+     * StringUtils.getLevenshteinDistance(*, null)             = IllegalArgumentException
+     * StringUtils.getLevenshteinDistance("","")               = 0
+     * StringUtils.getLevenshteinDistance("","a")              = 1
+     * StringUtils.getLevenshteinDistance("aaapppp", "")       = 7
+     * StringUtils.getLevenshteinDistance("frog", "fog")       = 1
+     * StringUtils.getLevenshteinDistance("fly", "ant")        = 3
+     * StringUtils.getLevenshteinDistance("elephant", "hippo") = 7
+     * StringUtils.getLevenshteinDistance("hippo", "elephant") = 7
+     * StringUtils.getLevenshteinDistance("hippo", "zzzzzzzz") = 8
+     * StringUtils.getLevenshteinDistance("hello", "hallo")    = 1
+     * 
+ * + * @param s the first String, must not be null + * @param t the second String, must not be null + * @return result distance + * @throws IllegalArgumentException if either String input null + */ + public static int getLevenshteinDistance(String s, String t) { + if (s == null || t == null) { + throw new IllegalArgumentException("Strings must not be null"); + } + 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] = min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost); + } + } + + // Step 7 + return d[n][m]; + } + + /** + *

Gets the minimum of three int values.

+ * + * @param a value 1 + * @param b value 2 + * @param c value 3 + * @return the smallest of the values + */ + private static int min(int a, int b, int c) { + // Method copied from NumberUtils to avoid dependency on subpackage + if (b < a) { + a = b; + } + if (c < a) { + a = c; + } + return a; + } + +} + Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/SystemUtils.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/SystemUtils.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/SystemUtils.java 30 Aug 2012 16:24:42 -0000 1.1 @@ -0,0 +1,886 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang; + +/** + *

Helpers for java.lang.System.

+ * + *

If a system property cannot be read due to security restrictions, + * the corresponding field in this class will be set to null + * and a message will be written to System.err.

+ * + * @author Based on code from Avalon Excalibur + * @author Based on code from Lucene + * @author Stephen Colebourne + * @author Steve Downey + * @author Gary Gregory + * @author Michael Becke + * @author Tetsuya Kaneuchi + * @since 1.0 + * @version $Id: SystemUtils.java,v 1.1 2012/08/30 16:24:42 marcin Exp $ + */ +public class SystemUtils { + + // System property constants + //----------------------------------------------------------------------- + // These MUST be declared first. Other constants depend on this. + + /** + *

The file.encoding System Property.

+ *

File encoding, such as Cp1252.

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since 2.0 + * @since Java 1.2. + */ + public static final String FILE_ENCODING = getSystemProperty("file.encoding"); + + /** + *

The file.separator System Property. + * File separator ("/" on UNIX).

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since Java 1.1. + */ + public static final String FILE_SEPARATOR = getSystemProperty("file.separator"); + + /** + *

The java.class.path System Property. Java class path.

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since Java 1.1. + */ + public static final String JAVA_CLASS_PATH = getSystemProperty("java.class.path"); + + /** + *

The java.class.version System Property. + * Java class format version number.

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since Java 1.1. + */ + public static final String JAVA_CLASS_VERSION = getSystemProperty("java.class.version"); + + /** + *

The java.compiler System Property. Name of JIT compiler to use. + * First in JDK version 1.2. Not used in Sun JDKs after 1.2.

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since Java 1.2. Not used in Sun versions after 1.2. + */ + public static final String JAVA_COMPILER = getSystemProperty("java.compiler"); + + /** + *

The java.ext.dirs System Property. Path of extension directory + * or directories.

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since Java 1.3 + */ + public static final String JAVA_EXT_DIRS = getSystemProperty("java.ext.dirs"); + + /** + *

The java.home System Property. Java installation directory.

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since Java 1.1 + */ + public static final String JAVA_HOME = getSystemProperty("java.home"); + + /** + *

The java.io.tmpdir System Property. Default temp file path.

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since Java 1.2 + */ + public static final String JAVA_IO_TMPDIR = getSystemProperty("java.io.tmpdir"); + + /** + *

The java.library.path System Property. List of paths to search + * when loading libraries.

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since Java 1.2 + */ + public static final String JAVA_LIBRARY_PATH = getSystemProperty("java.library.path"); + + /** + *

The java.runtime.name System Property. Java Runtime Environment + * name.

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since 2.0 + * @since Java 1.3 + */ + public static final String JAVA_RUNTIME_NAME = getSystemProperty("java.runtime.name"); + + /** + *

The java.runtime.version System Property. Java Runtime Environment + * version.

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since 2.0 + * @since Java 1.3 + */ + public static final String JAVA_RUNTIME_VERSION = getSystemProperty("java.runtime.version"); + + /** + *

The java.specification.name System Property. Java Runtime Environment + * specification name.

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since Java 1.2 + */ + public static final String JAVA_SPECIFICATION_NAME = getSystemProperty("java.specification.name"); + + /** + *

The java.specification.vendor System Property. Java Runtime Environment + * specification vendor.

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since Java 1.2 + */ + public static final String JAVA_SPECIFICATION_VENDOR = getSystemProperty("java.specification.vendor"); + + /** + *

The java.specification.version System Property. Java Runtime Environment + * specification version.

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since Java 1.3 + */ + public static final String JAVA_SPECIFICATION_VERSION = getSystemProperty("java.specification.version"); + + /** + *

The java.vendor System Property. Java vendor-specific string.

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since Java 1.1 + */ + public static final String JAVA_VENDOR = getSystemProperty("java.vendor"); + + /** + *

The java.vendor.url System Property. Java vendor URL.

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since Java 1.1 + */ + public static final String JAVA_VENDOR_URL = getSystemProperty("java.vendor.url"); + + /** + *

The java.version System Property. Java version number.

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since Java 1.1 + */ + public static final String JAVA_VERSION = getSystemProperty("java.version"); + + /** + *

The java.vm.info System Property. Java Virtual Machine implementation + * info.

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since 2.0 + * @since Java 1.2 + */ + public static final String JAVA_VM_INFO = getSystemProperty("java.vm.info"); + + /** + *

The java.vm.name System Property. Java Virtual Machine implementation + * name.

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since Java 1.2 + */ + public static final String JAVA_VM_NAME = getSystemProperty("java.vm.name"); + + /** + *

The java.vm.specification.name System Property. Java Virtual Machine + * specification name.

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since Java 1.2 + */ + public static final String JAVA_VM_SPECIFICATION_NAME = getSystemProperty("java.vm.specification.name"); + + /** + *

The java.vm.specification.vendor System Property. Java Virtual + * Machine specification vendor.

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since Java 1.2 + */ + public static final String JAVA_VM_SPECIFICATION_VENDOR = getSystemProperty("java.vm.specification.vendor"); + + /** + *

The java.vm.specification.version System Property. Java Virtual Machine + * specification version.

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since Java 1.2 + */ + public static final String JAVA_VM_SPECIFICATION_VERSION = getSystemProperty("java.vm.specification.version"); + + /** + *

The java.vm.vendor System Property. Java Virtual Machine implementation + * vendor.

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since Java 1.2 + */ + public static final String JAVA_VM_VENDOR = getSystemProperty("java.vm.vendor"); + + /** + *

The java.vm.version System Property. Java Virtual Machine + * implementation version.

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since Java 1.2 + */ + public static final String JAVA_VM_VERSION = getSystemProperty("java.vm.version"); + + /** + *

The line.separator System Property. Line separator + * ("\n<" on UNIX).

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since Java 1.1 + */ + public static final String LINE_SEPARATOR = getSystemProperty("line.separator"); + + /** + *

The os.arch System Property. Operating system architecture.

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since Java 1.1 + */ + public static final String OS_ARCH = getSystemProperty("os.arch"); + + /** + *

The os.name System Property. Operating system name.

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since Java 1.1 + */ + public static final String OS_NAME = getSystemProperty("os.name"); + + /** + *

The os.version System Property. Operating system version.

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since Java 1.1 + */ + public static final String OS_VERSION = getSystemProperty("os.version"); + + /** + *

The path.separator System Property. Path separator + * (":" on UNIX).

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since Java 1.1 + */ + public static final String PATH_SEPARATOR = getSystemProperty("path.separator"); + + /** + *

The user.country or user.region System Property. + * User's country code, such as GB. First in JDK version 1.2 as + * user.region. Renamed to user.country in 1.4

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since 2.0 + * @since Java 1.2 + */ + public static final String USER_COUNTRY = + (getSystemProperty("user.country") == null ? + getSystemProperty("user.region") : getSystemProperty("user.country")); + + /** + *

The user.dir System Property. User's current working + * directory.

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since Java 1.1 + */ + public static final String USER_DIR = getSystemProperty("user.dir"); + + /** + *

The user.home System Property. User's home directory.

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since Java 1.1 + */ + public static final String USER_HOME = getSystemProperty("user.home"); + + /** + *

The user.language System Property. User's language code, + * such as 'en'.

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since 2.0 + * @since Java 1.2 + */ + public static final String USER_LANGUAGE = getSystemProperty("user.language"); + + /** + *

The user.name System Property. User's account name.

+ * + *

Defaults to null if the runtime does not have + * security access to read this property or the property does not exist.

+ * + * @since Java 1.1 + */ + public static final String USER_NAME = getSystemProperty("user.name"); + + // Java version + //----------------------------------------------------------------------- + // These MUST be declared after those above as they depend on the + // values being set up + + /** + *

Gets the Java version as a float.

+ * + *

Example return values:

+ *
    + *
  • 1.2f for JDK 1.2 + *
  • 1.31f for JDK 1.3.1 + *
+ * + *

The field will return zero if {@link #JAVA_VERSION} is null.

+ * + * @since 2.0 + */ + public static final float JAVA_VERSION_FLOAT = getJavaVersionAsFloat(); + + /** + *

Gets the Java version as an int.

+ * + *

Example return values:

+ *
    + *
  • 120 for JDK 1.2 + *
  • 131 for JDK 1.3.1 + *
+ * + *

The field will return zero if {@link #JAVA_VERSION} is null.

+ * + * @since 2.0 + */ + public static final int JAVA_VERSION_INT = getJavaVersionAsInt(); + + // Java version checks + //----------------------------------------------------------------------- + // These MUST be declared after those above as they depend on the + // values being set up + + /** + *

Is true if this is Java version 1.1 (also 1.1.x versions).

+ * + *

The field will return false if {@link #JAVA_VERSION} is + * null.

+ */ + public static final boolean IS_JAVA_1_1 = getJavaVersionMatches("1.1"); + + /** + *

Is true if this is Java version 1.2 (also 1.2.x versions).

+ * + *

The field will return false if {@link #JAVA_VERSION} is + * null.

+ */ + public static final boolean IS_JAVA_1_2 = getJavaVersionMatches("1.2"); + + /** + *

Is true if this is Java version 1.3 (also 1.3.x versions).

+ * + *

The field will return false if {@link #JAVA_VERSION} is + * null.

+ */ + public static final boolean IS_JAVA_1_3 = getJavaVersionMatches("1.3"); + + /** + *

Is true if this is Java version 1.4 (also 1.4.x versions).

+ * + *

The field will false false if {@link #JAVA_VERSION} is + * null.

+ */ + public static final boolean IS_JAVA_1_4 = getJavaVersionMatches("1.4"); + + /** + *

Is true if this is Java version 1.5 (also 1.5.x versions).

+ * + *

The field will return false if {@link #JAVA_VERSION} is + * null.

+ */ + public static final boolean IS_JAVA_1_5 = getJavaVersionMatches("1.5"); + + // Operating system checks + //----------------------------------------------------------------------- + // These MUST be declared after those above as they depend on the + // values being set up + // OS names from http://www.vamphq.com/os.html + // Selected ones included - please advise commons-dev@jakarta.apache.org + // if you want another added or a mistake corrected + + /** + *

Is true if this is AIX.

+ * + *

The field will return false if OS_NAME is + * null.

+ * + * @since 2.0 + */ + public static final boolean IS_OS_AIX = getOSMatches("AIX"); + + /** + *

Is true if this is HP-UX.

+ * + *

The field will return false if OS_NAME is + * null.

+ * + * @since 2.0 + */ + public static final boolean IS_OS_HP_UX = getOSMatches("HP-UX"); + + /** + *

Is true if this is Irix.

+ * + *

The field will return false if OS_NAME is + * null.

+ * + * @since 2.0 + */ + public static final boolean IS_OS_IRIX = getOSMatches("Irix"); + + /** + *

Is true if this is Linux.

+ * + *

The field will return false if OS_NAME is + * null.

+ * + * @since 2.0 + */ + public static final boolean IS_OS_LINUX = getOSMatches("Linux") || getOSMatches("LINUX"); + + /** + *

Is true if this is Mac.

+ * + *

The field will return false if OS_NAME is + * null.

+ * + * @since 2.0 + */ + public static final boolean IS_OS_MAC = getOSMatches("Mac"); + + /** + *

Is true if this is Mac.

+ * + *

The field will return false if OS_NAME is + * null.

+ * + * @since 2.0 + */ + public static final boolean IS_OS_MAC_OSX = getOSMatches("Mac OS X"); + + /** + *

Is true if this is OS/2.

+ * + *

The field will return false if OS_NAME is + * null.

+ * + * @since 2.0 + */ + public static final boolean IS_OS_OS2 = getOSMatches("OS/2"); + + /** + *

Is true if this is Solaris.

+ * + *

The field will return false if OS_NAME is + * null.

+ * + * @since 2.0 + */ + public static final boolean IS_OS_SOLARIS = getOSMatches("Solaris"); + + /** + *

Is true if this is SunOS.

+ * + *

The field will return false if OS_NAME is + * null.

+ * + * @since 2.0 + */ + public static final boolean IS_OS_SUN_OS = getOSMatches("SunOS"); + + /** + *

Is true if this is Windows.

+ * + *

The field will return false if OS_NAME is + * null.

+ * + * @since 2.0 + */ + public static final boolean IS_OS_WINDOWS = getOSMatches("Windows"); + + /** + *

Is true if this is Windows 2000.

+ * + *

The field will return false if OS_NAME is + * null.

+ * + * @since 2.0 + */ + public static final boolean IS_OS_WINDOWS_2000 = getOSMatches("Windows", "5.0"); + + /** + *

Is true if this is Windows 95.

+ * + *

The field will return false if OS_NAME is + * null.

+ * + * @since 2.0 + */ + public static final boolean IS_OS_WINDOWS_95 = getOSMatches("Windows 9", "4.0"); + // JDK 1.2 running on Windows98 returns 'Windows 95', hence the above + + /** + *

Is true if this is Windows 98.

+ * + *

The field will return false if OS_NAME is + * null.

+ * + * @since 2.0 + */ + public static final boolean IS_OS_WINDOWS_98 = getOSMatches("Windows 9", "4.1"); + // JDK 1.2 running on Windows98 returns 'Windows 95', hence the above + + /** + *

Is true if this is Windows ME.

+ * + *

The field will return false if OS_NAME is + * null.

+ * + * @since 2.0 + */ + public static final boolean IS_OS_WINDOWS_ME = getOSMatches("Windows", "4.9"); + // JDK 1.2 running on WindowsME may return 'Windows 95', hence the above + + /** + *

Is true if this is Windows NT.

+ * + *

The field will return false if OS_NAME is + * null.

+ * + * @since 2.0 + */ + public static final boolean IS_OS_WINDOWS_NT = getOSMatches("Windows NT"); + // Windows 2000 returns 'Windows 2000' but may suffer from same JDK1.2 problem + + /** + *

Is true if this is Windows XP.

+ * + *

The field will return false if OS_NAME is + * null.

+ * + * @since 2.0 + */ + public static final boolean IS_OS_WINDOWS_XP = getOSMatches("Windows", "5.1"); + // Windows XP returns 'Windows 2000' just for fun... + + //----------------------------------------------------------------------- + /** + *

SystemUtils instances should NOT be constructed in standard + * programming. Instead, the class should be used as + * SystemUtils.FILE_SEPARATOR.

+ * + *

This constructor is public to permit tools that require a JavaBean + * instance to operate.

+ */ + public SystemUtils() { + } + + //----------------------------------------------------------------------- + /** + *

Gets the Java version number as a float.

+ * + *

Example return values:

+ *
    + *
  • 1.2f for JDK 1.2 + *
  • 1.31f for JDK 1.3.1 + *
+ * + * @return the version, for example 1.31f for JDK 1.3.1 + * @deprecated Use {@link #JAVA_VERSION_FLOAT} instead. + * Method will be removed in Commons Lang 3.0. + */ + public static float getJavaVersion() { + return JAVA_VERSION_FLOAT; + } + + /** + *

Gets the Java version number as a float.

+ * + *

Example return values:

+ *
    + *
  • 1.2f for JDK 1.2 + *
  • 1.31f for JDK 1.3.1 + *
+ * + *

Patch releases are not reported. + * Zero is returned if {@link #JAVA_VERSION} is null.

+ * + * @return the version, for example 1.31f for JDK 1.3.1 + */ + private static float getJavaVersionAsFloat() { + if (JAVA_VERSION == null) { + return 0f; + } + String str = JAVA_VERSION.substring(0, 3); + if (JAVA_VERSION.length() >= 5) { + str = str + JAVA_VERSION.substring(4, 5); + } + return Float.parseFloat(str); + } + + /** + *

Gets the Java version number as an int.

+ * + *

Example return values:

+ *
    + *
  • 120 for JDK 1.2 + *
  • 131 for JDK 1.3.1 + *
+ * + *

Patch releases are not reported. + * Zero is returned if {@link #JAVA_VERSION} is null.

+ * + * @return the version, for example 131 for JDK 1.3.1 + */ + private static int getJavaVersionAsInt() { + if (JAVA_VERSION == null) { + return 0; + } + String str = JAVA_VERSION.substring(0, 1); + str = str + JAVA_VERSION.substring(2, 3); + if (JAVA_VERSION.length() >= 5) { + str = str + JAVA_VERSION.substring(4, 5); + } else { + str = str + "0"; + } + return Integer.parseInt(str); + } + + /** + *

Decides if the java version matches.

+ * + * @param versionPrefix the prefix for the java version + * @return true if matches, or false if not or can't determine + */ + private static boolean getJavaVersionMatches(String versionPrefix) { + if (JAVA_VERSION == null) { + return false; + } + return JAVA_VERSION.startsWith(versionPrefix); + } + + /** + *

Decides if the operating system matches.

+ * + * @param osNamePrefix the prefix for the os name + * @return true if matches, or false if not or can't determine + */ + private static boolean getOSMatches(String osNamePrefix) { + if (OS_NAME == null) { + return false; + } + return OS_NAME.startsWith(osNamePrefix); + } + + /** + *

Decides if the operating system matches.

+ * + * @param osNamePrefix the prefix for the os name + * @param osVersionPrefix the prefix for the version + * @return true if matches, or false if not or can't determine + */ + private static boolean getOSMatches(String osNamePrefix, String osVersionPrefix) { + if (OS_NAME == null || OS_VERSION == null) { + return false; + } + return OS_NAME.startsWith(osNamePrefix) && OS_VERSION.startsWith(osVersionPrefix); + } + + //----------------------------------------------------------------------- + /** + *

Gets a System property, defaulting to null if the property + * cannot be read.

+ * + *

If a SecurityException is caught, the return + * value is null and a message is written to System.err.

+ * + * @param property the system property name + * @return the system property value or null if a security problem occurs + */ + private static String getSystemProperty(String property) { + try { + return System.getProperty(property); + } catch (SecurityException ex) { + // we are not allowed to look at this property + System.err.println( + "Caught a SecurityException reading the system property '" + property + + "'; the SystemUtils property value will default to null." + ); + return null; + } + } + + /** + *

Is the Java version at least the requested version.

+ * + *

Example input:

+ *
    + *
  • 1.2f to test for JDK 1.2
  • + *
  • 1.31f to test for JDK 1.3.1
  • + *
+ * + * @param requiredVersion the required version, for example 1.31f + * @return true if the actual version is equal or greater + * than the required version + */ + public static boolean isJavaVersionAtLeast(float requiredVersion) { + return (JAVA_VERSION_FLOAT >= requiredVersion); + } + + /** + *

Is the Java version at least the requested version.

+ * + *

Example input:

+ *
    + *
  • 120 to test for JDK 1.2 or greater
  • + *
  • 131 to test for JDK 1.3.1 or greater
  • + *
+ * + * @param requiredVersion the required version, for example 131 + * @return true if the actual version is equal or greater + * than the required version + * @since 2.0 + */ + public static boolean isJavaVersionAtLeast(int requiredVersion) { + return (JAVA_VERSION_INT >= requiredVersion); + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/UnhandledException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/UnhandledException.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/UnhandledException.java 30 Aug 2012 16:24:42 -0000 1.1 @@ -0,0 +1,87 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang; + +import org.apache.commons.lang.exception.NestableRuntimeException; + +/** + * Thrown when it is impossible or undesirable to consume + * or throw a checked exception. + * + * @author Matthew Hawthorne + * @since 2.0 + * @version $Id: UnhandledException.java,v 1.1 2012/08/30 16:24:42 marcin Exp $ + */ +public class UnhandledException extends NestableRuntimeException { + + /** + * Constructs the exception using a cause. + * + * @param cause the underlying cause + */ + public UnhandledException(Throwable cause) { + super(cause); + } + + /** + * Constructs the exception using a message and cause. + * + * @param message the message to use + * @param cause the underlying cause + */ + public UnhandledException(String message, Throwable cause) { + super(message, cause); + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/Validate.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/Validate.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/Validate.java 30 Aug 2012 16:24:42 -0000 1.1 @@ -0,0 +1,524 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; + +/** + *

Assists in validating arguments.

+ * + *

The class is based along the lines of JUnit. If an argument value is + * deemed invalid, an IllegalArgumentException is thrown. For example:

+ * + *
+ * Validate.isTrue( i > 0, "The value must be greater than zero: ", i);
+ * Validate.notNull( surname, "The surname must not be null");
+ * 
+ * + * @author Ola Berg + * @author Stephen Colebourne + * @author Gary Gregory + * @since 2.0 + * @version $Id: Validate.java,v 1.1 2012/08/30 16:24:42 marcin Exp $ + */ +public class Validate { + + /** + * Constructor. This class should not normally be instantiated. + */ + public Validate() { + } + + // isTrue + //--------------------------------------------------------------------------------- + + /** + *

Validate an argument, throwing IllegalArgumentException + * if the test result is false.

+ * + *

This is used when validating according to an arbitrary boolean expression, + * such as validating a primitive number or using your own custom validation + * expression.

+ * + *
+     * Validate.isTrue( myObject.isOk(), "The object is not OK: ", myObject);
+     * 
+ * + *

For performance reasons, the object is passed as a separate parameter and + * appended to the message string only in the case of an error.

+ * + * @param expression a boolean expression + * @param message the exception message you would like to see if the + * expression is false + * @param value the value to append to the message in case of error + * @throws IllegalArgumentException if expression is false + */ + public static void isTrue(boolean expression, String message, Object value) { + if (expression == false) { + throw new IllegalArgumentException(message + value); + } + } + + /** + *

Validate an argument, throwing IllegalArgumentException + * if the test result is false.

+ * + *

This is used when validating according to an arbitrary boolean expression, + * such as validating a primitive number or using your own custom validation + * expression.

+ * + *
+     * Validate.isTrue( i > 0, "The value must be greater than zero: ", i);
+     * 
+ * + *

For performance reasons, the object is passed as a separate parameter and + * appended to the message string only in the case of an error.

+ * + * @param expression a boolean expression + * @param message the exception message you would like to see if the expression is false + * @param value the value to append to the message in case of error + * @throws IllegalArgumentException if expression is false + */ + public static void isTrue(boolean expression, String message, long value) { + if (expression == false) { + throw new IllegalArgumentException(message + value); + } + } + + /** + *

Validate an argument, throwing IllegalArgumentException + * if the test result is false.

+ * + *

This is used when validating according to an arbitrary boolean expression, + * such as validating a primitive number or using your own custom validation + * expression.

+ * + *
+     * Validate.isTrue( d > 0.0, "The value must be greater than zero: ", d);
+     * 
+ * + *

For performance reasons, the object is passed as a separate parameter and + * appended to the message string only in the case of an error.

+ * + * @param expression a boolean expression + * @param message the exception message you would like to see if the expression + * is false + * @param value the value to append to the message in case of error + * @throws IllegalArgumentException if expression is false + */ + public static void isTrue(boolean expression, String message, double value) { + if (expression == false) { + throw new IllegalArgumentException(message + value); + } + } + + /** + *

Validate an argument, throwing IllegalArgumentException + * if the test result is false.

+ * + *

This is used when validating according to an arbitrary boolean expression, + * such as validating a primitive number or using your own custom validation + * expression.

+ * + *
+     * Validate.isTrue( (i > 0), "The value must be greater than zero");
+     * Validate.isTrue( myObject.isOk(), "The object is not OK");
+     * 
+ * + *

For performance reasons, the message string should not involve a string append, + * instead use the {@link #isTrue(boolean, String, Object)} method.

+ * + * @param expression a boolean expression + * @param message the exception message you would like to see if the expression + * is false + * @throws IllegalArgumentException if expression is false + */ + public static void isTrue(boolean expression, String message) { + if (expression == false) { + throw new IllegalArgumentException(message); + } + } + + /** + *

Validate an argument, throwing IllegalArgumentException + * if the test result is false.

+ * + *

This is used when validating according to an arbitrary boolean expression, + * such as validating a primitive number or using your own custom validation + * expression.

+ * + *
+     * Validate.isTrue( i > 0 );
+     * Validate.isTrue( myObject.isOk() );
+     * 
+ * + *

The message in the exception is 'The validated expression is false'.

+ * + * @param expression a boolean expression + * @throws IllegalArgumentException if expression is false + */ + public static void isTrue(boolean expression) { + if (expression == false) { + throw new IllegalArgumentException("The validated expression is false"); + } + } + + // notNull + //--------------------------------------------------------------------------------- + + /** + *

Validate an argument, throwing IllegalArgumentException + * if the argument is null.

+ * + *
+     * Validate.notNull(myObject, "The object must not be null");
+     * 
+ * + * @param object the object to check is not null + * @param message the exception message you would like to see + * if the object is null + * @throws IllegalArgumentException if the object is null + */ + public static void notNull(Object object, String message) { + if (object == null) { + throw new IllegalArgumentException(message); + } + } + + /** + *

Validate an argument, throwing IllegalArgumentException + * if the argument is null.

+ * + *
+     * Validate.notNull(myObject);
+     * 
+ * + *

The message in the exception is 'The validated object is null'.

+ * + * @param object the object to check is not null + * @throws IllegalArgumentException if the object is null + */ + public static void notNull(Object object) { + if (object == null) { + throw new IllegalArgumentException("The validated object is null"); + } + } + + // notEmpty array + //--------------------------------------------------------------------------------- + + /** + *

Validate an argument, throwing IllegalArgumentException + * if the argument array is empty (null or no elements).

+ * + *
+     * Validate.notEmpty(myArray, "The array must not be empty");
+     * 
+ * + * @param array the array to check is not empty + * @param message the exception message you would like to see if the array is empty + * @throws IllegalArgumentException if the array is empty + */ + public static void notEmpty(Object[] array, String message) { + if (array == null || array.length == 0) { + throw new IllegalArgumentException(message); + } + } + + /** + *

Validate an argument, throwing IllegalArgumentException + * if the argument array is empty (null or no elements).

+ * + *
+     * Validate.notEmpty(myArray);
+     * 
+ * + *

The message in the exception is 'The validated array is empty'. + * + * @param array the array to check is not empty + * @throws IllegalArgumentException if the array is empty + */ + public static void notEmpty(Object[] array) { + if (array == null || array.length == 0) { + throw new IllegalArgumentException("The validated array is empty"); + } + } + + // notEmpty collection + //--------------------------------------------------------------------------------- + + /** + *

Validate an argument, throwing IllegalArgumentException + * if the argument Collection is empty (null or no elements).

+ * + *
+     * Validate.notEmpty(myCollection, "The collection must not be empty");
+     * 
+ * + * @param collection the collection to check is not empty + * @param message the exception message you would like to see if the collection is empty + * @throws IllegalArgumentException if the collection is empty + */ + public static void notEmpty(Collection collection, String message) { + if (collection == null || collection.size() == 0) { + throw new IllegalArgumentException(message); + } + } + + /** + *

Validate an argument, throwing IllegalArgumentException + * if the argument Collection is empty (null or no elements).

+ * + *
+     * Validate.notEmpty(myCollection);
+     * 
+ * + *

The message in the exception is 'The validated collection is empty'.

+ * + * @param collection the collection to check is not empty + * @throws IllegalArgumentException if the collection is empty + */ + public static void notEmpty(Collection collection) { + if (collection == null || collection.size() == 0) { + throw new IllegalArgumentException("The validated collection is empty"); + } + } + + // notEmpty map + //--------------------------------------------------------------------------------- + + /** + *

Validate an argument, throwing IllegalArgumentException + * if the argument Map is empty (null or no elements).

+ * + *
+     * Validate.notEmpty(myMap, "The collection must not be empty");
+     * 
+ * + * @param map the map to check is not empty + * @param message the exception message you would like to see if the map is empty + * @throws IllegalArgumentException if the map is empty + */ + public static void notEmpty(Map map, String message) { + if (map == null || map.size() == 0) { + throw new IllegalArgumentException(message); + } + } + + /** + *

Validate an argument, throwing IllegalArgumentException + * if the argument Map is empty (null or no elements).

+ * + *
+     * Validate.notEmpty(myMap);
+     * 
+ * + *

The message in the exception is 'The validated map is empty'.

+ * + * @param map the map to check is not empty + * @throws IllegalArgumentException if the map is empty + */ + public static void notEmpty(Map map) { + if (map == null || map.size() == 0) { + throw new IllegalArgumentException("The validated map is empty"); + } + } + + // notEmpty string + //--------------------------------------------------------------------------------- + + /** + *

Validate an argument, throwing IllegalArgumentException + * if the argument String is empty (null or zero length).

+ * + *
+     * Validate.notEmpty(myString, "The string must not be empty");
+     * 
+ * + * @param string the string to check is not empty + * @param message the exception message you would like to see if the string is empty + * @throws IllegalArgumentException if the string is empty + */ + public static void notEmpty(String string, String message) { + if (string == null || string.length() == 0) { + throw new IllegalArgumentException(message); + } + } + + /** + *

Validate an argument, throwing IllegalArgumentException + * if the argument String is empty (null or zero length).

+ * + *
+     * Validate.notEmpty(myString);
+     * 
+ * + *

The message in the exception is 'The validated string is empty'.

+ * + * @param string the string to check is not empty + * @throws IllegalArgumentException if the string is empty + */ + public static void notEmpty(String string) { + if (string == null || string.length() == 0) { + throw new IllegalArgumentException("The validated string is empty"); + } + } + + // notNullElements array + //--------------------------------------------------------------------------------- + + /** + *

Validate an argument, throwing IllegalArgumentException + * if the argument array has null elements or is + * null.

+ * + *
+     * Validate.notEmpty(myArray, "The array must not contain null elements");
+     * 
+ * + * @param array the array to check + * @param message the exception message if the array has + * null elements + * @throws IllegalArgumentException if the array has null + * elements or is null + */ + public static void noNullElements(Object[] array, String message) { + Validate.notNull(array); + for (int i = 0; i < array.length; i++) { + if (array[i] == null) { + throw new IllegalArgumentException(message); + } + } + } + + /** + *

Validate an argument, throwing IllegalArgumentException + * if the argument array has null elements or is + * null.

+ * + *
+     * Validate.notEmpty(myArray);
+     * 
+ * + *

The message in the exception is 'The validated array contains null element at index: '.

+ * + * @param array the array to check + * @throws IllegalArgumentException if the array has null + * elements or is null + */ + public static void noNullElements(Object[] array) { + Validate.notNull(array); + for (int i = 0; i < array.length; i++) { + if (array[i] == null) { + throw new IllegalArgumentException("The validated array contains null element at index: " + i); + } + } + } + + // notNullElements collection + //--------------------------------------------------------------------------------- + + /** + *

Validate an argument, throwing IllegalArgumentException + * if the argument collection has null elements or is + * null.

+ * + *
+     * Validate.notEmpty(myCollection, "The collection must not contain null elements");
+     * 
+ * + * @param collection the collection to check + * @param message the exception message if the array has + * null elements + * @throws IllegalArgumentException if the collection has + * null elements or is null + */ + public static void noNullElements(Collection collection, String message) { + Validate.notNull(collection); + int i = 0; + for (Iterator it = collection.iterator(); it.hasNext(); i++) { + if (it.next() == null) { + throw new IllegalArgumentException(message); + } + } + } + + /** + *

Validate an argument, throwing IllegalArgumentException + * if the argument collection has null elements or is + * null.

+ * + *
+     * Validate.notEmpty(myCollection);
+     * 
+ * + *

The message in the exception is 'The validated collection contains null element at index: '.

+ * + * @param collection the collection to check + * @throws IllegalArgumentException if the collection has + * null elements or is null + */ + public static void noNullElements(Collection collection) { + Validate.notNull(collection); + int i = 0; + for (Iterator it = collection.iterator(); it.hasNext(); i++) { + if (it.next() == null) { + throw new IllegalArgumentException("The validated collection contains null element at index: " + i); + } + } + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/WordUtils.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/WordUtils.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/WordUtils.java 30 Aug 2012 16:24:42 -0000 1.1 @@ -0,0 +1,433 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang; + +/** + *

Operations on Strings that contain words.

+ * + *

This class tries to handle null input gracefully. + * An exception will not be thrown for a null input. + * Each method documents its behaviour in more detail.

+ * + * @author Apache Jakarta Velocity + * @author Henri Yandell + * @author Stephen Colebourne + * @author Henning P. Schmiedehausen + * @author Gary Gregory + * @since 2.0 + * @version $Id: WordUtils.java,v 1.1 2012/08/30 16:24:42 marcin Exp $ + */ +public class WordUtils { + + /** + *

WordWrapUtils instances should NOT be constructed in + * standard programming. Instead, the class should be used as + * WordWrapUtils.wrap("foo bar", 20);.

+ * + *

This constructor is public to permit tools that require a JavaBean + * instance to operate.

+ */ + public WordUtils() { + } + + // Wrapping + //-------------------------------------------------------------------------- +// /** +// *

Wraps a block of text to a specified line length using '\n' as +// * a newline.

+// * +// *

This method takes a block of text, which might have long lines in it +// * and wraps the long lines based on the supplied lineLength parameter.

+// * +// *

If a single word is longer than the line length (eg. a URL), it will +// * not be broken, and will display beyond the expected width.

+// * +// *

If there are tabs in inString, you are going to get results that are +// * a bit strange. Tabs are a single character but are displayed as 4 or 8 +// * spaces. Remove the tabs.

+// * +// * @param str text which is in need of word-wrapping, may be null +// * @param lineLength the column to wrap the words at +// * @return the text with all the long lines word-wrapped +// * null if null string input +// */ +// public static String wrapText(String str, int lineLength) { +// return wrap(str, null, lineLength); +// } + +// /** +// *

Wraps a block of text to a specified line length.

+// * +// *

This method takes a block of text, which might have long lines in it +// * and wraps the long lines based on the supplied lineLength parameter.

+// * +// *

If a single word is longer than the wrapColumn (eg. a URL), it will +// * not be broken, and will display beyond the expected width.

+// * +// *

If there are tabs in inString, you are going to get results that are +// * a bit strange. Tabs are a single character but are displayed as 4 or 8 +// * spaces. Remove the tabs.

+// * +// * @param str text which is in need of word-wrapping, may be null +// * @param newLineChars the characters that define a newline, null treated as \n +// * @param lineLength the column to wrap the words at +// * @return the text with all the long lines word-wrapped +// * null if null string input +// */ +// public static String wrapText(String str, String newLineChars, int lineLength) { +// if (str == null) { +// return null; +// } +// if (newLineChars == null) { +// newLineChars = "\n"; +// } +// StringTokenizer lineTokenizer = new StringTokenizer(str, newLineChars, true); +// StringBuffer stringBuffer = new StringBuffer(); +// +// while (lineTokenizer.hasMoreTokens()) { +// try { +// String nextLine = lineTokenizer.nextToken(); +// +// if (nextLine.length() > lineLength) { +// // This line is long enough to be wrapped. +// nextLine = wrapLine(nextLine, null, lineLength, false); +// } +// +// stringBuffer.append(nextLine); +// +// } catch (NoSuchElementException nsee) { +// // thrown by nextToken(), but I don't know why it would +// break; +// } +// } +// +// return (stringBuffer.toString()); +// } + + // Wrapping + //----------------------------------------------------------------------- + /** + *

Wraps a single line of text, identifying words by ' '.

+ * + *

New lines will be separated by the system property line separator. + * Very long words, such as URLs will not be wrapped.

+ * + *

Leading spaces on a new line are stripped. + * Trailing spaces are not stripped.

+ * + *
+     * WordUtils.wrap(null, *) = null
+     * WordUtils.wrap("", *) = ""
+     * 
+ * + * @param str the String to be word wrapped, may be null + * @param wrapLength the column to wrap the words at, less than 1 is treated as 1 + * @return a line with newlines inserted, null if null input + */ + public static String wrap(String str, int wrapLength) { + return wrap(str, wrapLength, null, false); + } + + /** + *

Wraps a single line of text, identifying words by ' '.

+ * + *

Leading spaces on a new line are stripped. + * Trailing spaces are not stripped.

+ * + *
+     * WordUtils.wrap(null, *, *, *) = null
+     * WordUtils.wrap("", *, *, *) = ""
+     * 
+ * + * @param str the String to be word wrapped, may be null + * @param wrapLength the column to wrap the words at, less than 1 is treated as 1 + * @param newLineStr the string to insert for a new line, + * null uses the system property line separator + * @param wrapLongWords true if long words (such as URLs) should be wrapped + * @return a line with newlines inserted, null if null input + */ + public static String wrap(String str, int wrapLength, String newLineStr, boolean wrapLongWords) { + if (str == null) { + return null; + } + if (newLineStr == null) { + newLineStr = SystemUtils.LINE_SEPARATOR; + } + if (wrapLength < 1) { + wrapLength = 1; + } + int inputLineLength = str.length(); + int offset = 0; + StringBuffer wrappedLine = new StringBuffer(inputLineLength + 32); + + while ((inputLineLength - offset) > wrapLength) { + if (str.charAt(offset) == ' ') { + offset++; + continue; + } + int spaceToWrapAt = str.lastIndexOf(' ', wrapLength + offset); + + if (spaceToWrapAt >= offset) { + // normal case + wrappedLine.append(str.substring(offset, spaceToWrapAt)); + wrappedLine.append(newLineStr); + offset = spaceToWrapAt + 1; + + } else { + // really long word or URL + if (wrapLongWords) { + // wrap really long word one line at a time + wrappedLine.append(str.substring(offset, wrapLength + offset)); + wrappedLine.append(newLineStr); + offset += wrapLength; + } else { + // do not wrap really long word, just extend beyond limit + spaceToWrapAt = str.indexOf(' ', wrapLength + offset); + if (spaceToWrapAt >= 0) { + wrappedLine.append(str.substring(offset, spaceToWrapAt)); + wrappedLine.append(newLineStr); + offset = spaceToWrapAt + 1; + } else { + wrappedLine.append(str.substring(offset)); + offset = inputLineLength; + } + } + } + } + + // Whatever is left in line is short enough to just pass through + wrappedLine.append(str.substring(offset)); + + return wrappedLine.toString(); + } + + // Capitalizing + //----------------------------------------------------------------------- + /** + *

Capitalizes all the whitespace separated words in a String. + * Only the first letter of each word is changed. To change all letters to + * the capitalized case, use {@link #capitalizeFully(String)}.

+ * + *

Whitespace is defined by {@link Character#isWhitespace(char)}. + * A null input String returns null. + * Capitalization uses the unicode title case, normally equivalent to + * upper case.

+ * + *
+     * WordUtils.capitalize(null)        = null
+     * WordUtils.capitalize("")          = ""
+     * WordUtils.capitalize("i am FINE") = "I Am FINE"
+     * 
+ * + * @param str the String to capitalize, may be null + * @return capitalized String, null if null String input + * @see #uncapitalize(String) + * @see #capitalizeFully(String) + */ + public static String capitalize(String str) { + int strLen; + if (str == null || (strLen = str.length()) == 0) { + return str; + } + StringBuffer buffer = new StringBuffer(strLen); + boolean whitespace = true; + for (int i = 0; i < strLen; i++) { + char ch = str.charAt(i); + if (Character.isWhitespace(ch)) { + buffer.append(ch); + whitespace = true; + } else if (whitespace) { + buffer.append(Character.toTitleCase(ch)); + whitespace = false; + } else { + buffer.append(ch); + } + } + return buffer.toString(); + } + + /** + *

Capitalizes all the whitespace separated words in a String. + * All letters are changed, so the resulting string will be fully changed.

+ * + *

Whitespace is defined by {@link Character#isWhitespace(char)}. + * A null input String returns null. + * Capitalization uses the unicode title case, normally equivalent to + * upper case.

+ * + *
+     * WordUtils.capitalize(null)        = null
+     * WordUtils.capitalize("")          = ""
+     * WordUtils.capitalize("i am FINE") = "I Am Fine"
+     * 
+ * + * @param str the String to capitalize, may be null + * @return capitalized String, null if null String input + */ + public static String capitalizeFully(String str) { + int strLen; + if (str == null || (strLen = str.length()) == 0) { + return str; + } + StringBuffer buffer = new StringBuffer(strLen); + boolean whitespace = true; + for (int i = 0; i < strLen; i++) { + char ch = str.charAt(i); + if (Character.isWhitespace(ch)) { + buffer.append(ch); + whitespace = true; + } else if (whitespace) { + buffer.append(Character.toTitleCase(ch)); + whitespace = false; + } else { + buffer.append(Character.toLowerCase(ch)); + } + } + return buffer.toString(); + } + + /** + *

Uncapitalizes all the whitespace separated words in a String. + * Only the first letter of each word is changed.

+ * + *

Whitespace is defined by {@link Character#isWhitespace(char)}. + * A null input String returns null.

+ * + *
+     * WordUtils.uncapitalize(null)        = null
+     * WordUtils.uncapitalize("")          = ""
+     * WordUtils.uncapitalize("I Am FINE") = "i am fINE"
+     * 
+ * + * @param str the String to uncapitalize, may be null + * @return uncapitalized String, null if null String input + * @see #capitalize(String) + */ + public static String uncapitalize(String str) { + int strLen; + if (str == null || (strLen = str.length()) == 0) { + return str; + } + StringBuffer buffer = new StringBuffer(strLen); + boolean whitespace = true; + for (int i = 0; i < strLen; i++) { + char ch = str.charAt(i); + if (Character.isWhitespace(ch)) { + buffer.append(ch); + whitespace = true; + } else if (whitespace) { + buffer.append(Character.toLowerCase(ch)); + whitespace = false; + } else { + buffer.append(ch); + } + } + return buffer.toString(); + } + + /** + *

Swaps the case of a String using a word based algorithm.

+ * + *
    + *
  • Upper case character converts to Lower case
  • + *
  • Title case character converts to Lower case
  • + *
  • Lower case character after Whitespace or at start converts to Title case
  • + *
  • Other Lower case character converts to Upper case
  • + *
+ * + *

Whitespace is defined by {@link Character#isWhitespace(char)}. + * A null input String returns null.

+ * + *
+     * StringUtils.swapCase(null)                 = null
+     * StringUtils.swapCase("")                   = ""
+     * StringUtils.swapCase("The dog has a BONE") = "tHE DOG HAS A bone"
+     * 
+ * + * @param str the String to swap case, may be null + * @return the changed String, null if null String input + */ + public static String swapCase(String str) { + int strLen; + if (str == null || (strLen = str.length()) == 0) { + return str; + } + StringBuffer buffer = new StringBuffer(strLen); + + boolean whitespace = true; + char ch = 0; + char tmp = 0; + + for (int i = 0; i < strLen; i++) { + ch = str.charAt(i); + if (Character.isUpperCase(ch)) { + tmp = Character.toLowerCase(ch); + } else if (Character.isTitleCase(ch)) { + tmp = Character.toLowerCase(ch); + } else if (Character.isLowerCase(ch)) { + if (whitespace) { + tmp = Character.toTitleCase(ch); + } else { + tmp = Character.toUpperCase(ch); + } + } else { + tmp = ch; + } + buffer.append(tmp); + whitespace = Character.isWhitespace(ch); + } + return buffer.toString(); + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/overview.html =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/overview.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/overview.html 30 Aug 2012 16:24:42 -0000 1.1 @@ -0,0 +1,7 @@ + + +

+This document is the API specification for the Apache Jakarta Commons Lang Library, version 2.0. +

+ + \ No newline at end of file Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/package.html =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/package.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/package.html 30 Aug 2012 16:24:42 -0000 1.1 @@ -0,0 +1,7 @@ + + +Provides highly reusable static utility methods, chiefly concerned +with adding value to java.lang and other standard core classes. +@since 1.0 + + Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/builder/CompareToBuilder.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/builder/CompareToBuilder.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/builder/CompareToBuilder.java 30 Aug 2012 16:24:43 -0000 1.1 @@ -0,0 +1,966 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.builder; + +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.Comparator; + +import org.apache.commons.lang.math.NumberUtils; + +/** + * Assists in implementing {@link java.lang.Comparable#compareTo(Object)} methods. + * + * It is consistent with equals(Object) and + * hashcode() built with {@link EqualsBuilder} and + * {@link HashCodeBuilder}.

+ * + *

Two Objects that compare equal using equals(Object) should normally + * also compare equal using compareTo(Object).

+ * + *

All relevant fields should be included in the calculation of the + * comparison. Derived fields may be ignored. The same fields, in the same + * order, should be used in both compareTo(Object) and + * equals(Object).

+ * + *

To use this class write code as follows:

+ * + *
+ * public class MyClass {
+ *   String field1;
+ *   int field2;
+ *   boolean field3;
+ *
+ *   ...
+ *
+ *   public int compareTo(Object o) {
+ *     MyClass myClass = (MyClass) o;
+ *     return new CompareToBuilder()
+ *       .appendSuper(super.compareTo(o)
+ *       .append(this.field1, myClass.field1)
+ *       .append(this.field2, myClass.field2)
+ *       .append(this.field3, myClass.field3)
+ *       .toComparison();
+ *   }
+ * }
+ * 
+ * + *

Alternatively, there is a method {@link #reflectionCompare reflectionCompare} that uses + * reflection to determine the fields to append. Because fields can be private, + * reflectionCompare uses {@link java.lang.reflect.AccessibleObject#setAccessible(boolean)} to + * bypass normal access control checks. This will fail under a security manager, + * unless the appropriate permissions are set up correctly. It is also + * slower than appending explicitly.

+ * + *

A typical implementation of compareTo(Object) using + * reflectionCompare looks like:

+ + *
+ * public int compareTo(Object o) {
+ *   return CompareToBuilder.reflectionCompare(this, o);
+ * }
+ * 
+ * + * @see java.lang.Comparable + * @see java.lang.Object#equals(Object) + * @see java.lang.Object#hashCode() + * @see EqualsBuilder + * @see HashCodeBuilder + * @author Steve Downey + * @author Stephen Colebourne + * @author Gary Gregory + * @author Pete Gieser + * @since 1.0 + * @version $Id: CompareToBuilder.java,v 1.1 2012/08/30 16:24:43 marcin Exp $ + */ +public class CompareToBuilder { + + /** + * Current state of the comparison as appended fields are checked. + */ + private int comparison; + + /** + *

Constructor for CompareToBuilder.

+ * + *

Starts off assuming that the objects are equal. Multiple calls are + * then made to the various append methods, followed by a call to + * {@link #toComparison} to get the result.

+ */ + public CompareToBuilder() { + super(); + comparison = 0; + } + + //----------------------------------------------------------------------- + /** + *

Compares two Objects via reflection.

+ * + *

Fields can be private, thus AccessibleObject.setAccessible + * is used to bypass normal access control checks. This will fail under a + * security manager unless the appropriate permissions are set.

+ * + *
    + *
  • Static fields will not be compared
  • + *
  • Transient members will be not be compared, as they are likely derived + * fields
  • + *
  • Superclass fields will be compared
  • + *
+ * + *

If both lhs and rhs are null, + * they are considered equal.

+ * + * @param lhs left-hand object + * @param rhs right-hand object + * @return a negative integer, zero, or a positive integer as lhs + * is less than, equal to, or greater than rhs + * @throws NullPointerException if either (but not both) parameters are + * null + * @throws ClassCastException if rhs is not assignment-compatible + * with lhs + */ + public static int reflectionCompare(Object lhs, Object rhs) { + return reflectionCompare(lhs, rhs, false, null); + } + + /** + *

Compares two Objects via reflection.

+ * + *

Fields can be private, thus AccessibleObject.setAccessible + * is used to bypass normal access control checks. This will fail under a + * security manager unless the appropriate permissions are set.

+ * + *
    + *
  • Static fields will not be compared
  • + *
  • If compareTransients is true, + * compares transient members. Otherwise ignores them, as they + * are likely derived fields.
  • + *
  • Superclass fields will be compared
  • + *
+ * + *

If both lhs and rhs are null, + * they are considered equal.

+ * + * @param lhs left-hand object + * @param rhs right-hand object + * @param compareTransients whether to compare transient fields + * @return a negative integer, zero, or a positive integer as lhs + * is less than, equal to, or greater than rhs + * @throws NullPointerException if either lhs or rhs + * (but not both) is null + * @throws ClassCastException if rhs is not assignment-compatible + * with lhs + */ + public static int reflectionCompare(Object lhs, Object rhs, boolean compareTransients) { + return reflectionCompare(lhs, rhs, compareTransients, null); + } + + /** + *

Compares two Objects via reflection.

+ * + *

Fields can be private, thus AccessibleObject.setAccessible + * is used to bypass normal access control checks. This will fail under a + * security manager unless the appropriate permissions are set.

+ * + *
    + *
  • Static fields will not be compared
  • + *
  • If the compareTransients is true, + * compares transient members. Otherwise ignores them, as they + * are likely derived fields.
  • + *
  • Compares superclass fields up to and including reflectUpToClass. + * If reflectUpToClass is null, compares all superclass fields.
  • + *
+ * + *

If both lhs and rhs are null, + * they are considered equal.

+ * + * @param lhs left-hand object + * @param rhs right-hand object + * @param compareTransients whether to compare transient fields + * @param reflectUpToClass last superclass for which fields are compared + * @return a negative integer, zero, or a positive integer as lhs + * is less than, equal to, or greater than rhs + * @throws NullPointerException if either lhs or rhs + * (but not both) is null + * @throws ClassCastException if rhs is not assignment-compatible + * with lhs + * @since 2.0 + */ + public static int reflectionCompare(Object lhs, Object rhs, boolean compareTransients, Class reflectUpToClass) { + if (lhs == rhs) { + return 0; + } + if (lhs == null || rhs == null) { + throw new NullPointerException(); + } + Class lhsClazz = lhs.getClass(); + if (!lhsClazz.isInstance(rhs)) { + throw new ClassCastException(); + } + CompareToBuilder compareToBuilder = new CompareToBuilder(); + reflectionAppend(lhs, rhs, lhsClazz, compareToBuilder, compareTransients); + while (lhsClazz.getSuperclass() != null && lhsClazz != reflectUpToClass) { + lhsClazz = lhsClazz.getSuperclass(); + reflectionAppend(lhs, rhs, lhsClazz, compareToBuilder, compareTransients); + } + return compareToBuilder.toComparison(); + } + + /** + *

Appends to builder the comparison of lhs + * to rhs using the fields defined in clazz.

+ * + * @param lhs left-hand object + * @param rhs right-hand object + * @param clazz Class that defines fields to be compared + * @param builder CompareToBuilder to append to + * @param useTransients whether to compare transient fields + */ + private static void reflectionAppend( + Object lhs, + Object rhs, + Class clazz, + CompareToBuilder builder, + boolean useTransients) { + + Field[] fields = clazz.getDeclaredFields(); + AccessibleObject.setAccessible(fields, true); + for (int i = 0; i < fields.length && builder.comparison == 0; i++) { + Field f = fields[i]; + if ((f.getName().indexOf('$') == -1) + && (useTransients || !Modifier.isTransient(f.getModifiers())) + && (!Modifier.isStatic(f.getModifiers()))) { + try { + builder.append(f.get(lhs), f.get(rhs)); + } catch (IllegalAccessException e) { + // This can't happen. Would get a Security exception instead. + // Throw a runtime exception in case the impossible happens. + throw new InternalError("Unexpected IllegalAccessException"); + } + } + } + } + + //----------------------------------------------------------------------- + /** + *

Appends to the builder the compareTo(Object) + * result of the superclass.

+ * + * @param superCompareTo result of calling super.compareTo(Object) + * @return this - used to chain append calls + * @since 2.0 + */ + public CompareToBuilder appendSuper(int superCompareTo) { + if (comparison != 0) { + return this; + } + comparison = superCompareTo; + return this; + } + + //----------------------------------------------------------------------- + /** + *

Appends to the builder the comparison of + * two Objects.

+ * + *
    + *
  1. Check if lhs == rhs
  2. + *
  3. Check if either lhs or rhs is null, + * a null object is less than a non-null object
  4. + *
  5. Check the object contents
  6. + *
+ * + *

lhs must either be an array or implement {@link Comparable}.

+ * + * @param lhs left-hand object + * @param rhs right-hand object + * @return this - used to chain append calls + * @throws ClassCastException if rhs is not assignment-compatible + * with lhs + */ + public CompareToBuilder append(Object lhs, Object rhs) { + return append(lhs, rhs, null); + } + + /** + *

Appends to the builder the comparison of + * two Objects.

+ * + *
    + *
  1. Check if lhs == rhs
  2. + *
  3. Check if either lhs or rhs is null, + * a null object is less than a non-null object
  4. + *
  5. Check the object contents
  6. + *
+ * + *

If lhs is an array, array comparison methods will be used. + * Otherwise comparator will be used to compare the objects. + * If comparator is null, lhs must + * implement {@link Comparable} instead.

+ * + * @param lhs left-hand object + * @param rhs right-hand object + * @param comparator Comparator used to compare the objects, + * null means treat lhs as Comparable + * @return this - used to chain append calls + * @throws ClassCastException if rhs is not assignment-compatible + * with lhs + * @since 2.0 + */ + public CompareToBuilder append(Object lhs, Object rhs, Comparator comparator) { + if (comparison != 0) { + return this; + } + if (lhs == rhs) { + return this; + } + if (lhs == null) { + comparison = -1; + return this; + } + if (rhs == null) { + comparison = +1; + return this; + } + if (lhs.getClass().isArray()) { + // switch on type of array, to dispatch to the correct handler + // handles multi dimensional arrays + // throws a ClassCastException if rhs is not the correct array type + if (lhs instanceof long[]) { + append((long[]) lhs, (long[]) rhs); + } else if (lhs instanceof int[]) { + append((int[]) lhs, (int[]) rhs); + } else if (lhs instanceof short[]) { + append((short[]) lhs, (short[]) rhs); + } else if (lhs instanceof char[]) { + append((char[]) lhs, (char[]) rhs); + } else if (lhs instanceof byte[]) { + append((byte[]) lhs, (byte[]) rhs); + } else if (lhs instanceof double[]) { + append((double[]) lhs, (double[]) rhs); + } else if (lhs instanceof float[]) { + append((float[]) lhs, (float[]) rhs); + } else if (lhs instanceof boolean[]) { + append((boolean[]) lhs, (boolean[]) rhs); + } else { + // not an array of primitives + // throws a ClassCastException if rhs is not an array + append((Object[]) lhs, (Object[]) rhs, comparator); + } + } else { + // the simple case, not an array, just test the element + if (comparator == null) { + comparison = ((Comparable) lhs).compareTo(rhs); + } else { + comparison = comparator.compare(lhs, rhs); + } + } + return this; + } + + //------------------------------------------------------------------------- + /** + * Appends to the builder the comparison of + * two longs. + * + * @param lhs left-hand value + * @param rhs right-hand value + * @return this - used to chain append calls + */ + public CompareToBuilder append(long lhs, long rhs) { + if (comparison != 0) { + return this; + } + comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0)); + return this; + } + + /** + * Appends to the builder the comparison of + * two ints. + * + * @param lhs left-hand value + * @param rhs right-hand value + * @return this - used to chain append calls + */ + public CompareToBuilder append(int lhs, int rhs) { + if (comparison != 0) { + return this; + } + comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0)); + return this; + } + + /** + * Appends to the builder the comparison of + * two shorts. + * + * @param lhs left-hand value + * @param rhs right-hand value + * @return this - used to chain append calls + */ + public CompareToBuilder append(short lhs, short rhs) { + if (comparison != 0) { + return this; + } + comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0)); + return this; + } + + /** + * Appends to the builder the comparison of + * two chars. + * + * @param lhs left-hand value + * @param rhs right-hand value + * @return this - used to chain append calls + */ + public CompareToBuilder append(char lhs, char rhs) { + if (comparison != 0) { + return this; + } + comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0)); + return this; + } + + /** + * Appends to the builder the comparison of + * two bytes. + * + * @param lhs left-hand value + * @param rhs right-hand value + * @return this - used to chain append calls + */ + public CompareToBuilder append(byte lhs, byte rhs) { + if (comparison != 0) { + return this; + } + comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0)); + return this; + } + + /** + *

Appends to the builder the comparison of + * two doubles.

+ * + *

This handles NaNs, Infinties, and -0.0.

+ * + *

It is compatible with the hash code generated by + * HashCodeBuilder.

+ * + * @param lhs left-hand value + * @param rhs right-hand value + * @return this - used to chain append calls + */ + public CompareToBuilder append(double lhs, double rhs) { + if (comparison != 0) { + return this; + } + comparison = NumberUtils.compare(lhs, rhs); + return this; + } + + /** + *

Appends to the builder the comparison of + * two floats.

+ * + *

This handles NaNs, Infinties, and -0.0.

+ * + *

It is compatible with the hash code generated by + * HashCodeBuilder.

+ * + * @param lhs left-hand value + * @param rhs right-hand value + * @return this - used to chain append calls + */ + public CompareToBuilder append(float lhs, float rhs) { + if (comparison != 0) { + return this; + } + comparison = NumberUtils.compare(lhs, rhs); + return this; + } + + /** + * Appends to the builder the comparison of + * two booleanss. + * + * @param lhs left-hand value + * @param rhs right-hand value + * @return this - used to chain append calls + */ + public CompareToBuilder append(boolean lhs, boolean rhs) { + if (comparison != 0) { + return this; + } + if (lhs == rhs) { + return this; + } + if (lhs == false) { + comparison = -1; + } else { + comparison = +1; + } + return this; + } + + //----------------------------------------------------------------------- + /** + *

Appends to the builder the deep comparison of + * two Object arrays.

+ * + *
    + *
  1. Check if arrays are the same using ==
  2. + *
  3. Check if for null, null is less than non-null
  4. + *
  5. Check array length, a short length array is less than a long length array
  6. + *
  7. Check array contents element by element using {@link #append(Object, Object, Comparator)}
  8. + *
+ * + *

This method will also will be called for the top level of multi-dimensional, + * ragged, and multi-typed arrays.

+ * + * @param lhs left-hand array + * @param rhs right-hand array + * @return this - used to chain append calls + * @throws ClassCastException if rhs is not assignment-compatible + * with lhs + */ + public CompareToBuilder append(Object[] lhs, Object[] rhs) { + return append(lhs, rhs, null); + } + + /** + *

Appends to the builder the deep comparison of + * two Object arrays.

+ * + *
    + *
  1. Check if arrays are the same using ==
  2. + *
  3. Check if for null, null is less than non-null
  4. + *
  5. Check array length, a short length array is less than a long length array
  6. + *
  7. Check array contents element by element using {@link #append(Object, Object, Comparator)}
  8. + *
+ * + *

This method will also will be called for the top level of multi-dimensional, + * ragged, and multi-typed arrays.

+ * + * @param lhs left-hand array + * @param rhs right-hand array + * @param comparator Comparator to use to compare the array elements, + * null means to treat lhs elements as Comparable. + * @return this - used to chain append calls + * @throws ClassCastException if rhs is not assignment-compatible + * with lhs + * @since 2.0 + */ + public CompareToBuilder append(Object[] lhs, Object[] rhs, Comparator comparator) { + if (comparison != 0) { + return this; + } + if (lhs == rhs) { + return this; + } + if (lhs == null) { + comparison = -1; + return this; + } + if (rhs == null) { + comparison = +1; + return this; + } + if (lhs.length != rhs.length) { + comparison = (lhs.length < rhs.length) ? -1 : +1; + return this; + } + for (int i = 0; i < lhs.length && comparison == 0; i++) { + append(lhs[i], rhs[i], comparator); + } + return this; + } + + /** + *

Appends to the builder the deep comparison of + * two long arrays.

+ * + *
    + *
  1. Check if arrays are the same using ==
  2. + *
  3. Check if for null, null is less than non-null
  4. + *
  5. Check array length, a shorter length array is less than a longer length array
  6. + *
  7. Check array contents element by element using {@link #append(long, long)}
  8. + *
+ * + * @param lhs left-hand array + * @param rhs right-hand array + * @return this - used to chain append calls + */ + public CompareToBuilder append(long[] lhs, long[] rhs) { + if (comparison != 0) { + return this; + } + if (lhs == rhs) { + return this; + } + if (lhs == null) { + comparison = -1; + return this; + } + if (rhs == null) { + comparison = +1; + return this; + } + if (lhs.length != rhs.length) { + comparison = (lhs.length < rhs.length) ? -1 : +1; + return this; + } + for (int i = 0; i < lhs.length && comparison == 0; i++) { + append(lhs[i], rhs[i]); + } + return this; + } + + /** + *

Appends to the builder the deep comparison of + * two int arrays.

+ * + *
    + *
  1. Check if arrays are the same using ==
  2. + *
  3. Check if for null, null is less than non-null
  4. + *
  5. Check array length, a shorter length array is less than a longer length array
  6. + *
  7. Check array contents element by element using {@link #append(int, int)}
  8. + *
+ * + * @param lhs left-hand array + * @param rhs right-hand array + * @return this - used to chain append calls + */ + public CompareToBuilder append(int[] lhs, int[] rhs) { + if (comparison != 0) { + return this; + } + if (lhs == rhs) { + return this; + } + if (lhs == null) { + comparison = -1; + return this; + } + if (rhs == null) { + comparison = +1; + return this; + } + if (lhs.length != rhs.length) { + comparison = (lhs.length < rhs.length) ? -1 : +1; + return this; + } + for (int i = 0; i < lhs.length && comparison == 0; i++) { + append(lhs[i], rhs[i]); + } + return this; + } + + /** + *

Appends to the builder the deep comparison of + * two short arrays.

+ * + *
    + *
  1. Check if arrays are the same using ==
  2. + *
  3. Check if for null, null is less than non-null
  4. + *
  5. Check array length, a shorter length array is less than a longer length array
  6. + *
  7. Check array contents element by element using {@link #append(short, short)}
  8. + *
+ * + * @param lhs left-hand array + * @param rhs right-hand array + * @return this - used to chain append calls + */ + public CompareToBuilder append(short[] lhs, short[] rhs) { + if (comparison != 0) { + return this; + } + if (lhs == rhs) { + return this; + } + if (lhs == null) { + comparison = -1; + return this; + } + if (rhs == null) { + comparison = +1; + return this; + } + if (lhs.length != rhs.length) { + comparison = (lhs.length < rhs.length) ? -1 : +1; + return this; + } + for (int i = 0; i < lhs.length && comparison == 0; i++) { + append(lhs[i], rhs[i]); + } + return this; + } + + /** + *

Appends to the builder the deep comparison of + * two char arrays.

+ * + *
    + *
  1. Check if arrays are the same using ==
  2. + *
  3. Check if for null, null is less than non-null
  4. + *
  5. Check array length, a shorter length array is less than a longer length array
  6. + *
  7. Check array contents element by element using {@link #append(char, char)}
  8. + *
+ * + * @param lhs left-hand array + * @param rhs right-hand array + * @return this - used to chain append calls + */ + public CompareToBuilder append(char[] lhs, char[] rhs) { + if (comparison != 0) { + return this; + } + if (lhs == rhs) { + return this; + } + if (lhs == null) { + comparison = -1; + return this; + } + if (rhs == null) { + comparison = +1; + return this; + } + if (lhs.length != rhs.length) { + comparison = (lhs.length < rhs.length) ? -1 : +1; + return this; + } + for (int i = 0; i < lhs.length && comparison == 0; i++) { + append(lhs[i], rhs[i]); + } + return this; + } + + /** + *

Appends to the builder the deep comparison of + * two byte arrays.

+ * + *
    + *
  1. Check if arrays are the same using ==
  2. + *
  3. Check if for null, null is less than non-null
  4. + *
  5. Check array length, a shorter length array is less than a longer length array
  6. + *
  7. Check array contents element by element using {@link #append(byte, byte)}
  8. + *
+ * + * @param lhs left-hand array + * @param rhs right-hand array + * @return this - used to chain append calls + */ + public CompareToBuilder append(byte[] lhs, byte[] rhs) { + if (comparison != 0) { + return this; + } + if (lhs == rhs) { + return this; + } + if (lhs == null) { + comparison = -1; + return this; + } + if (rhs == null) { + comparison = +1; + return this; + } + if (lhs.length != rhs.length) { + comparison = (lhs.length < rhs.length) ? -1 : +1; + return this; + } + for (int i = 0; i < lhs.length && comparison == 0; i++) { + append(lhs[i], rhs[i]); + } + return this; + } + + /** + *

Appends to the builder the deep comparison of + * two double arrays.

+ * + *
    + *
  1. Check if arrays are the same using ==
  2. + *
  3. Check if for null, null is less than non-null
  4. + *
  5. Check array length, a shorter length array is less than a longer length array
  6. + *
  7. Check array contents element by element using {@link #append(double, double)}
  8. + *
+ * + * @param lhs left-hand array + * @param rhs right-hand array + * @return this - used to chain append calls + */ + public CompareToBuilder append(double[] lhs, double[] rhs) { + if (comparison != 0) { + return this; + } + if (lhs == rhs) { + return this; + } + if (lhs == null) { + comparison = -1; + return this; + } + if (rhs == null) { + comparison = +1; + return this; + } + if (lhs.length != rhs.length) { + comparison = (lhs.length < rhs.length) ? -1 : +1; + return this; + } + for (int i = 0; i < lhs.length && comparison == 0; i++) { + append(lhs[i], rhs[i]); + } + return this; + } + + /** + *

Appends to the builder the deep comparison of + * two float arrays.

+ * + *
    + *
  1. Check if arrays are the same using ==
  2. + *
  3. Check if for null, null is less than non-null
  4. + *
  5. Check array length, a shorter length array is less than a longer length array
  6. + *
  7. Check array contents element by element using {@link #append(float, float)}
  8. + *
+ * + * @param lhs left-hand array + * @param rhs right-hand array + * @return this - used to chain append calls + */ + public CompareToBuilder append(float[] lhs, float[] rhs) { + if (comparison != 0) { + return this; + } + if (lhs == rhs) { + return this; + } + if (lhs == null) { + comparison = -1; + return this; + } + if (rhs == null) { + comparison = +1; + return this; + } + if (lhs.length != rhs.length) { + comparison = (lhs.length < rhs.length) ? -1 : +1; + return this; + } + for (int i = 0; i < lhs.length && comparison == 0; i++) { + append(lhs[i], rhs[i]); + } + return this; + } + + /** + *

Appends to the builder the deep comparison of + * two boolean arrays.

+ * + *
    + *
  1. Check if arrays are the same using ==
  2. + *
  3. Check if for null, null is less than non-null
  4. + *
  5. Check array length, a shorter length array is less than a longer length array
  6. + *
  7. Check array contents element by element using {@link #append(boolean, boolean)}
  8. + *
+ * + * @param lhs left-hand array + * @param rhs right-hand array + * @return this - used to chain append calls + */ + public CompareToBuilder append(boolean[] lhs, boolean[] rhs) { + if (comparison != 0) { + return this; + } + if (lhs == rhs) { + return this; + } + if (lhs == null) { + comparison = -1; + return this; + } + if (rhs == null) { + comparison = +1; + return this; + } + if (lhs.length != rhs.length) { + comparison = (lhs.length < rhs.length) ? -1 : +1; + return this; + } + for (int i = 0; i < lhs.length && comparison == 0; i++) { + append(lhs[i], rhs[i]); + } + return this; + } + + //----------------------------------------------------------------------- + /** + * Returns a negative integer, a positive integer, or zero as + * the builder has judged the "left-hand" side + * as less than, greater than, or equal to the "right-hand" + * side. + * + * @return final comparison result + */ + public int toComparison() { + return comparison; + } + +} + Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/builder/EqualsBuilder.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/builder/EqualsBuilder.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/builder/EqualsBuilder.java 30 Aug 2012 16:24:43 -0000 1.1 @@ -0,0 +1,781 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.builder; + +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + +/** + *

Assists in implementing {@link Object#equals(Object)} methods.

+ * + *

This class provides methods to build a good equals method for any + * class. It follows rules laid out in + * Effective Java + * , by Joshua Bloch. In particular the rule for comparing doubles, + * floats, and arrays can be tricky. Also, making sure that + * equals() and hashCode() are consistent can be + * difficult.

+ * + *

Two Objects that compare as equals must generate the same hash code, + * but two Objects with the same hash code do not have to be equal.

+ * + *

All relevant fields should be included in the calculation of equals. + * Derived fields may be ignored. In particular, any field used in + * generating a hash code must be used in the equals method, and vice + * versa.

+ * + *

Typical use for the code is as follows:

+ *
+ * public boolean equals(Object o) {
+ *   if ( !(o instanceof MyClass) ) {
+ *    return false;
+ *   }
+ *  MyClass rhs = (MyClass) o;
+ *  return new EqualsBuilder()
+ *                 .appendSuper(super.equals(o))
+ *                 .append(field1, rhs.field1)
+ *                 .append(field2, rhs.field2)
+ *                 .append(field3, rhs.field3)
+ *                 .isEquals();
+ *  }
+ * 
+ * + *

Alternatively, there is a method that uses reflection to determine + * the fields to test. Because these fields are usually private, the method, + * reflectionEquals, uses AccessibleObject.setAccessible to + * change the visibility of the fields. This will fail under a security + * manager, unless the appropriate permissions are set up correctly. It is + * also slower than testing explicitly.

+ * + *

A typical invocation for this method would look like:

+ *
+ * public boolean equals(Object o) {
+ *   return EqualsBuilder.reflectionEquals(this, o);
+ * }
+ * 
+ * + * @author Steve Downey + * @author Stephen Colebourne + * @author Gary Gregory + * @author Pete Gieser + * @since 1.0 + * @version $Id: EqualsBuilder.java,v 1.1 2012/08/30 16:24:43 marcin Exp $ + */ +public class EqualsBuilder { + /** + * If the fields tested are equals. + */ + private boolean isEquals; + + /** + *

Constructor for EqualsBuilder.

+ * + *

Starts off assuming that equals is true.

+ * @see java.lang.Object#equals + */ + public EqualsBuilder() { + super(); + isEquals = true; + } + + //------------------------------------------------------------------------- + + /** + *

This method uses reflection to determine if the two Objects + * are equal.

+ * + *

It uses AccessibleObject.setAccessible to gain access to private + * fields. This means that it will throw a security exception if run under + * a security manager, if the permissions are not set up correctly. It is also + * not as efficient as testing explicitly.

+ * + *

Transient members will be not be tested, as they are likely derived + * fields, and not part of the value of the Object.

+ * + *

Static fields will not be tested. Superclass fields will be included.

+ * + * @param lhs this object + * @param rhs the other object + * @return true if the two Objects have tested equals. + */ + public static boolean reflectionEquals(Object lhs, Object rhs) { + return reflectionEquals(lhs, rhs, false, null); + } + + /** + *

This method uses reflection to determine if the two Objects + * are equal.

+ * + *

It uses AccessibleObject.setAccessible to gain access to private + * fields. This means that it will throw a security exception if run under + * a security manager, if the permissions are not set up correctly. It is also + * not as efficient as testing explicitly.

+ * + *

If the TestTransients parameter is set to true, transient + * members will be tested, otherwise they are ignored, as they are likely + * derived fields, and not part of the value of the Object.

+ * + *

Static fields will not be tested. Superclass fields will be included.

+ * + * @param lhs this object + * @param rhs the other object + * @param testTransients whether to include transient fields + * @return true if the two Objects have tested equals. + */ + public static boolean reflectionEquals(Object lhs, Object rhs, boolean testTransients) { + return reflectionEquals(lhs, rhs, testTransients, null); + } + + /** + *

This method uses reflection to determine if the two Objects + * are equal.

+ * + *

It uses AccessibleObject.setAccessible to gain access to private + * fields. This means that it will throw a security exception if run under + * a security manager, if the permissions are not set up correctly. It is also + * not as efficient as testing explicitly.

+ * + *

If the testTransients parameter is set to true, transient + * members will be tested, otherwise they are ignored, as they are likely + * derived fields, and not part of the value of the Object.

+ * + *

Static fields will not be included. Superclass fields will be appended + * up to and including the specified superclass. A null superclass is treated + * as java.lang.Object.

+ * + * @param lhs this object + * @param rhs the other object + * @param testTransients whether to include transient fields + * @param reflectUpToClass the superclass to reflect up to (inclusive), + * may be null + * @return true if the two Objects have tested equals. + * @since 2.0 + */ + public static boolean reflectionEquals(Object lhs, Object rhs, boolean testTransients, Class reflectUpToClass) { + if (lhs == rhs) { + return true; + } + if (lhs == null || rhs == null) { + return false; + } + // Find the leaf class since there may be transients in the leaf + // class or in classes between the leaf and root. + // If we are not testing transients or a subclass has no ivars, + // then a subclass can test equals to a superclass. + Class lhsClass = lhs.getClass(); + Class rhsClass = rhs.getClass(); + Class testClass; + if (lhsClass.isInstance(rhs)) { + testClass = lhsClass; + if (!rhsClass.isInstance(lhs)) { + // rhsClass is a subclass of lhsClass + testClass = rhsClass; + } + } else if (rhsClass.isInstance(lhs)) { + testClass = rhsClass; + if (!lhsClass.isInstance(rhs)) { + // lhsClass is a subclass of rhsClass + testClass = lhsClass; + } + } else { + // The two classes are not related. + return false; + } + EqualsBuilder equalsBuilder = new EqualsBuilder(); + try { + reflectionAppend(lhs, rhs, testClass, equalsBuilder, testTransients); + while (testClass.getSuperclass() != null && testClass != reflectUpToClass) { + testClass = testClass.getSuperclass(); + reflectionAppend(lhs, rhs, testClass, equalsBuilder, testTransients); + } + } catch (IllegalArgumentException e) { + // In this case, we tried to test a subclass vs. a superclass and + // the subclass has ivars or the ivars are transient and + // we are testing transients. + // If a subclass has ivars that we are trying to test them, we get an + // exception and we know that the objects are not equal. + return false; + } + return equalsBuilder.isEquals(); + } + + /** + *

Appends the fields and values defined by the given object of the + * given Class.

+ * + * @param lhs the left hand object + * @param rhs the right hand object + * @param clazz the class to append details of + * @param builder the builder to append to + * @param useTransients whether to test transient fields + */ + private static void reflectionAppend( + Object lhs, + Object rhs, + Class clazz, + EqualsBuilder builder, + boolean useTransients) { + Field[] fields = clazz.getDeclaredFields(); + AccessibleObject.setAccessible(fields, true); + for (int i = 0; i < fields.length && builder.isEquals; i++) { + Field f = fields[i]; + if ((f.getName().indexOf('$') == -1) + && (useTransients || !Modifier.isTransient(f.getModifiers())) + && (!Modifier.isStatic(f.getModifiers()))) { + try { + builder.append(f.get(lhs), f.get(rhs)); + } catch (IllegalAccessException e) { + //this can't happen. Would get a Security exception instead + //throw a runtime exception in case the impossible happens. + throw new InternalError("Unexpected IllegalAccessException"); + } + } + } + } + + //------------------------------------------------------------------------- + + /** + *

Adds the result of super.equals() to this builder.

+ * + * @param superEquals the result of calling super.equals() + * @return EqualsBuilder - used to chain calls. + * @since 2.0 + */ + public EqualsBuilder appendSuper(boolean superEquals) { + if (isEquals == false) { + return this; + } + isEquals = superEquals; + return this; + } + + //------------------------------------------------------------------------- + + /** + *

Test if two Objects are equal using their + * equals method.

+ * + * @param lhs the left hand object + * @param rhs the right hand object + * @return EqualsBuilder - used to chain calls. + */ + public EqualsBuilder append(Object lhs, Object rhs) { + if (isEquals == false) { + return this; + } + if (lhs == rhs) { + return this; + } + if (lhs == null || rhs == null) { + isEquals = false; + return this; + } + Class lhsClass = lhs.getClass(); + if (!lhsClass.isArray()) { + //the simple case, not an array, just test the element + isEquals = lhs.equals(rhs); + } else { + //'Switch' on type of array, to dispatch to the correct handler + // This handles multi dimensional arrays + if (lhs instanceof long[]) { + append((long[]) lhs, (long[]) rhs); + } else if (lhs instanceof int[]) { + append((int[]) lhs, (int[]) rhs); + } else if (lhs instanceof short[]) { + append((short[]) lhs, (short[]) rhs); + } else if (lhs instanceof char[]) { + append((char[]) lhs, (char[]) rhs); + } else if (lhs instanceof byte[]) { + append((byte[]) lhs, (byte[]) rhs); + } else if (lhs instanceof double[]) { + append((double[]) lhs, (double[]) rhs); + } else if (lhs instanceof float[]) { + append((float[]) lhs, (float[]) rhs); + } else if (lhs instanceof boolean[]) { + append((boolean[]) lhs, (boolean[]) rhs); + } else { + // Not an array of primitives + append((Object[]) lhs, (Object[]) rhs); + } + } + return this; + } + + /** + *

Test if two longs are equal.

+ * + * @param lhs the left hand long + * @param rhs the right hand long + * @return EqualsBuilder - used to chain calls. + */ + public EqualsBuilder append(long lhs, long rhs) { + if (isEquals == false) { + return this; + } + isEquals = (lhs == rhs); + return this; + } + + /** + *

Test if two ints are equal.

+ * + * @param lhs the left hand int + * @param rhs the right hand int + * @return EqualsBuilder - used to chain calls. + */ + public EqualsBuilder append(int lhs, int rhs) { + if (isEquals == false) { + return this; + } + isEquals = (lhs == rhs); + return this; + } + + /** + *

Test if two shorts are equal.

+ * + * @param lhs the left hand short + * @param rhs the right hand short + * @return EqualsBuilder - used to chain calls. + */ + public EqualsBuilder append(short lhs, short rhs) { + if (isEquals == false) { + return this; + } + isEquals = (lhs == rhs); + return this; + } + + /** + *

Test if two chars are equal.

+ * + * @param lhs the left hand char + * @param rhs the right hand char + * @return EqualsBuilder - used to chain calls. + */ + public EqualsBuilder append(char lhs, char rhs) { + if (isEquals == false) { + return this; + } + isEquals = (lhs == rhs); + return this; + } + + /** + *

Test if two bytes are equal.

+ * + * @param lhs the left hand byte + * @param rhs the right hand byte + * @return EqualsBuilder - used to chain calls. + */ + public EqualsBuilder append(byte lhs, byte rhs) { + if (isEquals == false) { + return this; + } + isEquals = (lhs == rhs); + return this; + } + + /** + *

Test if two doubles are equal by testing that the + * pattern of bits returned by doubleToLong are equal.

+ * + *

This handles NaNs, Infinties, and -0.0.

+ * + *

It is compatible with the hash code generated by + * HashCodeBuilder.

+ * + * @param lhs the left hand double + * @param rhs the right hand double + * @return EqualsBuilder - used to chain calls. + */ + public EqualsBuilder append(double lhs, double rhs) { + if (isEquals == false) { + return this; + } + return append(Double.doubleToLongBits(lhs), Double.doubleToLongBits(rhs)); + } + + /** + *

Test if two floats are equal byt testing that the + * pattern of bits returned by doubleToLong are equal.

+ * + *

This handles NaNs, Infinties, and -0.0.

+ * + *

It is compatible with the hash code generated by + * HashCodeBuilder.

+ * + * @param lhs the left hand float + * @param rhs the right hand float + * @return EqualsBuilder - used to chain calls. + */ + public EqualsBuilder append(float lhs, float rhs) { + if (isEquals == false) { + return this; + } + return append(Float.floatToIntBits(lhs), Float.floatToIntBits(rhs)); + } + + /** + *

Test if two booleanss are equal.

+ * + * @param lhs the left hand boolean + * @param rhs the right hand boolean + * @return EqualsBuilder - used to chain calls. + */ + public EqualsBuilder append(boolean lhs, boolean rhs) { + if (isEquals == false) { + return this; + } + isEquals = (lhs == rhs); + return this; + } + + /** + *

Performs a deep comparison of two Object arrays.

+ * + *

This also will be called for the top level of + * multi-dimensional, ragged, and multi-typed arrays.

+ * + * @param lhs the left hand Object[] + * @param rhs the right hand Object[] + * @return EqualsBuilder - used to chain calls. + */ + public EqualsBuilder append(Object[] lhs, Object[] rhs) { + if (isEquals == false) { + return this; + } + if (lhs == rhs) { + return this; + } + if (lhs == null || rhs == null) { + isEquals = false; + return this; + } + if (lhs.length != rhs.length) { + isEquals = false; + return this; + } + for (int i = 0; i < lhs.length && isEquals; ++i) { + Class lhsClass = lhs[i].getClass(); + if (!lhsClass.isInstance(rhs[i])) { + isEquals = false; //If the types don't match, not equal + break; + } + append(lhs[i], rhs[i]); + } + return this; + } + + /** + *

Deep comparison of array of long. Length and all + * values are compared.

+ * + *

The method {@link #append(long, long)} is used.

+ * + * @param lhs the left hand long[] + * @param rhs the right hand long[] + * @return EqualsBuilder - used to chain calls. + */ + public EqualsBuilder append(long[] lhs, long[] rhs) { + if (isEquals == false) { + return this; + } + if (lhs == rhs) { + return this; + } + if (lhs == null || rhs == null) { + isEquals = false; + return this; + } + if (lhs.length != rhs.length) { + isEquals = false; + return this; + } + for (int i = 0; i < lhs.length && isEquals; ++i) { + append(lhs[i], rhs[i]); + } + return this; + } + + /** + *

Deep comparison of array of int. Length and all + * values are compared.

+ * + *

The method {@link #append(int, int)} is used.

+ * + * @param lhs the left hand int[] + * @param rhs the right hand int[] + * @return EqualsBuilder - used to chain calls. + */ + public EqualsBuilder append(int[] lhs, int[] rhs) { + if (isEquals == false) { + return this; + } + if (lhs == rhs) { + return this; + } + if (lhs == null || rhs == null) { + isEquals = false; + return this; + } + if (lhs.length != rhs.length) { + isEquals = false; + return this; + } + for (int i = 0; i < lhs.length && isEquals; ++i) { + append(lhs[i], rhs[i]); + } + return this; + } + + /** + *

Deep comparison of array of short. Length and all + * values are compared.

+ * + *

The method {@link #append(short, short)} is used.

+ * + * @param lhs the left hand short[] + * @param rhs the right hand short[] + * @return EqualsBuilder - used to chain calls. + */ + public EqualsBuilder append(short[] lhs, short[] rhs) { + if (isEquals == false) { + return this; + } + if (lhs == rhs) { + return this; + } + if (lhs == null || rhs == null) { + isEquals = false; + return this; + } + if (lhs.length != rhs.length) { + isEquals = false; + return this; + } + for (int i = 0; i < lhs.length && isEquals; ++i) { + append(lhs[i], rhs[i]); + } + return this; + } + + /** + *

Deep comparison of array of char. Length and all + * values are compared.

+ * + *

The method {@link #append(char, char)} is used.

+ * + * @param lhs the left hand char[] + * @param rhs the right hand char[] + * @return EqualsBuilder - used to chain calls. + */ + public EqualsBuilder append(char[] lhs, char[] rhs) { + if (isEquals == false) { + return this; + } + if (lhs == rhs) { + return this; + } + if (lhs == null || rhs == null) { + isEquals = false; + return this; + } + if (lhs.length != rhs.length) { + isEquals = false; + return this; + } + for (int i = 0; i < lhs.length && isEquals; ++i) { + append(lhs[i], rhs[i]); + } + return this; + } + + /** + *

Deep comparison of array of byte. Length and all + * values are compared.

+ * + *

The method {@link #append(byte, byte)} is used.

+ * + * @param lhs the left hand byte[] + * @param rhs the right hand byte[] + * @return EqualsBuilder - used to chain calls. + */ + public EqualsBuilder append(byte[] lhs, byte[] rhs) { + if (isEquals == false) { + return this; + } + if (lhs == rhs) { + return this; + } + if (lhs == null || rhs == null) { + isEquals = false; + return this; + } + if (lhs.length != rhs.length) { + isEquals = false; + return this; + } + for (int i = 0; i < lhs.length && isEquals; ++i) { + append(lhs[i], rhs[i]); + } + return this; + } + + /** + *

Deep comparison of array of double. Length and all + * values are compared.

+ * + *

The method {@link #append(double, double)} is used.

+ * + * @param lhs the left hand double[] + * @param rhs the right hand double[] + * @return EqualsBuilder - used to chain calls. + */ + public EqualsBuilder append(double[] lhs, double[] rhs) { + if (isEquals == false) { + return this; + } + if (lhs == rhs) { + return this; + } + if (lhs == null || rhs == null) { + isEquals = false; + return this; + } + if (lhs.length != rhs.length) { + isEquals = false; + return this; + } + for (int i = 0; i < lhs.length && isEquals; ++i) { + append(lhs[i], rhs[i]); + } + return this; + } + + /** + *

Deep comparison of array of float. Length and all + * values are compared.

+ * + *

The method {@link #append(float, float)} is used.

+ * + * @param lhs the left hand float[] + * @param rhs the right hand float[] + * @return EqualsBuilder - used to chain calls. + */ + public EqualsBuilder append(float[] lhs, float[] rhs) { + if (isEquals == false) { + return this; + } + if (lhs == rhs) { + return this; + } + if (lhs == null || rhs == null) { + isEquals = false; + return this; + } + if (lhs.length != rhs.length) { + isEquals = false; + return this; + } + for (int i = 0; i < lhs.length && isEquals; ++i) { + append(lhs[i], rhs[i]); + } + return this; + } + + /** + *

Deep comparison of array of boolean. Length and all + * values are compared.

+ * + *

The method {@link #append(boolean, boolean)} is used.

+ * + * @param lhs the left hand boolean[] + * @param rhs the right hand boolean[] + * @return EqualsBuilder - used to chain calls. + */ + public EqualsBuilder append(boolean[] lhs, boolean[] rhs) { + if (isEquals == false) { + return this; + } + if (lhs == rhs) { + return this; + } + if (lhs == null || rhs == null) { + isEquals = false; + return this; + } + if (lhs.length != rhs.length) { + isEquals = false; + return this; + } + for (int i = 0; i < lhs.length && isEquals; ++i) { + append(lhs[i], rhs[i]); + } + return this; + } + + /** + *

Return true if the fields that have been checked + * are all equal.

+ * + * @return boolean + */ + public boolean isEquals() { + return isEquals; + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/builder/HashCodeBuilder.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/builder/HashCodeBuilder.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/builder/HashCodeBuilder.java 30 Aug 2012 16:24:43 -0000 1.1 @@ -0,0 +1,671 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.builder; + +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + +/** + *

Assists in implementing {@link Object#hashCode()} methods.

+ * + *

This class enables a good hashCode method to be built for any class. It + * follows the rules laid out in the book + * Effective Java + * by Joshua Bloch. Writing a good hashCode method is actually quite + * difficult. This class aims to simplify the process.

+ * + *

All relevant fields from the object should be included in the + * hashCode method. Derived fields may be excluded. In general, any + * field used in the equals method must be used in the hashCode + * method.

+ * + *

To use this class write code as follows:

+ *
+ * public class Person {
+ *   String name;
+ *   int age;
+ *   boolean isSmoker;
+ *   ...
+ *
+ *   public int hashCode() {
+ *     // you pick a hard-coded, randomly chosen, non-zero, odd number
+ *     // ideally different for each class
+ *     return new HashCodeBuilder(17, 37).
+ *       append(name).
+ *       append(age).
+ *       append(smoker).
+ *       toHashCode();
+ *   }
+ * }
+ * 
+ * + *

If required, the superclass hashCode() can be added + * using {@link #appendSuper}.

+ * + *

Alternatively, there is a method that uses reflection to determine + * the fields to test. Because these fields are usually private, the method, + * reflectionHashCode, uses AccessibleObject.setAccessible to + * change the visibility of the fields. This will fail under a security manager, + * unless the appropriate permissions are set up correctly. It is also slower + * than testing explicitly.

+ * + *

A typical invocation for this method would look like:

+ *
+ * public int hashCode() {
+ *   return HashCodeBuilder.reflectionHashCode(this);
+ * }
+ * 
+ * + * @author Stephen Colebourne + * @author Gary Gregory + * @author Pete Gieser + * @since 1.0 + * @version $Id: HashCodeBuilder.java,v 1.1 2012/08/30 16:24:43 marcin Exp $ + */ +public class HashCodeBuilder { + + /** + * Constant to use in building the hashCode. + */ + private final int iConstant; + /** + * Running total of the hashCode. + */ + private int iTotal = 0; + + /** + *

Constructor.

+ * + *

This constructor uses two hard coded choices for the constants + * needed to build a hashCode.

+ */ + public HashCodeBuilder() { + super(); + iConstant = 37; + iTotal = 17; + } + + /** + *

Constructor.

+ * + *

Two randomly chosen, non-zero, odd numbers must be passed in. + * Ideally these should be different for each class, however this is + * not vital.

+ * + *

Prime numbers are preferred, especially for the multiplier.

+ * + * @param initialNonZeroOddNumber a non-zero, odd number used as the initial value + * @param multiplierNonZeroOddNumber a non-zero, odd number used as the multiplier + * @throws IllegalArgumentException if the number is zero or even + */ + public HashCodeBuilder(int initialNonZeroOddNumber, int multiplierNonZeroOddNumber) { + super(); + if (initialNonZeroOddNumber == 0) { + throw new IllegalArgumentException("HashCodeBuilder requires a non zero initial value"); + } + if (initialNonZeroOddNumber % 2 == 0) { + throw new IllegalArgumentException("HashCodeBuilder requires an odd initial value"); + } + if (multiplierNonZeroOddNumber == 0) { + throw new IllegalArgumentException("HashCodeBuilder requires a non zero multiplier"); + } + if (multiplierNonZeroOddNumber % 2 == 0) { + throw new IllegalArgumentException("HashCodeBuilder requires an odd multiplier"); + } + iConstant = multiplierNonZeroOddNumber; + iTotal = initialNonZeroOddNumber; + } + + //------------------------------------------------------------------------- + + /** + *

This method uses reflection to build a valid hash code.

+ * + *

This constructor uses two hard coded choices for the constants + * needed to build a hash code.

+ * + *

It uses AccessibleObject.setAccessible to gain access to private + * fields. This means that it will throw a security exception if run under + * a security manager, if the permissions are not set up correctly. It is + * also not as efficient as testing explicitly.

+ * + *

Transient members will be not be used, as they are likely derived + * fields, and not part of the value of the Object.

+ * + *

Static fields will not be tested. Superclass fields will be included.

+ * + * @param object the Object to create a hashCode for + * @return int hash code + * @throws IllegalArgumentException if the object is null + */ + public static int reflectionHashCode(Object object) { + return reflectionHashCode(17, 37, object, false, null); + } + + /** + *

This method uses reflection to build a valid hash code.

+ * + *

This constructor uses two hard coded choices for the constants needed + * to build a hash code.

+ * + *

It uses AccessibleObject.setAccessible to gain access to private + * fields. This means that it will throw a security exception if run under + * a security manager, if the permissions are not set up correctly. It is + * also not as efficient as testing explicitly.

+ * + *

If the TestTransients parameter is set to true, transient + * members will be tested, otherwise they are ignored, as they are likely + * derived fields, and not part of the value of the Object.

+ * + *

Static fields will not be tested. Superclass fields will be included.

+ * + * @param object the Object to create a hashCode for + * @param testTransients whether to include transient fields + * @return int hash code + * @throws IllegalArgumentException if the object is null + */ + public static int reflectionHashCode(Object object, boolean testTransients) { + return reflectionHashCode(17, 37, object, testTransients, null); + } + + /** + *

This method uses reflection to build a valid hash code.

+ * + *

It uses AccessibleObject.setAccessible to gain access to private + * fields. This means that it will throw a security exception if run under + * a security manager, if the permissions are not set up correctly. It is + * also not as efficient as testing explicitly.

+ * + *

Transient members will be not be used, as they are likely derived + * fields, and not part of the value of the Object.

+ * + *

Static fields will not be tested. Superclass fields will be included.

+ * + *

Two randomly chosen, non-zero, odd numbers must be passed in. Ideally + * these should be different for each class, however this is not vital. + * Prime numbers are preferred, especially for the multiplier.

+ * + * @param initialNonZeroOddNumber a non-zero, odd number used as the initial value + * @param multiplierNonZeroOddNumber a non-zero, odd number used as the multiplier + * @param object the Object to create a hashCode for + * @return int hash code + * @throws IllegalArgumentException if the Object is null + * @throws IllegalArgumentException if the number is zero or even + */ + public static int reflectionHashCode( + int initialNonZeroOddNumber, int multiplierNonZeroOddNumber, Object object) { + return reflectionHashCode(initialNonZeroOddNumber, multiplierNonZeroOddNumber, object, false, null); + } + + /** + *

This method uses reflection to build a valid hash code.

+ * + *

It uses AccessibleObject.setAccessible to gain access to private + * fields. This means that it will throw a security exception if run under + * a security manager, if the permissions are not set up correctly. It is also + * not as efficient as testing explicitly.

+ * + *

If the TestTransients parameter is set to true, transient + * members will be tested, otherwise they are ignored, as they are likely + * derived fields, and not part of the value of the Object.

+ * + *

Static fields will not be tested. Superclass fields will be included.

+ * + *

Two randomly chosen, non-zero, odd numbers must be passed in. Ideally + * these should be different for each class, however this is not vital. + * Prime numbers are preferred, especially for the multiplier.

+ * + * @param initialNonZeroOddNumber a non-zero, odd number used as the initial value + * @param multiplierNonZeroOddNumber a non-zero, odd number used as the multiplier + * @param object the Object to create a hashCode for + * @param testTransients whether to include transient fields + * @return int hash code + * @throws IllegalArgumentException if the Object is null + * @throws IllegalArgumentException if the number is zero or even + */ + public static int reflectionHashCode( + int initialNonZeroOddNumber, int multiplierNonZeroOddNumber, + Object object, boolean testTransients) { + return reflectionHashCode(initialNonZeroOddNumber, multiplierNonZeroOddNumber, object, testTransients, null); + } + + /** + *

This method uses reflection to build a valid hash code.

+ * + *

It uses AccessibleObject.setAccessible to gain access to private + * fields. This means that it will throw a security exception if run under + * a security manager, if the permissions are not set up correctly. It is also + * not as efficient as testing explicitly.

+ * + *

If the TestTransients parameter is set to true, transient + * members will be tested, otherwise they are ignored, as they are likely + * derived fields, and not part of the value of the Object.

+ * + *

Static fields will not be included. Superclass fields will be included + * up to and including the specified superclass. A null superclass is treated + * as java.lang.Object.

+ * + *

Two randomly chosen, non-zero, odd numbers must be passed in. Ideally + * these should be different for each class, however this is not vital. + * Prime numbers are preferred, especially for the multiplier.

+ * + * @param initialNonZeroOddNumber a non-zero, odd number used as the initial value + * @param multiplierNonZeroOddNumber a non-zero, odd number used as the multiplier + * @param object the Object to create a hashCode for + * @param testTransients whether to include transient fields + * @param reflectUpToClass the superclass to reflect up to (inclusive), + * may be null + * @return int hash code + * @throws IllegalArgumentException if the Object is null + * @throws IllegalArgumentException if the number is zero or even + * @since 2.0 + */ + public static int reflectionHashCode( + int initialNonZeroOddNumber, + int multiplierNonZeroOddNumber, + Object object, + boolean testTransients, + Class reflectUpToClass) { + + if (object == null) { + throw new IllegalArgumentException("The object to build a hash code for must not be null"); + } + HashCodeBuilder builder = new HashCodeBuilder(initialNonZeroOddNumber, multiplierNonZeroOddNumber); + Class clazz = object.getClass(); + reflectionAppend(object, clazz, builder, testTransients); + while (clazz.getSuperclass() != null && clazz != reflectUpToClass) { + clazz = clazz.getSuperclass(); + reflectionAppend(object, clazz, builder, testTransients); + } + return builder.toHashCode(); + } + + /** + *

Appends the fields and values defined by the given object of the + * given Class.

+ * + * @param object the object to append details of + * @param clazz the class to append details of + * @param builder the builder to append to + * @param useTransients whether to use transient fields + */ + private static void reflectionAppend(Object object, Class clazz, HashCodeBuilder builder, boolean useTransients) { + Field[] fields = clazz.getDeclaredFields(); + AccessibleObject.setAccessible(fields, true); + for (int i = 0; i < fields.length; i++) { + Field f = fields[i]; + if ((f.getName().indexOf('$') == -1) + && (useTransients || !Modifier.isTransient(f.getModifiers())) + && (!Modifier.isStatic(f.getModifiers()))) { + try { + builder.append(f.get(object)); + } catch (IllegalAccessException e) { + //this can't happen. Would get a Security exception instead + //throw a runtime exception in case the impossible happens. + throw new InternalError("Unexpected IllegalAccessException"); + } + } + } + } + + //------------------------------------------------------------------------- + + /** + *

Adds the result of super.hashCode() to this builder.

+ * + * @param superHashCode the result of calling super.hashCode() + * @return this HashCodeBuilder, used to chain calls. + * @since 2.0 + */ + public HashCodeBuilder appendSuper(int superHashCode) { + iTotal = iTotal * iConstant + superHashCode; + return this; + } + + //------------------------------------------------------------------------- + + /** + *

Append a hashCode for an Object.

+ * + * @param object the Object to add to the hashCode + * @return this + */ + public HashCodeBuilder append(Object object) { + if (object == null) { + iTotal = iTotal * iConstant; + + } else { + if (object.getClass().isArray() == false) { + //the simple case, not an array, just the element + iTotal = iTotal * iConstant + object.hashCode(); + + } else { + //'Switch' on type of array, to dispatch to the correct handler + // This handles multi dimensional arrays + if (object instanceof long[]) { + append((long[]) object); + } else if (object instanceof int[]) { + append((int[]) object); + } else if (object instanceof short[]) { + append((short[]) object); + } else if (object instanceof char[]) { + append((char[]) object); + } else if (object instanceof byte[]) { + append((byte[]) object); + } else if (object instanceof double[]) { + append((double[]) object); + } else if (object instanceof float[]) { + append((float[]) object); + } else if (object instanceof boolean[]) { + append((boolean[]) object); + } else { + // Not an array of primitives + append((Object[]) object); + } + } + } + return this; + } + + /** + *

Append a hashCode for a long.

+ * + * @param value the long to add to the hashCode + * @return this + */ + public HashCodeBuilder append(long value) { + iTotal = iTotal * iConstant + ((int) (value ^ (value >> 32))); + return this; + } + + /** + *

Append a hashCode for an int.

+ * + * @param value the int to add to the hashCode + * @return this + */ + public HashCodeBuilder append(int value) { + iTotal = iTotal * iConstant + value; + return this; + } + + /** + *

Append a hashCode for a short.

+ * + * @param value the short to add to the hashCode + * @return this + */ + public HashCodeBuilder append(short value) { + iTotal = iTotal * iConstant + value; + return this; + } + + /** + *

Append a hashCode for a char.

+ * + * @param value the char to add to the hashCode + * @return this + */ + public HashCodeBuilder append(char value) { + iTotal = iTotal * iConstant + value; + return this; + } + + /** + *

Append a hashCode for a byte.

+ * + * @param value the byte to add to the hashCode + * @return this + */ + public HashCodeBuilder append(byte value) { + iTotal = iTotal * iConstant + value; + return this; + } + + /** + *

Append a hashCode for a double.

+ * + * @param value the double to add to the hashCode + * @return this + */ + public HashCodeBuilder append(double value) { + return append(Double.doubleToLongBits(value)); + } + + /** + *

Append a hashCode for a float.

+ * + * @param value the float to add to the hashCode + * @return this + */ + public HashCodeBuilder append(float value) { + iTotal = iTotal * iConstant + Float.floatToIntBits(value); + return this; + } + + /** + *

Append a hashCode for a boolean.

+ * + * @param value the boolean to add to the hashCode + * @return this + */ + public HashCodeBuilder append(boolean value) { + iTotal = iTotal * iConstant + (value ? 0 : 1); + return this; + } + + /** + *

Append a hashCode for an Object array.

+ * + * @param array the array to add to the hashCode + * @return this + */ + public HashCodeBuilder append(Object[] array) { + if (array == null) { + iTotal = iTotal * iConstant; + } else { + for (int i = 0; i < array.length; i++) { + append(array[i]); + } + } + return this; + } + + /** + *

Append a hashCode for a long array.

+ * + * @param array the array to add to the hashCode + * @return this + */ + public HashCodeBuilder append(long[] array) { + if (array == null) { + iTotal = iTotal * iConstant; + } else { + for (int i = 0; i < array.length; i++) { + append(array[i]); + } + } + return this; + } + + /** + *

Append a hashCode for an int array.

+ * + * @param array the array to add to the hashCode + * @return this + */ + public HashCodeBuilder append(int[] array) { + if (array == null) { + iTotal = iTotal * iConstant; + } else { + for (int i = 0; i < array.length; i++) { + append(array[i]); + } + } + return this; + } + + /** + *

Append a hashCode for a short array.

+ * + * @param array the array to add to the hashCode + * @return this + */ + public HashCodeBuilder append(short[] array) { + if (array == null) { + iTotal = iTotal * iConstant; + } else { + for (int i = 0; i < array.length; i++) { + append(array[i]); + } + } + return this; + } + + /** + *

Append a hashCode for a char array.

+ * + * @param array the array to add to the hashCode + * @return this + */ + public HashCodeBuilder append(char[] array) { + if (array == null) { + iTotal = iTotal * iConstant; + } else { + for (int i = 0; i < array.length; i++) { + append(array[i]); + } + } + return this; + } + + /** + *

Append a hashCode for a byte array.

+ * + * @param array the array to add to the hashCode + * @return this + */ + public HashCodeBuilder append(byte[] array) { + if (array == null) { + iTotal = iTotal * iConstant; + } else { + for (int i = 0; i < array.length; i++) { + append(array[i]); + } + } + return this; + } + + /** + *

Append a hashCode for a double array.

+ * + * @param array the array to add to the hashCode + * @return this + */ + public HashCodeBuilder append(double[] array) { + if (array == null) { + iTotal = iTotal * iConstant; + } else { + for (int i = 0; i < array.length; i++) { + append(array[i]); + } + } + return this; + } + + /** + *

Append a hashCode for a float array.

+ * + * @param array the array to add to the hashCode + * @return this + */ + public HashCodeBuilder append(float[] array) { + if (array == null) { + iTotal = iTotal * iConstant; + } else { + for (int i = 0; i < array.length; i++) { + append(array[i]); + } + } + return this; + } + + /** + *

Append a hashCode for a boolean array.

+ * + * @param array the array to add to the hashCode + * @return this + */ + public HashCodeBuilder append(boolean[] array) { + if (array == null) { + iTotal = iTotal * iConstant; + } else { + for (int i = 0; i < array.length; i++) { + append(array[i]); + } + } + return this; + } + + /** + *

Return the computed hashCode.

+ * + * @return hashCode based on the fields appended + */ + public int toHashCode() { + return iTotal; + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/builder/ReflectionToStringBuilder.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/builder/ReflectionToStringBuilder.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/builder/ReflectionToStringBuilder.java 30 Aug 2012 16:24:43 -0000 1.1 @@ -0,0 +1,535 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.builder; + +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.HashSet; +import java.util.Set; + +import org.apache.commons.lang.ClassUtils; + +/** + *

Assists in implementing {@link Object#toString()} methods using reflection.

+ * + *

This class uses reflection to determine the fields to append. + * Because these fields are usually private, the class + * uses AccessibleObject.setAccessible to + * change the visibility of the fields. This will fail under a security manager, + * unless the appropriate permissions are set up correctly.

+ * + *

A typical invocation for this method would look like:

+ *
+ * public String toString() {
+ *   return ReflectionToStringBuilder.toString(this);
+ * }
+ * + *

You can also use the builder to debug 3rd party objects:

+ *
+ * System.out.println("An object: " + ReflectionToStringBuilder.toString(anObject));
+ * + *

A subclass can control field output by overriding the methods: + *

    + *
  • {@link #accept(java.lang.reflect.Field)}
  • + *
  • {@link #getValue(java.lang.reflect.Field)}
  • + *
+ *

+ *

For example, this method does not include the password field in the returned + * String:

+ *
+ * public String toString() {
+ *     return (new ReflectionToStringBuilder(this) {
+ *         protected boolean accept(Field f) {
+ *             return super.accept(f) && !f.getName().equals("password");
+ *         }
+ *     }).toString();
+ * }
+ * + *

The exact format of the toString is determined by + * the {@link ToStringStyle} passed into the constructor.

+ * + * @author Gary Gregory + * @author Stephen Colebourne + * @author Pete Gieser + * @since 2.0 + * @version $Id: ReflectionToStringBuilder.java,v 1.1 2012/08/30 16:24:43 marcin Exp $ + */ +public class ReflectionToStringBuilder extends ToStringBuilder { + + /** + *

A registry of objects used by reflectionToString methods + * to detect cyclical object references and avoid infinite loops.

+ */ + private static ThreadLocal registry = new ThreadLocal() { + protected synchronized Object initialValue() { + // The HashSet implementation is not synchronized, + // which is just what we need here. + return new HashSet(); + } + }; + + /** + *

Returns the registry of objects being traversed by the + * reflectionToString methods in the current thread.

+ * + * @return Set the registry of objects being traversed + */ + static Set getRegistry() { + return (Set) registry.get(); + } + + /** + *

Returns true if the registry contains the given object. + * Used by the reflection methods to avoid infinite loops.

+ * + * @param value The object to lookup in the registry. + * @return boolean true if the registry contains the given object. + */ + static boolean isRegistered(Object value) { + return getRegistry().contains(value); + } + + /** + *

Registers the given object. + * Used by the reflection methods to avoid infinite loops.

+ * + * @param value The object to register. + */ + static void register(Object value) { + getRegistry().add(value); + } + + /** + *

This method uses reflection to build a suitable + * toString using the default ToStringStyle. + * + *

It uses AccessibleObject.setAccessible to gain access to private + * fields. This means that it will throw a security exception if run + * under a security manager, if the permissions are not set up correctly. + * It is also not as efficient as testing explicitly.

+ * + *

Transient members will be not be included, as they are likely derived. + * Static fields will not be included. Superclass fields will be appended.

+ * + * @param object the Object to be output + * @return the String result + * @throws IllegalArgumentException if the Object is null + */ + public static String toString(Object object) { + return toString(object, null, false, null); + } + + /** + *

This method uses reflection to build a suitable + * toString.

+ * + *

It uses AccessibleObject.setAccessible to gain access to private + * fields. This means that it will throw a security exception if run + * under a security manager, if the permissions are not set up correctly. + * It is also not as efficient as testing explicitly.

+ * + *

Transient members will be not be included, as they are likely derived. + * Static fields will not be included. Superclass fields will be appended.

+ * + *

If the style is null, the default + * ToStringStyle is used.

+ * + * @param object the Object to be output + * @param style the style of the toString to create, + * may be null + * @return the String result + * @throws IllegalArgumentException if the Object or + * ToStringStyle is null + */ + public static String toString(Object object, ToStringStyle style) { + return toString(object, style, false, null); + } + + /** + *

This method uses reflection to build a suitable + * toString.

+ * + *

It uses AccessibleObject.setAccessible to gain access to private + * fields. This means that it will throw a security exception if run + * under a security manager, if the permissions are not set up correctly. + * It is also not as efficient as testing explicitly.

+ * + *

If the outputTransients is true, + * transient members will be output, otherwise they are ignored, + * as they are likely derived fields, and not part of the value of the + * Object.

+ * + *

Static fields will not be included. Superclass fields will be appended.

+ * + *

If the style is null, the default + * ToStringStyle is used.

+ * + * @param object the Object to be output + * @param style the style of the toString to create, + * may be null + * @param outputTransients whether to include transient fields + * @return the String result + * @throws IllegalArgumentException if the Object is null + */ + public static String toString(Object object, ToStringStyle style, boolean outputTransients) { + return toString(object, style, outputTransients, null); + } + + /** + *

This method uses reflection to build a suitable + * toString.

+ * + *

It uses AccessibleObject.setAccessible to gain access to private + * fields. This means that it will throw a security exception if run + * under a security manager, if the permissions are not set up correctly. + * It is also not as efficient as testing explicitly.

+ * + *

If the outputTransients is true, + * transient members will be output, otherwise they are ignored, + * as they are likely derived fields, and not part of the value of the + * Object.

+ * + *

Static fields will not be included. Superclass fields will be appended + * up to and including the specified superclass. A null superclass is treated + * as java.lang.Object.

+ * + *

If the style is null, the default + * ToStringStyle is used.

+ * + * @param object the Object to be output + * @param style the style of the toString to create, + * may be null + * @param outputTransients whether to include transient fields + * @param reflectUpToClass the superclass to reflect up to (inclusive), + * may be null + * @return the String result + * @throws IllegalArgumentException if the Object is null + */ + public static String toString( + Object object, + ToStringStyle style, + boolean outputTransients, + Class reflectUpToClass) { + return new ReflectionToStringBuilder(object, style, null, reflectUpToClass, outputTransients).toString(); + } + + /** + *

Unregisters the given object.

+ * + *

Used by the reflection methods to avoid infinite loops.

+ * + * @param value The object to unregister. + */ + static void unregister(Object value) { + getRegistry().remove(value); + } + + /** + * Whether or not to append transient fields. + */ + private boolean appendTransients = false; + + /** + * The last super class to stop appending fields for. + */ + private Class upToClass = null; + + /** + *

Constructor.

+ * + *

This constructor outputs using the default style set with + * setDefaultStyle.

+ * + * @param object the Object to build a toString for, + * must not be null + * @throws IllegalArgumentException if the Object passed in is + * null + */ + public ReflectionToStringBuilder(Object object) { + super(object); + } + + /** + *

Constructor.

+ * + *

If the style is null, the default style is used.

+ * + * @param object the Object to build a toString for, + * must not be null + * @param style the style of the toString to create, + * may be null + * @throws IllegalArgumentException if the Object passed in is + * null + */ + public ReflectionToStringBuilder(Object object, ToStringStyle style) { + super(object, style); + } + + /** + *

Constructor.

+ * + *

If the style is null, the default style is used.

+ * + *

If the buffer is null, a new one is created.

+ * + * @param object the Object to build a toString for, + * must not be null + * @param style the style of the toString to create, + * may be null + * @param buffer the StringBuffer to populate, may be + * null + * @throws IllegalArgumentException if the Object passed in is + * null + */ + public ReflectionToStringBuilder(Object object, ToStringStyle style, StringBuffer buffer) { + super(object, style, buffer); + } + + /** + * Constructor. + * + * @param object the Object to build a toString for, + * must not be null + * @param style the style of the toString to create, + * may be null + * @param buffer the StringBuffer to populate, may be + * null + * @param reflectUpToClass the superclass to reflect up to (inclusive), + * may be null + * @param outputTransients whether to include transient fields + */ + public ReflectionToStringBuilder( + Object object, + ToStringStyle style, + StringBuffer buffer, + Class reflectUpToClass, + boolean outputTransients) { + super(object, style, buffer); + this.setUpToClass(reflectUpToClass); + this.setAppendTransients(outputTransients); + } + + /** + * Returns whether or not to append the given Field. + *
    + *
  • Static fields are not appended.
  • + *
  • Transient fields are appended only if {@link #isAppendTransients()} returns true. + *
  • Inner class fields are not appened.
  • + *
+ * @param field The Field to test. + * @return Whether or not to append the given Field. + */ + protected boolean accept(Field field) { + String fieldName = field.getName(); + return (fieldName.indexOf(ClassUtils.INNER_CLASS_SEPARATOR_CHAR) == -1) + && (this.isAppendTransients() || !Modifier.isTransient(field.getModifiers())) + && (!Modifier.isStatic(field.getModifiers())); + } + + /** + *

Appends the fields and values defined by the given object of the + * given Class.

+ * + *

If a cycle is detected as an object is "toString()'ed", + * such an object is rendered as if Object.toString() + * had been called and not implemented by the object.

+ * + * @param clazz The class of object parameter + */ + protected void appendFieldsIn(Class clazz) { + if (isRegistered(this.getObject())) { + // The object has already been appended, therefore we have an object cycle. + // Append a simple Object.toString style string. The field name is already appended at this point. + this.appendAsObjectToString(this.getObject()); + return; + } + try { + this.registerObject(); + if (clazz.isArray()) { + this.reflectionAppendArray(this.getObject()); + return; + } + Field[] fields = clazz.getDeclaredFields(); + AccessibleObject.setAccessible(fields, true); + for (int i = 0; i < fields.length; i++) { + Field field = fields[i]; + String fieldName = field.getName(); + if (this.accept(field)) { + try { + // Warning: Field.get(Object) creates wrappers objects for primitive types. + Object fieldValue = this.getValue(field); + if (isRegistered(fieldValue) && !field.getType().isPrimitive()) { + // A known field value has already been appended, therefore we have an object cycle, + // append a simple Object.toString style string. + this.getStyle().appendFieldStart(this.getStringBuffer(), fieldName); + this.appendAsObjectToString(fieldValue); + // The recursion out of + // builder.append(fieldName, fieldValue); + // below will append the field + // end marker. + } else { + try { + this.registerObject(); + this.append(fieldName, fieldValue); + } finally { + this.unregisterObject(); + } + } + } catch (IllegalAccessException ex) { + //this can't happen. Would get a Security exception instead + //throw a runtime exception in case the impossible happens. + throw new InternalError("Unexpected IllegalAccessException: " + ex.getMessage()); + } + } + } + } finally { + this.unregisterObject(); + } + } + + /** + *

Gets the last super class to stop appending fields for.

+ * + * @return The last super class to stop appending fields for. + */ + public Class getUpToClass() { + return this.upToClass; + } + + /** + *

Calls java.lang.reflect.Field.get(Object).

+ * + * @see java.lang.reflect.Field#get(Object) + * @throws IllegalArgumentException + * @throws IllegalAccessException + */ + protected Object getValue(Field field) throws IllegalArgumentException, IllegalAccessException { + return field.get(this.getObject()); + } + + /** + *

Gets whether or not to append transient fields.

+ * + * @return Whether or not to append transient fields. + */ + public boolean isAppendTransients() { + return this.appendTransients; + } + + /** + *

Append to the toString an Object + * array.

+ * + * @param array the array to add to the toString + * @return this + */ + public ToStringBuilder reflectionAppendArray(Object array) { + this.getStyle().reflectionAppendArrayDetail(this.getStringBuffer(), null, array); + return this; + } + + /** + *

Registers this builder's source object to avoid infinite + * loops when processing circular object references.

+ */ + void registerObject() { + register(this.getObject()); + } + + /** + *

Sets whether or not to append transient fields.

+ * + * @param appendTransients Whether or not to append transient fields. + */ + public void setAppendTransients(boolean appendTransients) { + this.appendTransients = appendTransients; + } + + /** + *

Sets the last super class to stop appending fields for.

+ * + * @param clazz The last super class to stop appending fields for. + */ + public void setUpToClass(Class clazz) { + this.upToClass = clazz; + } + + /** + *

Gets the String built by this builder.

+ * + * @return the built string + */ + public String toString() { + if (this.getObject() == null) { + return this.getStyle().getNullText(); + } + Class clazz = this.getObject().getClass(); + this.appendFieldsIn(clazz); + while (clazz.getSuperclass() != null && clazz != this.getUpToClass()) { + clazz = clazz.getSuperclass(); + this.appendFieldsIn(clazz); + } + return super.toString(); + } + + /** + *

Unegisters this builder's source object to avoid infinite + * loops when processing circular object references.

+ */ + void unregisterObject() { + unregister(this.getObject()); + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/builder/StandardToStringStyle.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/builder/StandardToStringStyle.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/builder/StandardToStringStyle.java 30 Aug 2012 16:24:43 -0000 1.1 @@ -0,0 +1,575 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.builder; + +/** + *

Works with {@link ToStringBuilder} to create a toString.

+ * + *

This class is intended to be used as a singleton. + * There is no need to instantiate a new style each time. + * Simply instantiate the class once, customize the values as required, and + * store the result in a public static final variable for the rest of the + * program to access.

+ * + * @author Stephen Colebourne + * @author Pete Gieser + * @author Gary Gregory + * @since 1.0 + * @version $Id: StandardToStringStyle.java,v 1.1 2012/08/30 16:24:43 marcin Exp $ + */ +public class StandardToStringStyle extends ToStringStyle { + + /** + *

Constructor.

+ */ + public StandardToStringStyle() { + super(); + } + + //--------------------------------------------------------------------- + + /** + *

Gets whether to use the class name.

+ * + * @return the current useClassName flag + */ + public boolean isUseClassName() { + return super.isUseClassName(); + } + + /** + *

Sets whether to use the class name.

+ * + * @param useClassName the new useClassName flag + */ + public void setUseClassName(boolean useClassName) { + super.setUseClassName(useClassName); + } + + //--------------------------------------------------------------------- + + /** + *

Gets whether to output short or long class names.

+ * + * @return the current useShortClassName flag + * @since 2.0 + */ + public boolean isUseShortClassName() { + return super.isUseShortClassName(); + } + + /** + *

Gets whether to output short or long class names.

+ * + * @return the current shortClassName flag + * @deprecated Use {@link #isUseShortClassName()} + * Method will be removed in Commons Lang 3.0. + */ + public boolean isShortClassName() { + return super.isUseShortClassName(); + } + + /** + *

Sets whether to output short or long class names.

+ * + * @param useShortClassName the new useShortClassName flag + * @since 2.0 + */ + public void setUseShortClassName(boolean useShortClassName) { + super.setUseShortClassName(useShortClassName); + } + + /** + *

Sets whether to output short or long class names.

+ * + * @param shortClassName the new shortClassName flag + * @deprecated Use {@link #setUseShortClassName(boolean)} + * Method will be removed in Commons Lang 3.0. + */ + public void setShortClassName(boolean shortClassName) { + super.setUseShortClassName(shortClassName); + } + + //--------------------------------------------------------------------- + + /** + *

Gets whether to use the identity hash code.

+ * @return the current useIdentityHashCode flag + */ + public boolean isUseIdentityHashCode() { + return super.isUseIdentityHashCode(); + } + + /** + *

Sets whether to use the identity hash code.

+ * + * @param useIdentityHashCode the new useIdentityHashCode flag + */ + public void setUseIdentityHashCode(boolean useIdentityHashCode) { + super.setUseIdentityHashCode(useIdentityHashCode); + } + + //--------------------------------------------------------------------- + + /** + *

Gets whether to use the field names passed in.

+ * + * @return the current useFieldNames flag + */ + public boolean isUseFieldNames() { + return super.isUseFieldNames(); + } + + /** + *

Sets whether to use the field names passed in.

+ * + * @param useFieldNames the new useFieldNames flag + */ + public void setUseFieldNames(boolean useFieldNames) { + super.setUseFieldNames(useFieldNames); + } + + //--------------------------------------------------------------------- + + /** + *

Gets whether to use full detail when the caller doesn't + * specify.

+ * + * @return the current defaultFullDetail flag + */ + public boolean isDefaultFullDetail() { + return super.isDefaultFullDetail(); + } + + /** + *

Sets whether to use full detail when the caller doesn't + * specify.

+ * + * @param defaultFullDetail the new defaultFullDetail flag + */ + public void setDefaultFullDetail(boolean defaultFullDetail) { + super.setDefaultFullDetail(defaultFullDetail); + } + + //--------------------------------------------------------------------- + + /** + *

Gets whether to output array content detail.

+ * + * @return the current array content detail setting + */ + public boolean isArrayContentDetail() { + return super.isArrayContentDetail(); + } + + /** + *

Sets whether to output array content detail.

+ * + * @param arrayContentDetail the new arrayContentDetail flag + */ + public void setArrayContentDetail(boolean arrayContentDetail) { + super.setArrayContentDetail(arrayContentDetail); + } + + //--------------------------------------------------------------------- + + /** + *

Gets the array start text.

+ * + * @return the current array start text + */ + public String getArrayStart() { + return super.getArrayStart(); + } + + /** + *

Sets the array start text.

+ * + *

null is accepted, but will be converted + * to an empty String.

+ * + * @param arrayStart the new array start text + */ + public void setArrayStart(String arrayStart) { + super.setArrayStart(arrayStart); + } + + //--------------------------------------------------------------------- + + /** + *

Gets the array end text.

+ * + * @return the current array end text + */ + public String getArrayEnd() { + return super.getArrayEnd(); + } + + /** + *

Sets the array end text.

+ * + *

null is accepted, but will be converted + * to an empty String.

+ * + * @param arrayEnd the new array end text + */ + public void setArrayEnd(String arrayEnd) { + super.setArrayEnd(arrayEnd); + } + + //--------------------------------------------------------------------- + + /** + *

Gets the array separator text.

+ * + * @return the current array separator text + */ + public String getArraySeparator() { + return super.getArraySeparator(); + } + + /** + *

Sets the array separator text.

+ * + *

null is accepted, but will be converted + * to an empty String.

+ * + * @param arraySeparator the new array separator text + */ + public void setArraySeparator(String arraySeparator) { + super.setArraySeparator(arraySeparator); + } + + //--------------------------------------------------------------------- + + /** + *

Gets the content start text.

+ * + * @return the current content start text + */ + public String getContentStart() { + return super.getContentStart(); + } + + /** + *

Sets the content start text.

+ * + *

null is accepted, but will be converted + * to an empty String.

+ * + * @param contentStart the new content start text + */ + public void setContentStart(String contentStart) { + super.setContentStart(contentStart); + } + + //--------------------------------------------------------------------- + + /** + *

Gets the content end text.

+ * + * @return the current content end text + */ + public String getContentEnd() { + return super.getContentEnd(); + } + + /** + *

Sets the content end text.

+ * + *

null is accepted, but will be converted + * to an empty String.

+ * + * @param contentEnd the new content end text + */ + public void setContentEnd(String contentEnd) { + super.setContentEnd(contentEnd); + } + + //--------------------------------------------------------------------- + + /** + *

Gets the field name value separator text.

+ * + * @return the current field name value separator text + */ + public String getFieldNameValueSeparator() { + return super.getFieldNameValueSeparator(); + } + + /** + *

Sets the field name value separator text.

+ * + *

null is accepted, but will be converted + * to an empty String.

+ * + * @param fieldNameValueSeparator the new field name value separator text + */ + public void setFieldNameValueSeparator(String fieldNameValueSeparator) { + super.setFieldNameValueSeparator(fieldNameValueSeparator); + } + + //--------------------------------------------------------------------- + + /** + *

Gets the field separator text.

+ * + * @return the current field separator text + */ + public String getFieldSeparator() { + return super.getFieldSeparator(); + } + + /** + *

Sets the field separator text.

+ * + *

null is accepted, but will be converted + * to an empty String.

+ * + * @param fieldSeparator the new field separator text + */ + public void setFieldSeparator(String fieldSeparator) { + super.setFieldSeparator(fieldSeparator); + } + + //--------------------------------------------------------------------- + + /** + *

Gets whether the field separator should be added at the start + * of each buffer.

+ * + * @return the fieldSeparatorAtStart flag + * @since 2.0 + */ + public boolean isFieldSeparatorAtStart() { + return super.isFieldSeparatorAtStart(); + } + + /** + *

Sets whether the field separator should be added at the start + * of each buffer.

+ * + * @param fieldSeparatorAtStart the fieldSeparatorAtStart flag + * @since 2.0 + */ + public void setFieldSeparatorAtStart(boolean fieldSeparatorAtStart) { + super.setFieldSeparatorAtStart(fieldSeparatorAtStart); + } + + //--------------------------------------------------------------------- + + /** + *

Gets whether the field separator should be added at the end + * of each buffer.

+ * + * @return fieldSeparatorAtEnd flag + * @since 2.0 + */ + public boolean isFieldSeparatorAtEnd() { + return super.isFieldSeparatorAtEnd(); + } + + /** + *

Sets whether the field separator should be added at the end + * of each buffer.

+ * + * @param fieldSeparatorAtEnd the fieldSeparatorAtEnd flag + * @since 2.0 + */ + public void setFieldSeparatorAtEnd(boolean fieldSeparatorAtEnd) { + super.setFieldSeparatorAtEnd(fieldSeparatorAtEnd); + } + + //--------------------------------------------------------------------- + + /** + *

Gets the text to output when null found.

+ * + * @return the current text to output when null found + */ + public String getNullText() { + return super.getNullText(); + } + + /** + *

Sets the text to output when null found.

+ * + *

null is accepted, but will be converted + * to an empty String.

+ * + * @param nullText the new text to output when null found + */ + public void setNullText(String nullText) { + super.setNullText(nullText); + } + + //--------------------------------------------------------------------- + + /** + *

Gets the text to output when a Collection, + * Map or Array size is output.

+ * + *

This is output before the size value.

+ * + * @return the current start of size text + */ + public String getSizeStartText() { + return super.getSizeStartText(); + } + + /** + *

Sets the start text to output when a Collection, + * Map or Array size is output.

+ * + *

This is output before the size value.

+ * + *

null is accepted, but will be converted to + * an empty String.

+ * + * @param sizeStartText the new start of size text + */ + public void setSizeStartText(String sizeStartText) { + super.setSizeStartText(sizeStartText); + } + + //--------------------------------------------------------------------- + + /** + * Gets the end text to output when a Collection, + * Map or Array size is output.

+ * + *

This is output after the size value.

+ * + * @return the current end of size text + */ + public String getSizeEndText() { + return super.getSizeEndText(); + } + + /** + *

Sets the end text to output when a Collection, + * Map or Array size is output.

+ * + *

This is output after the size value.

+ * + *

null is accepted, but will be converted + * to an empty String.

+ * + * @param sizeEndText the new end of size text + */ + public void setSizeEndText(String sizeEndText) { + super.setSizeEndText(sizeEndText); + } + + //--------------------------------------------------------------------- + + /** + *

Gets the start text to output when an Object is + * output in summary mode.

+ * + *

This is output before the size value.

+ * + * @return the current start of summary text + */ + public String getSummaryObjectStartText() { + return super.getSummaryObjectStartText(); + } + + /** + *

Sets the start text to output when an Object is + * output in summary mode.

+ * + *

This is output before the size value.

+ * + *

null is accepted, but will be converted to + * an empty String.

+ * + * @param summaryObjectStartText the new start of summary text + */ + public void setSummaryObjectStartText(String summaryObjectStartText) { + super.setSummaryObjectStartText(summaryObjectStartText); + } + + //--------------------------------------------------------------------- + + /** + *

Gets the end text to output when an Object is + * output in summary mode.

+ * + *

This is output after the size value.

+ * + * @return the current end of summary text + */ + public String getSummaryObjectEndText() { + return super.getSummaryObjectEndText(); + } + + /** + *

Sets the end text to output when an Object is + * output in summary mode.

+ * + *

This is output after the size value.

+ * + *

null is accepted, but will be converted to + * an empty String.

+ * + * @param summaryObjectEndText the new end of summary text + */ + public void setSummaryObjectEndText(String summaryObjectEndText) { + super.setSummaryObjectEndText(summaryObjectEndText); + } + + //--------------------------------------------------------------------- + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/builder/ToStringBuilder.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/builder/ToStringBuilder.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/builder/ToStringBuilder.java 30 Aug 2012 16:24:43 -0000 1.1 @@ -0,0 +1,1082 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.builder; + +import org.apache.commons.lang.BooleanUtils; +import org.apache.commons.lang.ObjectUtils; + +/** + *

Assists in implementing {@link Object#toString()} methods.

+ * + *

This class enables a good and consistent toString() to be built for any + * class or object. This class aims to simplify the process by:

+ *
    + *
  • allowing field names
  • + *
  • handling all types consistently
  • + *
  • handling nulls consistently
  • + *
  • outputting arrays and multi-dimensional arrays
  • + *
  • enabling the detail level to be controlled for Objects and Collections
  • + *
  • handling class hierarchies
  • + *
+ * + *

To use this class write code as follows:

+ * + *
+ * public class Person {
+ *   String name;
+ *   int age;
+ *   boolean isSmoker;
+ * 
+ *   ...
+ * 
+ *   public String toString() {
+ *     return new ToStringBuilder(this).
+ *       append("name", name).
+ *       append("age", age).
+ *       append("smoker", smoker).
+ *       toString();
+ *   }
+ * }
+ * 
+ * + *

This will produce a toString of the format: + * Person@7f54[name=Stephen,age=29,smoker=false]

+ * + *

To add the superclass toString, use {@link #appendSuper}. + * To append the toString from an object that is delegated + * to (or any other object), use {@link #appendToString}.

+ * + *

Alternatively, there is a method that uses reflection to determine + * the fields to test. Because these fields are usually private, the method, + * reflectionToString, uses AccessibleObject.setAccessible to + * change the visibility of the fields. This will fail under a security manager, + * unless the appropriate permissions are set up correctly. It is also + * slower than testing explicitly.

+ * + *

A typical invocation for this method would look like:

+ * + *
+ * public String toString() {
+ *   return ToStringBuilder.reflectionToString(this);
+ * }
+ * 
+ * + *

You can also use the builder to debug 3rd party objects:

+ * + *
+ * System.out.println("An object: " + ToStringBuilder.reflectionToString(anObject));
+ * 
+ * + *

The exact format of the toString is determined by + * the {@link ToStringStyle} passed into the constructor.

+ * + * @author Stephen Colebourne + * @author Gary Gregory + * @author Pete Gieser + * @since 1.0 + * @version $Id: ToStringBuilder.java,v 1.1 2012/08/30 16:24:43 marcin Exp $ + */ +public class ToStringBuilder { + + /** + * The default style of output to use. + */ + private static ToStringStyle defaultStyle = ToStringStyle.DEFAULT_STYLE; + + //---------------------------------------------------------------------------- + + /** + *

Gets the default ToStringStyle to use.

+ * + *

This could allow the ToStringStyle to be + * controlled for an entire application with one call.

+ * + *

This might be used to have a verbose + * ToStringStyle during development and a compact + * ToStringStyle in production.

+ * + * @return the default ToStringStyle + */ + public static ToStringStyle getDefaultStyle() { + return defaultStyle; + } + + /** + *

Forwards to ReflectionToStringBuilder.

+ * + * @see ReflectionToStringBuilder#toString(Object) + */ + public static String reflectionToString(Object object) { + return ReflectionToStringBuilder.toString(object); + } + + /** + *

Forwards to ReflectionToStringBuilder.

+ * + * @see ReflectionToStringBuilder#toString(Object,ToStringStyle) + */ + public static String reflectionToString(Object object, ToStringStyle style) { + return ReflectionToStringBuilder.toString(object, style); + } + + /** + *

Forwards to ReflectionToStringBuilder.

+ * + * @see ReflectionToStringBuilder#toString(Object,ToStringStyle,boolean) + */ + public static String reflectionToString(Object object, ToStringStyle style, boolean outputTransients) { + return ReflectionToStringBuilder.toString(object, style, outputTransients, null); + } + + /** + *

Forwards to ReflectionToStringBuilder.

+ * + * @see ReflectionToStringBuilder#toString(Object,ToStringStyle,boolean,Class) + * @since 2.0 + */ + public static String reflectionToString( + Object object, + ToStringStyle style, + boolean outputTransients, + Class reflectUpToClass) { + return ReflectionToStringBuilder.toString(object, style, outputTransients, reflectUpToClass); + } + + /** + *

Sets the default ToStringStyle to use.

+ * + * @param style the default ToStringStyle + * @throws IllegalArgumentException if the style is null + */ + public static void setDefaultStyle(ToStringStyle style) { + if (style == null) { + throw new IllegalArgumentException("The style must not be null"); + } + defaultStyle = style; + } + + /** + * Current toString buffer. + */ + private final StringBuffer buffer; + + /** + * The object being output. + */ + private final Object object; + + /** + * The style of output to use. + */ + private final ToStringStyle style; + + /** + *

Constructor for ToStringBuilder.

+ * + *

This constructor outputs using the default style set with + * setDefaultStyle.

+ * + * @param object the Object to build a toString for, + * must not be null + * @throws IllegalArgumentException if the Object passed in is + * null + */ + public ToStringBuilder(Object object) { + this(object, getDefaultStyle(), null); + } + + /** + *

Constructor for ToStringBuilder specifying the + * output style.

+ * + *

If the style is null, the default style is used.

+ * + * @param object the Object to build a toString for, + * must not be null + * @param style the style of the toString to create, + * may be null + * @throws IllegalArgumentException if the Object passed in is + * null + */ + public ToStringBuilder(Object object, ToStringStyle style) { + this(object, style, null); + } + + /** + *

Constructor for ToStringBuilder.

+ * + *

If the style is null, the default style is used.

+ * + *

If the buffer is null, a new one is created.

+ * + * @param object the Object to build a toString for, + * must not be null + * @param style the style of the toString to create, + * may be null + * @param buffer the StringBuffer to populate, may be + * null + * @throws IllegalArgumentException if the Object passed in is + * null + */ + public ToStringBuilder(Object object, ToStringStyle style, StringBuffer buffer) { + super(); + if (object == null) { + throw new IllegalArgumentException("The object to create a toString for must not be null"); + } + if (style == null) { + style = getDefaultStyle(); + } + if (buffer == null) { + buffer = new StringBuffer(512); + } + this.buffer = buffer; + this.style = style; + this.object = object; + + style.appendStart(buffer, object); + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString a boolean + * value.

+ * + * @param value the value to add to the toString + * @return this + */ + public ToStringBuilder append(boolean value) { + style.append(buffer, null, value); + return this; + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString a boolean + * array.

+ * + * @param array the array to add to the toString + * @return this + */ + public ToStringBuilder append(boolean[] array) { + style.append(buffer, null, array, null); + return this; + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString a byte + * value.

+ * + * @param value the value to add to the toString + * @return this + */ + public ToStringBuilder append(byte value) { + style.append(buffer, null, value); + return this; + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString a byte + * array.

+ * + * @param array the array to add to the toString + * @return this + */ + public ToStringBuilder append(byte[] array) { + style.append(buffer, null, array, null); + return this; + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString a char + * value.

+ * + * @param value the value to add to the toString + * @return this + */ + public ToStringBuilder append(char value) { + style.append(buffer, null, value); + return this; + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString a char + * array.

+ * + * @param array the array to add to the toString + * @return this + */ + public ToStringBuilder append(char[] array) { + style.append(buffer, null, array, null); + return this; + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString a double + * value.

+ * + * @param value the value to add to the toString + * @return this + */ + public ToStringBuilder append(double value) { + style.append(buffer, null, value); + return this; + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString a double + * array.

+ * + * @param array the array to add to the toString + * @return this + */ + public ToStringBuilder append(double[] array) { + style.append(buffer, null, array, null); + return this; + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString a float + * value.

+ * + * @param value the value to add to the toString + * @return this + */ + public ToStringBuilder append(float value) { + style.append(buffer, null, value); + return this; + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString a float + * array.

+ * + * @param array the array to add to the toString + * @return this + */ + public ToStringBuilder append(float[] array) { + style.append(buffer, null, array, null); + return this; + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString an int + * value.

+ * + * @param value the value to add to the toString + * @return this + */ + public ToStringBuilder append(int value) { + style.append(buffer, null, value); + return this; + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString an int + * array.

+ * + * @param array the array to add to the toString + * @return this + */ + public ToStringBuilder append(int[] array) { + style.append(buffer, null, array, null); + return this; + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString a long + * value.

+ * + * @param value the value to add to the toString + * @return this + */ + public ToStringBuilder append(long value) { + style.append(buffer, null, value); + return this; + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString a long + * array.

+ * + * @param array the array to add to the toString + * @return this + */ + public ToStringBuilder append(long[] array) { + style.append(buffer, null, array, null); + return this; + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString an Object + * value.

+ * + * @param object the value to add to the toString + * @return this + */ + public ToStringBuilder append(Object object) { + style.append(buffer, null, object, null); + return this; + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString an Object + * array.

+ * + * @param array the array to add to the toString + * @return this + */ + public ToStringBuilder append(Object[] array) { + style.append(buffer, null, array, null); + return this; + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString a short + * value.

+ * + * @param value the value to add to the toString + * @return this + */ + public ToStringBuilder append(short value) { + style.append(buffer, null, value); + return this; + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString a short + * array.

+ * + * @param array the array to add to the toString + * @return this + */ + public ToStringBuilder append(short[] array) { + style.append(buffer, null, array, null); + return this; + } + + /** + *

Append to the toString a boolean + * value.

+ * + * @param fieldName the field name + * @param value the value to add to the toString + * @return this + */ + public ToStringBuilder append(String fieldName, boolean value) { + style.append(buffer, fieldName, value); + return this; + } + + /** + *

Append to the toString a boolean + * array.

+ * + * @param fieldName the field name + * @param array the array to add to the hashCode + * @return this + */ + public ToStringBuilder append(String fieldName, boolean[] array) { + style.append(buffer, fieldName, array, null); + return this; + } + + /** + *

Append to the toString a boolean + * array.

+ * + *

A boolean parameter controls the level of detail to show. + * Setting true will output the array in full. Setting + * false will output a summary, typically the size of + * the array.

+ * + * @param fieldName the field name + * @param array the array to add to the toString + * @param fullDetail true for detail, false + * for summary info + * @return this + */ + public ToStringBuilder append(String fieldName, boolean[] array, boolean fullDetail) { + style.append(buffer, fieldName, array, BooleanUtils.toBooleanObject(fullDetail)); + return this; + } + + /** + *

Append to the toString an byte + * value.

+ * + * @param fieldName the field name + * @param value the value to add to the toString + * @return this + */ + public ToStringBuilder append(String fieldName, byte value) { + style.append(buffer, fieldName, value); + return this; + } + + /** + *

Append to the toString a byte array.

+ * + * @param fieldName the field name + * @param array the array to add to the toString + * @return this + */ + public ToStringBuilder append(String fieldName, byte[] array) { + style.append(buffer, fieldName, array, null); + return this; + } + + /** + *

Append to the toString a byte + * array.

+ * + *

A boolean parameter controls the level of detail to show. + * Setting true will output the array in full. Setting + * false will output a summary, typically the size of + * the array. + * + * @param fieldName the field name + * @param array the array to add to the toString + * @param fullDetail true for detail, false + * for summary info + * @return this + */ + public ToStringBuilder append(String fieldName, byte[] array, boolean fullDetail) { + style.append(buffer, fieldName, array, BooleanUtils.toBooleanObject(fullDetail)); + return this; + } + + /** + *

Append to the toString a char + * value.

+ * + * @param fieldName the field name + * @param value the value to add to the toString + * @return this + */ + public ToStringBuilder append(String fieldName, char value) { + style.append(buffer, fieldName, value); + return this; + } + + /** + *

Append to the toString a char + * array.

+ * + * @param fieldName the field name + * @param array the array to add to the toString + * @return this + */ + public ToStringBuilder append(String fieldName, char[] array) { + style.append(buffer, fieldName, array, null); + return this; + } + + /** + *

Append to the toString a char + * array.

+ * + *

A boolean parameter controls the level of detail to show. + * Setting true will output the array in full. Setting + * false will output a summary, typically the size of + * the array.

+ * + * @param fieldName the field name + * @param array the array to add to the toString + * @param fullDetail true for detail, false + * for summary info + * @return this + */ + public ToStringBuilder append(String fieldName, char[] array, boolean fullDetail) { + style.append(buffer, fieldName, array, BooleanUtils.toBooleanObject(fullDetail)); + return this; + } + + /** + *

Append to the toString a double + * value.

+ * + * @param fieldName the field name + * @param value the value to add to the toString + * @return this + */ + public ToStringBuilder append(String fieldName, double value) { + style.append(buffer, fieldName, value); + return this; + } + + /** + *

Append to the toString a double + * array.

+ * + * @param fieldName the field name + * @param array the array to add to the toString + * @return this + */ + public ToStringBuilder append(String fieldName, double[] array) { + style.append(buffer, fieldName, array, null); + return this; + } + + /** + *

Append to the toString a double + * array.

+ * + *

A boolean parameter controls the level of detail to show. + * Setting true will output the array in full. Setting + * false will output a summary, typically the size of + * the array.

+ * + * @param fieldName the field name + * @param array the array to add to the toString + * @param fullDetail true for detail, false + * for summary info + * @return this + */ + public ToStringBuilder append(String fieldName, double[] array, boolean fullDetail) { + style.append(buffer, fieldName, array, BooleanUtils.toBooleanObject(fullDetail)); + return this; + } + + /** + *

Append to the toString an float + * value.

+ * + * @param fieldName the field name + * @param value the value to add to the toString + * @return this + */ + public ToStringBuilder append(String fieldName, float value) { + style.append(buffer, fieldName, value); + return this; + } + + /** + *

Append to the toString a float + * array.

+ * + * @param fieldName the field name + * @param array the array to add to the toString + * @return this + */ + public ToStringBuilder append(String fieldName, float[] array) { + style.append(buffer, fieldName, array, null); + return this; + } + + /** + *

Append to the toString a float + * array.

+ * + *

A boolean parameter controls the level of detail to show. + * Setting true will output the array in full. Setting + * false will output a summary, typically the size of + * the array.

+ * + * @param fieldName the field name + * @param array the array to add to the toString + * @param fullDetail true for detail, false + * for summary info + * @return this + */ + public ToStringBuilder append(String fieldName, float[] array, boolean fullDetail) { + style.append(buffer, fieldName, array, BooleanUtils.toBooleanObject(fullDetail)); + return this; + } + + /** + *

Append to the toString an int + * value.

+ * + * @param fieldName the field name + * @param value the value to add to the toString + * @return this + */ + public ToStringBuilder append(String fieldName, int value) { + style.append(buffer, fieldName, value); + return this; + } + + /** + *

Append to the toString an int + * array.

+ * + * @param fieldName the field name + * @param array the array to add to the toString + * @return this + */ + public ToStringBuilder append(String fieldName, int[] array) { + style.append(buffer, fieldName, array, null); + return this; + } + + /** + *

Append to the toString an int + * array.

+ * + *

A boolean parameter controls the level of detail to show. + * Setting true will output the array in full. Setting + * false will output a summary, typically the size of + * the array.

+ * + * @param fieldName the field name + * @param array the array to add to the toString + * @param fullDetail true for detail, false + * for summary info + * @return this + */ + public ToStringBuilder append(String fieldName, int[] array, boolean fullDetail) { + style.append(buffer, fieldName, array, BooleanUtils.toBooleanObject(fullDetail)); + return this; + } + + /** + *

Append to the toString a long + * value.

+ * + * @param fieldName the field name + * @param value the value to add to the toString + * @return this + */ + public ToStringBuilder append(String fieldName, long value) { + style.append(buffer, fieldName, value); + return this; + } + + /** + *

Append to the toString a long + * array.

+ * + * @param fieldName the field name + * @param array the array to add to the toString + * @return this + */ + public ToStringBuilder append(String fieldName, long[] array) { + style.append(buffer, fieldName, array, null); + return this; + } + + /** + *

Append to the toString a long + * array.

+ * + *

A boolean parameter controls the level of detail to show. + * Setting true will output the array in full. Setting + * false will output a summary, typically the size of + * the array.

+ * + * @param fieldName the field name + * @param array the array to add to the toString + * @param fullDetail true for detail, false + * for summary info + * @return this + */ + public ToStringBuilder append(String fieldName, long[] array, boolean fullDetail) { + style.append(buffer, fieldName, array, BooleanUtils.toBooleanObject(fullDetail)); + return this; + } + + /** + *

Append to the toString an Object + * value.

+ * + * @param fieldName the field name + * @param object the value to add to the toString + * @return this + */ + public ToStringBuilder append(String fieldName, Object object) { + style.append(buffer, fieldName, object, null); + return this; + } + + /** + *

Append to the toString an Object + * value.

+ * + * @param fieldName the field name + * @param object the value to add to the toString + * @param fullDetail true for detail, + * false for summary info + * @return this + */ + public ToStringBuilder append(String fieldName, Object object, boolean fullDetail) { + style.append(buffer, fieldName, object, BooleanUtils.toBooleanObject(fullDetail)); + return this; + } + + /** + *

Append to the toString an Object + * array.

+ * + * @param fieldName the field name + * @param array the array to add to the toString + * @return this + */ + public ToStringBuilder append(String fieldName, Object[] array) { + style.append(buffer, fieldName, array, null); + return this; + } + + /** + *

Append to the toString an Object + * array.

+ * + *

A boolean parameter controls the level of detail to show. + * Setting true will output the array in full. Setting + * false will output a summary, typically the size of + * the array.

+ * + * @param fieldName the field name + * @param array the array to add to the toString + * @param fullDetail true for detail, false + * for summary info + * @return this + */ + public ToStringBuilder append(String fieldName, Object[] array, boolean fullDetail) { + style.append(buffer, fieldName, array, BooleanUtils.toBooleanObject(fullDetail)); + return this; + } + + /** + *

Append to the toString an short + * value.

+ * + * @param fieldName the field name + * @param value the value to add to the toString + * @return this + */ + public ToStringBuilder append(String fieldName, short value) { + style.append(buffer, fieldName, value); + return this; + } + + /** + *

Append to the toString a short + * array.

+ * + * @param fieldName the field name + * @param array the array to add to the toString + * @return this + */ + public ToStringBuilder append(String fieldName, short[] array) { + style.append(buffer, fieldName, array, null); + return this; + } + + /** + *

Append to the toString a short + * array.

+ * + *

A boolean parameter controls the level of detail to show. + * Setting true will output the array in full. Setting + * false will output a summary, typically the size of + * the array. + * + * @param fieldName the field name + * @param array the array to add to the toString + * @param fullDetail true for detail, false + * for summary info + * @return this + */ + public ToStringBuilder append(String fieldName, short[] array, boolean fullDetail) { + style.append(buffer, fieldName, array, BooleanUtils.toBooleanObject(fullDetail)); + return this; + } + + /** + *

Appends with the same format as the default Object toString() + * method. Appends the class name followed by + * {@link System#identityHashCode(java.lang.Object)}.

+ * + * @param object the Object whose class name and id to output + * @since 2.0 + */ + public ToStringBuilder appendAsObjectToString(Object object) { + ObjectUtils.appendIdentityToString(this.getStringBuffer(), object); + return this; + } + + //---------------------------------------------------------------------------- + + /** + *

Append the toString from the superclass.

+ * + *

This method assumes that the superclass uses the same ToStringStyle + * as this one.

+ * + *

If superToString is null, no change is made.

+ * + * @param superToString the result of super.toString() + * @return this + * @since 2.0 + */ + public ToStringBuilder appendSuper(String superToString) { + if (superToString != null) { + style.appendSuper(buffer, superToString); + } + return this; + } + + /** + *

Append the toString from another object.

+ * + *

This method is useful where a class delegates most of the implementation of + * its properties to another class. You can then call toString() on + * the other class and pass the result into this method.

+ * + *
+     *   private AnotherObject delegate;
+     *   private String fieldInThisClass;
+     * 
+     *   public String toString() {
+     *     return new ToStringBuilder(this).
+     *       appendToString(delegate.toString()).
+     *       append(fieldInThisClass).
+     *       toString();
+     *   }
+ * + *

This method assumes that the other object uses the same ToStringStyle + * as this one.

+ * + *

If the toString is null, no change is made.

+ * + * @param toString the result of toString() on another object + * @return this + * @since 2.0 + */ + public ToStringBuilder appendToString(String toString) { + if (toString != null) { + style.appendToString(buffer, toString); + } + return this; + } + + /** + *

Gets the StringBuffer being populated.

+ * + * @return the StringBuffer being populated + */ + public StringBuffer getStringBuffer() { + return buffer; + } + + //---------------------------------------------------------------------------- + + /** + *

Gets the ToStringStyle being used.

+ * + * @return the ToStringStyle being used + * @since 2.0 + */ + public ToStringStyle getStyle() { + return style; + } + + /** + *

Returns the built toString.

+ * + *

This method appends the end of data indicator, and can only be called once. + * Use {@link #getStringBuffer} to get the current string state.

+ * + * @return the String toString + */ + public String toString() { + style.appendEnd(buffer, object); + return buffer.toString(); + } + + /** + *

Returns the Object being output.

+ * + * @return The object being output. + * @since 2.0 + */ + public Object getObject() { + return object; + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/builder/ToStringStyle.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/builder/ToStringStyle.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/builder/ToStringStyle.java 30 Aug 2012 16:24:43 -0000 1.1 @@ -0,0 +1,2169 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.builder; + +import java.io.Serializable; +import java.lang.reflect.Array; +import java.util.Collection; +import java.util.Map; + +import org.apache.commons.lang.ClassUtils; +import org.apache.commons.lang.ObjectUtils; +import org.apache.commons.lang.SystemUtils; + +/** + *

Controls String formatting for {@link ToStringBuilder}. + * The main public interface is always via ToStringBuilder.

+ * + *

These classes are intended to be used as Singletons. + * There is no need to instantiate a new style each time. A program + * will generally use one of the predefined constants on this class. + * Alternatively, the {@link StandardToStringStyle} class can be used + * to set the individual settings. Thus most styles can be achieved + * without subclassing.

+ * + *

If required, a subclass can override as many or as few of the + * methods as it requires. Each object type (from boolean + * to long to Object to int[]) has + * its own methods to output it. Most have two versions, detail and summary. + * + *

For example, the detail version of the array based methods will + * output the whole array, whereas the summary method will just output + * the array length.

+ * + * @author Stephen Colebourne + * @author Gary Gregory + * @author Pete Gieser + * @since 1.0 + * @version $Id: ToStringStyle.java,v 1.1 2012/08/30 16:24:43 marcin Exp $ + */ +public abstract class ToStringStyle implements Serializable { + + /** + * The default toString style. + */ + public static final ToStringStyle DEFAULT_STYLE = new DefaultToStringStyle(); + /** + * The multi line toString style. + */ + public static final ToStringStyle MULTI_LINE_STYLE = new MultiLineToStringStyle(); + /** + * The no field names toString style. + */ + public static final ToStringStyle NO_FIELD_NAMES_STYLE = new NoFieldNameToStringStyle(); + /** + * The simple toString style. + */ + public static final ToStringStyle SIMPLE_STYLE = new SimpleToStringStyle(); + + /** + * Whether to use the field names, the default is true. + */ + private boolean useFieldNames = true; + /** + * Whether to use the class name, the default is true. + */ + private boolean useClassName = true; + /** + * Whether to use short class names, the default is false. + */ + private boolean useShortClassName = false; + /** + * Whether to use the identity hash code, the default is true. + */ + private boolean useIdentityHashCode = true; + + /** + * The content start '['. + */ + private String contentStart = "["; + /** + * The content end ']'. + */ + private String contentEnd = "]"; + /** + * The field name value separator '='. + */ + private String fieldNameValueSeparator = "="; + /** + * Whether the field separator should be added before any other fields. + */ + private boolean fieldSeparatorAtStart = false; + /** + * Whether the field separator should be added after any other fields. + */ + private boolean fieldSeparatorAtEnd = false; + /** + * The field separator ','. + */ + private String fieldSeparator = ","; + /** + * The array start '{'. + */ + private String arrayStart = "{"; + /** + * The array separator ','. + */ + private String arraySeparator = ","; + /** + * The detail for array content. + */ + private boolean arrayContentDetail = true; + /** + * The array end '}'. + */ + private String arrayEnd = "}"; + /** + * The value to use when fullDetail is null, + * the default value is true. + */ + private boolean defaultFullDetail = true; + /** + * The null text '<null>'. + */ + private String nullText = ""; + /** + * The summary size text start '. + */ + private String sizeStartText = "'>'. + */ + private String sizeEndText = ">"; + /** + * The summary object text start '<'. + */ + private String summaryObjectStartText = "<"; + /** + * The summary object text start '>'. + */ + private String summaryObjectEndText = ">"; + + //---------------------------------------------------------------------------- + + /** + *

Constructor.

+ */ + protected ToStringStyle() { + super(); + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString the superclass toString.

+ * + *

A null superToString is ignored.

+ * + * @param buffer the StringBuffer to populate + * @param superToString the super.toString() + * @since 2.0 + */ + public void appendSuper(StringBuffer buffer, String superToString) { + appendToString(buffer, superToString); + } + + /** + *

Append to the toString another toString.

+ * + *

A null toString is ignored.

+ * + * @param buffer the StringBuffer to populate + * @param toString the additional toString + * @since 2.0 + */ + public void appendToString(StringBuffer buffer, String toString) { + if (toString != null) { + int pos1 = toString.indexOf(contentStart) + contentStart.length(); + int pos2 = toString.lastIndexOf(contentEnd); + if (pos1 != pos2 && pos1 >= 0 && pos2 >= 0) { + String data = toString.substring(pos1, pos2); + if (fieldSeparatorAtStart) { + removeLastFieldSeparator(buffer); + } + buffer.append(data); + appendFieldSeparator(buffer); + } + } + } + + /** + *

Append to the toString the start of data indicator.

+ * + * @param buffer the StringBuffer to populate + * @param object the Object to build a + * toString for, must not be null + */ + public void appendStart(StringBuffer buffer, Object object) { + appendClassName(buffer, object); + appendIdentityHashCode(buffer, object); + appendContentStart(buffer); + if (fieldSeparatorAtStart) { + appendFieldSeparator(buffer); + } + } + + /** + *

Append to the toString the end of data indicator.

+ * + * @param buffer the StringBuffer to populate + * @param object the Object to build a + * toString for, must not be null + */ + public void appendEnd(StringBuffer buffer, Object object) { + if (fieldSeparatorAtEnd == false) { + removeLastFieldSeparator(buffer); + } + appendContentEnd(buffer); + } + + /** + *

Remove the last field separator from the buffer.

+ * + * @param buffer the StringBuffer to populate + * @since 2.0 + */ + protected void removeLastFieldSeparator(StringBuffer buffer) { + int len = buffer.length(); + int sepLen = fieldSeparator.length(); + if (len > 0 && sepLen > 0 && len >= sepLen) { + boolean match = true; + for (int i = 0; i < sepLen; i++) { + if (buffer.charAt(len - 1 - i) != fieldSeparator.charAt(sepLen - 1 - i)) { + match = false; + break; + } + } + if (match) { + buffer.setLength(len - sepLen); + } + } + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString an Object + * value, printing the full toString of the + * Object passed in.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name + * @param value the value to add to the toString + * @param fullDetail true for detail, false + * for summary info, null for style decides + */ + public void append(StringBuffer buffer, String fieldName, Object value, Boolean fullDetail) { + appendFieldStart(buffer, fieldName); + + if (value == null) { + appendNullText(buffer, fieldName); + + } else { + appendInternal(buffer, fieldName, value, isFullDetail(fullDetail)); + } + + appendFieldEnd(buffer, fieldName); + } + + /** + *

Append to the toString an Object, + * correctly interpreting its type.

+ * + *

This method performs the main lookup by Class type to correctly + * route arrays, Collections, Maps and + * Objects to the appropriate method.

+ * + *

Either detail or summary views can be specified.

+ * + *

If a cycle is detected, an object will be appended with the + * Object.toString() format.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param value the value to add to the toString, + * not null + * @param detail output detail or not + */ + protected void appendInternal(StringBuffer buffer, String fieldName, Object value, boolean detail) { + if (ReflectionToStringBuilder.isRegistered(value) + && !(value instanceof Number || value instanceof Boolean || value instanceof Character)) { + ObjectUtils.appendIdentityToString(buffer, value); + + } else if (value instanceof Collection) { + if (detail) { + appendDetail(buffer, fieldName, (Collection) value); + } else { + appendSummarySize(buffer, fieldName, ((Collection) value).size()); + } + + } else if (value instanceof Map) { + if (detail) { + appendDetail(buffer, fieldName, (Map) value); + } else { + appendSummarySize(buffer, fieldName, ((Map) value).size()); + } + + } else if (value instanceof long[]) { + if (detail) { + appendDetail(buffer, fieldName, (long[]) value); + } else { + appendSummary(buffer, fieldName, (long[]) value); + } + + } else if (value instanceof int[]) { + if (detail) { + appendDetail(buffer, fieldName, (int[]) value); + } else { + appendSummary(buffer, fieldName, (int[]) value); + } + + } else if (value instanceof short[]) { + if (detail) { + appendDetail(buffer, fieldName, (short[]) value); + } else { + appendSummary(buffer, fieldName, (short[]) value); + } + + } else if (value instanceof byte[]) { + if (detail) { + appendDetail(buffer, fieldName, (byte[]) value); + } else { + appendSummary(buffer, fieldName, (byte[]) value); + } + + } else if (value instanceof char[]) { + if (detail) { + appendDetail(buffer, fieldName, (char[]) value); + } else { + appendSummary(buffer, fieldName, (char[]) value); + } + + } else if (value instanceof double[]) { + if (detail) { + appendDetail(buffer, fieldName, (double[]) value); + } else { + appendSummary(buffer, fieldName, (double[]) value); + } + + } else if (value instanceof float[]) { + if (detail) { + appendDetail(buffer, fieldName, (float[]) value); + } else { + appendSummary(buffer, fieldName, (float[]) value); + } + + } else if (value instanceof boolean[]) { + if (detail) { + appendDetail(buffer, fieldName, (boolean[]) value); + } else { + appendSummary(buffer, fieldName, (boolean[]) value); + } + + } else if (value.getClass().isArray()) { + if (detail) { + appendDetail(buffer, fieldName, (Object[]) value); + } else { + appendSummary(buffer, fieldName, (Object[]) value); + } + + } else { + if (detail) { + appendDetail(buffer, fieldName, value); + } else { + appendSummary(buffer, fieldName, value); + } + } + } + + /** + *

Append to the toString an Object + * value, printing the full detail of the Object.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param value the value to add to the toString, + * not null + */ + protected void appendDetail(StringBuffer buffer, String fieldName, Object value) { + buffer.append(value); + } + + /** + *

Append to the toString a Collection.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param coll the Collection to add to the + * toString, not null + */ + protected void appendDetail(StringBuffer buffer, String fieldName, Collection coll) { + buffer.append(coll); + } + + /** + *

Append to the toString a Map.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param map the Map to add to the toString, + * not null + */ + protected void appendDetail(StringBuffer buffer, String fieldName, Map map) { + buffer.append(map); + } + + /** + *

Append to the toString an Object + * value, printing a summary of the Object.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param value the value to add to the toString, + * not null + */ + protected void appendSummary(StringBuffer buffer, String fieldName, Object value) { + buffer.append(summaryObjectStartText); + buffer.append(getShortClassName(value.getClass())); + buffer.append(summaryObjectEndText); + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString a long + * value.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name + * @param value the value to add to the toString + */ + public void append(StringBuffer buffer, String fieldName, long value) { + appendFieldStart(buffer, fieldName); + appendDetail(buffer, fieldName, value); + appendFieldEnd(buffer, fieldName); + } + + /** + *

Append to the toString a long + * value.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param value the value to add to the toString + */ + protected void appendDetail(StringBuffer buffer, String fieldName, long value) { + buffer.append(value); + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString an int + * value.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name + * @param value the value to add to the toString + */ + public void append(StringBuffer buffer, String fieldName, int value) { + appendFieldStart(buffer, fieldName); + appendDetail(buffer, fieldName, value); + appendFieldEnd(buffer, fieldName); + } + + /** + *

Append to the toString an int + * value.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param value the value to add to the toString + */ + protected void appendDetail(StringBuffer buffer, String fieldName, int value) { + buffer.append(value); + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString a short + * value.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name + * @param value the value to add to the toString + */ + public void append(StringBuffer buffer, String fieldName, short value) { + appendFieldStart(buffer, fieldName); + appendDetail(buffer, fieldName, value); + appendFieldEnd(buffer, fieldName); + } + + /** + *

Append to the toString a short + * value.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param value the value to add to the toString + */ + protected void appendDetail(StringBuffer buffer, String fieldName, short value) { + buffer.append(value); + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString a byte + * value.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name + * @param value the value to add to the toString + */ + public void append(StringBuffer buffer, String fieldName, byte value) { + appendFieldStart(buffer, fieldName); + appendDetail(buffer, fieldName, value); + appendFieldEnd(buffer, fieldName); + } + + /** + *

Append to the toString a byte + * value.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param value the value to add to the toString + */ + protected void appendDetail(StringBuffer buffer, String fieldName, byte value) { + buffer.append(value); + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString a char + * value.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name + * @param value the value to add to the toString + */ + public void append(StringBuffer buffer, String fieldName, char value) { + appendFieldStart(buffer, fieldName); + appendDetail(buffer, fieldName, value); + appendFieldEnd(buffer, fieldName); + } + + /** + *

Append to the toString a char + * value.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param value the value to add to the toString + */ + protected void appendDetail(StringBuffer buffer, String fieldName, char value) { + buffer.append(value); + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString a double + * value.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name + * @param value the value to add to the toString + */ + public void append(StringBuffer buffer, String fieldName, double value) { + appendFieldStart(buffer, fieldName); + appendDetail(buffer, fieldName, value); + appendFieldEnd(buffer, fieldName); + } + + /** + *

Append to the toString a double + * value.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param value the value to add to the toString + */ + protected void appendDetail(StringBuffer buffer, String fieldName, double value) { + buffer.append(value); + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString a float + * value.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name + * @param value the value to add to the toString + */ + public void append(StringBuffer buffer, String fieldName, float value) { + appendFieldStart(buffer, fieldName); + appendDetail(buffer, fieldName, value); + appendFieldEnd(buffer, fieldName); + } + + /** + *

Append to the toString a float + * value.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param value the value to add to the toString + */ + protected void appendDetail(StringBuffer buffer, String fieldName, float value) { + buffer.append(value); + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString a boolean + * value.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name + * @param value the value to add to the toString + */ + public void append(StringBuffer buffer, String fieldName, boolean value) { + appendFieldStart(buffer, fieldName); + appendDetail(buffer, fieldName, value); + appendFieldEnd(buffer, fieldName); + } + + /** + *

Append to the toString a boolean + * value.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param value the value to add to the toString + */ + protected void appendDetail(StringBuffer buffer, String fieldName, boolean value) { + buffer.append(value); + } + + /** + *

Append to the toString an Object + * array.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name + * @param array the array to add to the toString + * @param fullDetail true for detail, false + * for summary info, null for style decides + */ + public void append(StringBuffer buffer, String fieldName, Object[] array, Boolean fullDetail) { + appendFieldStart(buffer, fieldName); + + if (array == null) { + appendNullText(buffer, fieldName); + + } else if (isFullDetail(fullDetail)) { + appendDetail(buffer, fieldName, array); + + } else { + appendSummary(buffer, fieldName, array); + } + + appendFieldEnd(buffer, fieldName); + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString the detail of an + * Object array.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param array the array to add to the toString, + * not null + */ + protected void appendDetail(StringBuffer buffer, String fieldName, Object[] array) { + buffer.append(arrayStart); + for (int i = 0; i < array.length; i++) { + Object item = array[i]; + if (i > 0) { + buffer.append(arraySeparator); + } + if (item == null) { + appendNullText(buffer, fieldName); + + } else { + appendInternal(buffer, fieldName, item, arrayContentDetail); + } + } + buffer.append(arrayEnd); + } + + /** + *

Append to the toString the detail of an array type.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param array the array to add to the toString, + * not null + * @since 2.0 + */ + protected void reflectionAppendArrayDetail(StringBuffer buffer, String fieldName, Object array) { + buffer.append(arrayStart); + int length = Array.getLength(array); + for (int i = 0; i < length; i++) { + Object item = Array.get(array, i); + if (i > 0) { + buffer.append(arraySeparator); + } + if (item == null) { + appendNullText(buffer, fieldName); + + } else { + appendInternal(buffer, fieldName, item, arrayContentDetail); + } + } + buffer.append(arrayEnd); + } + + /** + *

Append to the toString a summary of an + * Object array.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param array the array to add to the toString, + * not null + */ + protected void appendSummary(StringBuffer buffer, String fieldName, Object[] array) { + appendSummarySize(buffer, fieldName, array.length); + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString a long + * array.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name + * @param array the array to add to the toString + * @param fullDetail true for detail, false + * for summary info, null for style decides + */ + public void append(StringBuffer buffer, String fieldName, long[] array, Boolean fullDetail) { + appendFieldStart(buffer, fieldName); + + if (array == null) { + appendNullText(buffer, fieldName); + + } else if (isFullDetail(fullDetail)) { + appendDetail(buffer, fieldName, array); + + } else { + appendSummary(buffer, fieldName, array); + } + + appendFieldEnd(buffer, fieldName); + } + + /** + *

Append to the toString the detail of a + * long array.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param array the array to add to the toString, + * not null + */ + protected void appendDetail(StringBuffer buffer, String fieldName, long[] array) { + buffer.append(arrayStart); + for (int i = 0; i < array.length; i++) { + if (i > 0) { + buffer.append(arraySeparator); + } + appendDetail(buffer, fieldName, array[i]); + } + buffer.append(arrayEnd); + } + + /** + *

Append to the toString a summary of a + * long array.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param array the array to add to the toString, + * not null + */ + protected void appendSummary(StringBuffer buffer, String fieldName, long[] array) { + appendSummarySize(buffer, fieldName, array.length); + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString an int + * array.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name + * @param array the array to add to the toString + * @param fullDetail true for detail, false + * for summary info, null for style decides + */ + public void append(StringBuffer buffer, String fieldName, int[] array, Boolean fullDetail) { + appendFieldStart(buffer, fieldName); + + if (array == null) { + appendNullText(buffer, fieldName); + + } else if (isFullDetail(fullDetail)) { + appendDetail(buffer, fieldName, array); + + } else { + appendSummary(buffer, fieldName, array); + } + + appendFieldEnd(buffer, fieldName); + } + + /** + *

Append to the toString the detail of an + * int array.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param array the array to add to the toString, + * not null + */ + protected void appendDetail(StringBuffer buffer, String fieldName, int[] array) { + buffer.append(arrayStart); + for (int i = 0; i < array.length; i++) { + if (i > 0) { + buffer.append(arraySeparator); + } + appendDetail(buffer, fieldName, array[i]); + } + buffer.append(arrayEnd); + } + + /** + *

Append to the toString a summary of an + * int array.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param array the array to add to the toString, + * not null + */ + protected void appendSummary(StringBuffer buffer, String fieldName, int[] array) { + appendSummarySize(buffer, fieldName, array.length); + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString a short + * array.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name + * @param array the array to add to the toString + * @param fullDetail true for detail, false + * for summary info, null for style decides + */ + public void append(StringBuffer buffer, String fieldName, short[] array, Boolean fullDetail) { + appendFieldStart(buffer, fieldName); + + if (array == null) { + appendNullText(buffer, fieldName); + + } else if (isFullDetail(fullDetail)) { + appendDetail(buffer, fieldName, array); + + } else { + appendSummary(buffer, fieldName, array); + } + + appendFieldEnd(buffer, fieldName); + } + + /** + *

Append to the toString the detail of a + * short array.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param array the array to add to the toString, + * not null + */ + protected void appendDetail(StringBuffer buffer, String fieldName, short[] array) { + buffer.append(arrayStart); + for (int i = 0; i < array.length; i++) { + if (i > 0) { + buffer.append(arraySeparator); + } + appendDetail(buffer, fieldName, array[i]); + } + buffer.append(arrayEnd); + } + + /** + *

Append to the toString a summary of a + * short array.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param array the array to add to the toString, + * not null + */ + protected void appendSummary(StringBuffer buffer, String fieldName, short[] array) { + appendSummarySize(buffer, fieldName, array.length); + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString a byte + * array.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name + * @param array the array to add to the toString + * @param fullDetail true for detail, false + * for summary info, null for style decides + */ + public void append(StringBuffer buffer, String fieldName, byte[] array, Boolean fullDetail) { + appendFieldStart(buffer, fieldName); + + if (array == null) { + appendNullText(buffer, fieldName); + + } else if (isFullDetail(fullDetail)) { + appendDetail(buffer, fieldName, array); + + } else { + appendSummary(buffer, fieldName, array); + } + + appendFieldEnd(buffer, fieldName); + } + + /** + *

Append to the toString the detail of a + * byte array.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param array the array to add to the toString, + * not null + */ + protected void appendDetail(StringBuffer buffer, String fieldName, byte[] array) { + buffer.append(arrayStart); + for (int i = 0; i < array.length; i++) { + if (i > 0) { + buffer.append(arraySeparator); + } + appendDetail(buffer, fieldName, array[i]); + } + buffer.append(arrayEnd); + } + + /** + *

Append to the toString a summary of a + * byte array.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param array the array to add to the toString, + * not null + */ + protected void appendSummary(StringBuffer buffer, String fieldName, byte[] array) { + appendSummarySize(buffer, fieldName, array.length); + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString a char + * array.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name + * @param array the array to add to the toString + * @param fullDetail true for detail, false + * for summary info, null for style decides + */ + public void append(StringBuffer buffer, String fieldName, char[] array, Boolean fullDetail) { + appendFieldStart(buffer, fieldName); + + if (array == null) { + appendNullText(buffer, fieldName); + + } else if (isFullDetail(fullDetail)) { + appendDetail(buffer, fieldName, array); + + } else { + appendSummary(buffer, fieldName, array); + } + + appendFieldEnd(buffer, fieldName); + } + + /** + *

Append to the toString the detail of a + * char array.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param array the array to add to the toString, + * not null + */ + protected void appendDetail(StringBuffer buffer, String fieldName, char[] array) { + buffer.append(arrayStart); + for (int i = 0; i < array.length; i++) { + if (i > 0) { + buffer.append(arraySeparator); + } + appendDetail(buffer, fieldName, array[i]); + } + buffer.append(arrayEnd); + } + + /** + *

Append to the toString a summary of a + * char array.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param array the array to add to the toString, + * not null + */ + protected void appendSummary(StringBuffer buffer, String fieldName, char[] array) { + appendSummarySize(buffer, fieldName, array.length); + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString a double + * array.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name + * @param array the array to add to the toString + * @param fullDetail true for detail, false + * for summary info, null for style decides + */ + public void append(StringBuffer buffer, String fieldName, double[] array, Boolean fullDetail) { + appendFieldStart(buffer, fieldName); + + if (array == null) { + appendNullText(buffer, fieldName); + + } else if (isFullDetail(fullDetail)) { + appendDetail(buffer, fieldName, array); + + } else { + appendSummary(buffer, fieldName, array); + } + + appendFieldEnd(buffer, fieldName); + } + + /** + *

Append to the toString the detail of a + * double array.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param array the array to add to the toString, + * not null + */ + protected void appendDetail(StringBuffer buffer, String fieldName, double[] array) { + buffer.append(arrayStart); + for (int i = 0; i < array.length; i++) { + if (i > 0) { + buffer.append(arraySeparator); + } + appendDetail(buffer, fieldName, array[i]); + } + buffer.append(arrayEnd); + } + + /** + *

Append to the toString a summary of a + * double array.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param array the array to add to the toString, + * not null + */ + protected void appendSummary(StringBuffer buffer, String fieldName, double[] array) { + appendSummarySize(buffer, fieldName, array.length); + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString a float + * array.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name + * @param array the array to add to the toString + * @param fullDetail true for detail, false + * for summary info, null for style decides + */ + public void append(StringBuffer buffer, String fieldName, float[] array, Boolean fullDetail) { + appendFieldStart(buffer, fieldName); + + if (array == null) { + appendNullText(buffer, fieldName); + + } else if (isFullDetail(fullDetail)) { + appendDetail(buffer, fieldName, array); + + } else { + appendSummary(buffer, fieldName, array); + } + + appendFieldEnd(buffer, fieldName); + } + + /** + *

Append to the toString the detail of a + * float array.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param array the array to add to the toString, + * not null + */ + protected void appendDetail(StringBuffer buffer, String fieldName, float[] array) { + buffer.append(arrayStart); + for (int i = 0; i < array.length; i++) { + if (i > 0) { + buffer.append(arraySeparator); + } + appendDetail(buffer, fieldName, array[i]); + } + buffer.append(arrayEnd); + } + + /** + *

Append to the toString a summary of a + * float array.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param array the array to add to the toString, + * not null + */ + protected void appendSummary(StringBuffer buffer, String fieldName, float[] array) { + appendSummarySize(buffer, fieldName, array.length); + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString a boolean + * array.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name + * @param array the array to add to the toString + * @param fullDetail true for detail, false + * for summary info, null for style decides + */ + public void append(StringBuffer buffer, String fieldName, boolean[] array, Boolean fullDetail) { + appendFieldStart(buffer, fieldName); + + if (array == null) { + appendNullText(buffer, fieldName); + + } else if (isFullDetail(fullDetail)) { + appendDetail(buffer, fieldName, array); + + } else { + appendSummary(buffer, fieldName, array); + } + + appendFieldEnd(buffer, fieldName); + } + + /** + *

Append to the toString the detail of a + * boolean array.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param array the array to add to the toString, + * not null + */ + protected void appendDetail(StringBuffer buffer, String fieldName, boolean[] array) { + buffer.append(arrayStart); + for (int i = 0; i < array.length; i++) { + if (i > 0) { + buffer.append(arraySeparator); + } + appendDetail(buffer, fieldName, array[i]); + } + buffer.append(arrayEnd); + } + + /** + *

Append to the toString a summary of a + * boolean array.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param array the array to add to the toString, + * not null + */ + protected void appendSummary(StringBuffer buffer, String fieldName, boolean[] array) { + appendSummarySize(buffer, fieldName, array.length); + } + + //---------------------------------------------------------------------------- + + /** + *

Append to the toString the class name.

+ * + * @param buffer the StringBuffer to populate + * @param object the Object whose name to output + */ + protected void appendClassName(StringBuffer buffer, Object object) { + if (useClassName) { + if (useShortClassName) { + buffer.append(getShortClassName(object.getClass())); + } else { + buffer.append(object.getClass().getName()); + } + } + } + + /** + *

Append the {@link System#identityHashCode(java.lang.Object)}.

+ * + * @param buffer the StringBuffer to populate + * @param object the Object whose id to output + */ + protected void appendIdentityHashCode(StringBuffer buffer, Object object) { + if (useIdentityHashCode) { + buffer.append('@'); + buffer.append(Integer.toHexString(System.identityHashCode(object))); + } + } + + /** + *

Append to the toString the content start.

+ * + * @param buffer the StringBuffer to populate + */ + protected void appendContentStart(StringBuffer buffer) { + buffer.append(contentStart); + } + + /** + *

Append to the toString the content end.

+ * + * @param buffer the StringBuffer to populate + */ + protected void appendContentEnd(StringBuffer buffer) { + buffer.append(contentEnd); + } + + /** + *

Append to the toString an indicator for null.

+ * + *

The default indicator is '<null>'.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + */ + protected void appendNullText(StringBuffer buffer, String fieldName) { + buffer.append(nullText); + } + + /** + *

Append to the toString the field separator.

+ * + * @param buffer the StringBuffer to populate + */ + protected void appendFieldSeparator(StringBuffer buffer) { + buffer.append(fieldSeparator); + } + + /** + *

Append to the toString the field start.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name + */ + protected void appendFieldStart(StringBuffer buffer, String fieldName) { + if (useFieldNames && fieldName != null) { + buffer.append(fieldName); + buffer.append(fieldNameValueSeparator); + } + } + + /** + *

Append to the toString the field end.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + */ + protected void appendFieldEnd(StringBuffer buffer, String fieldName) { + appendFieldSeparator(buffer); + } + + /** + *

Append to the toString a size summary.

+ * + *

The size summary is used to summarize the contents of + * Collections, Maps and arrays.

+ * + *

The output consists of a prefix, the passed in size + * and a suffix.

+ * + *

The default format is '<size=n>'.

+ * + * @param buffer the StringBuffer to populate + * @param fieldName the field name, typically not used as already appended + * @param size the size to append + */ + protected void appendSummarySize(StringBuffer buffer, String fieldName, int size) { + buffer.append(sizeStartText); + buffer.append(size); + buffer.append(sizeEndText); + } + + /** + *

Is this field to be output in full detail.

+ * + *

This method converts a detail request into a detail level. + * The calling code may request full detail (true), + * but a subclass might ignore that and always return + * false. The calling code may pass in + * null indicating that it doesn't care about + * the detail level. In this case the default detail level is + * used.

+ * + * @param fullDetailRequest the detail level requested + * @return whether full detail is to be shown + */ + protected boolean isFullDetail(Boolean fullDetailRequest) { + if (fullDetailRequest == null) { + return defaultFullDetail; + } + return fullDetailRequest.booleanValue(); + } + + /** + *

Gets the short class name for a class.

+ * + *

The short class name is the classname excluding + * the package name.

+ * + * @param cls the Class to get the short name of + * @return the short name + */ + protected String getShortClassName(Class cls) { + return ClassUtils.getShortClassName(cls); + } + + // Setters and getters for the customizable parts of the style + // These methods are not expected to be overridden, except to make public + // (They are not public so that immutable subclasses can be written) + //--------------------------------------------------------------------- + + /** + *

Gets whether to use the class name.

+ * + * @return the current useClassName flag + */ + protected boolean isUseClassName() { + return useClassName; + } + + /** + *

Sets whether to use the class name.

+ * + * @param useClassName the new useClassName flag + */ + protected void setUseClassName(boolean useClassName) { + this.useClassName = useClassName; + } + + //--------------------------------------------------------------------- + + /** + *

Gets whether to output short or long class names.

+ * + * @return the current useShortClassName flag + * @since 2.0 + */ + protected boolean isUseShortClassName() { + return useShortClassName; + } + + /** + *

Gets whether to output short or long class names.

+ * + * @return the current shortClassName flag + * @deprecated Use {@link #isUseShortClassName()} + * Method will be removed in Commons Lang 3.0. + */ + protected boolean isShortClassName() { + return useShortClassName; + } + + /** + *

Sets whether to output short or long class names.

+ * + * @param useShortClassName the new useShortClassName flag + * @since 2.0 + */ + protected void setUseShortClassName(boolean useShortClassName) { + this.useShortClassName = useShortClassName; + } + + /** + *

Sets whether to output short or long class names.

+ * + * @param shortClassName the new shortClassName flag + * @deprecated Use {@link #setUseShortClassName(boolean)} + * Method will be removed in Commons Lang 3.0. + */ + protected void setShortClassName(boolean shortClassName) { + this.useShortClassName = shortClassName; + } + + //--------------------------------------------------------------------- + + /** + *

Gets whether to use the identity hash code.

+ * + * @return the current useIdentityHashCode flag + */ + protected boolean isUseIdentityHashCode() { + return useIdentityHashCode; + } + + /** + *

Sets whether to use the identity hash code.

+ * + * @param useIdentityHashCode the new useIdentityHashCode flag + */ + protected void setUseIdentityHashCode(boolean useIdentityHashCode) { + this.useIdentityHashCode = useIdentityHashCode; + } + + //--------------------------------------------------------------------- + + /** + *

Gets whether to use the field names passed in.

+ * + * @return the current useFieldNames flag + */ + protected boolean isUseFieldNames() { + return useFieldNames; + } + + /** + *

Sets whether to use the field names passed in.

+ * + * @param useFieldNames the new useFieldNames flag + */ + protected void setUseFieldNames(boolean useFieldNames) { + this.useFieldNames = useFieldNames; + } + + //--------------------------------------------------------------------- + + /** + *

Gets whether to use full detail when the caller doesn't + * specify.

+ * + * @return the current defaultFullDetail flag + */ + protected boolean isDefaultFullDetail() { + return defaultFullDetail; + } + + /** + *

Sets whether to use full detail when the caller doesn't + * specify.

+ * + * @param defaultFullDetail the new defaultFullDetail flag + */ + protected void setDefaultFullDetail(boolean defaultFullDetail) { + this.defaultFullDetail = defaultFullDetail; + } + + //--------------------------------------------------------------------- + + /** + *

Gets whether to output array content detail.

+ * + * @return the current array content detail setting + */ + protected boolean isArrayContentDetail() { + return arrayContentDetail; + } + + /** + *

Sets whether to output array content detail.

+ * + * @param arrayContentDetail the new arrayContentDetail flag + */ + protected void setArrayContentDetail(boolean arrayContentDetail) { + this.arrayContentDetail = arrayContentDetail; + } + + //--------------------------------------------------------------------- + + /** + *

Gets the array start text.

+ * + * @return the current array start text + */ + protected String getArrayStart() { + return arrayStart; + } + + /** + *

Sets the array start text.

+ * + *

null is accepted, but will be converted to + * an empty String.

+ * + * @param arrayStart the new array start text + */ + protected void setArrayStart(String arrayStart) { + if (arrayStart == null) { + arrayStart = ""; + } + this.arrayStart = arrayStart; + } + + //--------------------------------------------------------------------- + + /** + *

Gets the array end text.

+ * + * @return the current array end text + */ + protected String getArrayEnd() { + return arrayEnd; + } + + /** + *

Sets the array end text.

+ * + *

null is accepted, but will be converted to + * an empty String.

+ * + * @param arrayEnd the new array end text + */ + protected void setArrayEnd(String arrayEnd) { + if (arrayStart == null) { + arrayStart = ""; + } + this.arrayEnd = arrayEnd; + } + + //--------------------------------------------------------------------- + + /** + *

Gets the array separator text.

+ * + * @return the current array separator text + */ + protected String getArraySeparator() { + return arraySeparator; + } + + /** + *

Sets the array separator text.

+ * + *

null is accepted, but will be converted to + * an empty String.

+ * + * @param arraySeparator the new array separator text + */ + protected void setArraySeparator(String arraySeparator) { + if (arraySeparator == null) { + arraySeparator = ""; + } + this.arraySeparator = arraySeparator; + } + + //--------------------------------------------------------------------- + + /** + *

Gets the content start text.

+ * + * @return the current content start text + */ + protected String getContentStart() { + return contentStart; + } + + /** + *

Sets the content start text.

+ * + *

null is accepted, but will be converted to + * an empty String.

+ * + * @param contentStart the new content start text + */ + protected void setContentStart(String contentStart) { + if (contentStart == null) { + contentStart = ""; + } + this.contentStart = contentStart; + } + + //--------------------------------------------------------------------- + + /** + *

Gets the content end text.

+ * + * @return the current content end text + */ + protected String getContentEnd() { + return contentEnd; + } + + /** + *

Sets the content end text.

+ * + *

null is accepted, but will be converted to + * an empty String.

+ * + * @param contentEnd the new content end text + */ + protected void setContentEnd(String contentEnd) { + if (contentEnd == null) { + contentEnd = ""; + } + this.contentEnd = contentEnd; + } + + //--------------------------------------------------------------------- + + /** + *

Gets the field name value separator text.

+ * + * @return the current field name value separator text + */ + protected String getFieldNameValueSeparator() { + return fieldNameValueSeparator; + } + + /** + *

Sets the field name value separator text.

+ * + *

null is accepted, but will be converted to + * an empty String.

+ * + * @param fieldNameValueSeparator the new field name value separator text + */ + protected void setFieldNameValueSeparator(String fieldNameValueSeparator) { + if (fieldNameValueSeparator == null) { + fieldNameValueSeparator = ""; + } + this.fieldNameValueSeparator = fieldNameValueSeparator; + } + + //--------------------------------------------------------------------- + + /** + *

Gets the field separator text.

+ * + * @return the current field separator text + */ + protected String getFieldSeparator() { + return fieldSeparator; + } + + /** + *

Sets the field separator text.

+ * + *

null is accepted, but will be converted to + * an empty String.

+ * + * @param fieldSeparator the new field separator text + */ + protected void setFieldSeparator(String fieldSeparator) { + if (fieldSeparator == null) { + fieldSeparator = ""; + } + this.fieldSeparator = fieldSeparator; + } + + //--------------------------------------------------------------------- + + /** + *

Gets whether the field separator should be added at the start + * of each buffer.

+ * + * @return the fieldSeparatorAtStart flag + * @since 2.0 + */ + protected boolean isFieldSeparatorAtStart() { + return fieldSeparatorAtStart; + } + + /** + *

Sets whether the field separator should be added at the start + * of each buffer.

+ * + * @param fieldSeparatorAtStart the fieldSeparatorAtStart flag + * @since 2.0 + */ + protected void setFieldSeparatorAtStart(boolean fieldSeparatorAtStart) { + this.fieldSeparatorAtStart = fieldSeparatorAtStart; + } + + //--------------------------------------------------------------------- + + /** + *

Gets whether the field separator should be added at the end + * of each buffer.

+ * + * @return fieldSeparatorAtEnd flag + * @since 2.0 + */ + protected boolean isFieldSeparatorAtEnd() { + return fieldSeparatorAtEnd; + } + + /** + *

Sets whether the field separator should be added at the end + * of each buffer.

+ * + * @param fieldSeparatorAtEnd the fieldSeparatorAtEnd flag + * @since 2.0 + */ + protected void setFieldSeparatorAtEnd(boolean fieldSeparatorAtEnd) { + this.fieldSeparatorAtEnd = fieldSeparatorAtEnd; + } + + //--------------------------------------------------------------------- + + /** + *

Gets the text to output when null found.

+ * + * @return the current text to output when null found + */ + protected String getNullText() { + return nullText; + } + + /** + *

Sets the text to output when null found.

+ * + *

null is accepted, but will be converted to + * an empty String.

+ * + * @param nullText the new text to output when null found + */ + protected void setNullText(String nullText) { + if (nullText == null) { + nullText = ""; + } + this.nullText = nullText; + } + + //--------------------------------------------------------------------- + + /** + *

Gets the start text to output when a Collection, + * Map or array size is output.

+ * + *

This is output before the size value.

+ * + * @return the current start of size text + */ + protected String getSizeStartText() { + return sizeStartText; + } + + /** + *

Sets the start text to output when a Collection, + * Map or array size is output.

+ * + *

This is output before the size value.

+ * + *

null is accepted, but will be converted to + * an empty String.

+ * + * @param sizeStartText the new start of size text + */ + protected void setSizeStartText(String sizeStartText) { + if (sizeStartText == null) { + sizeStartText = ""; + } + this.sizeStartText = sizeStartText; + } + + //--------------------------------------------------------------------- + + /** + *

Gets the end text to output when a Collection, + * Map or array size is output.

+ * + *

This is output after the size value.

+ * + * @return the current end of size text + */ + protected String getSizeEndText() { + return sizeEndText; + } + + /** + *

Sets the end text to output when a Collection, + * Map or array size is output.

+ * + *

This is output after the size value.

+ * + *

null is accepted, but will be converted to + * an empty String.

+ * + * @param sizeEndText the new end of size text + */ + protected void setSizeEndText(String sizeEndText) { + if (sizeEndText == null) { + sizeEndText = ""; + } + this.sizeEndText = sizeEndText; + } + + //--------------------------------------------------------------------- + + /** + *

Gets the start text to output when an Object is + * output in summary mode.

+ * + *

This is output before the size value.

+ * + * @return the current start of summary text + */ + protected String getSummaryObjectStartText() { + return summaryObjectStartText; + } + + /** + *

Sets the start text to output when an Object is + * output in summary mode.

+ * + *

This is output before the size value.

+ * + *

null is accepted, but will be converted to + * an empty String.

+ * + * @param summaryObjectStartText the new start of summary text + */ + protected void setSummaryObjectStartText(String summaryObjectStartText) { + if (summaryObjectStartText == null) { + summaryObjectStartText = ""; + } + this.summaryObjectStartText = summaryObjectStartText; + } + + //--------------------------------------------------------------------- + + /** + *

Gets the end text to output when an Object is + * output in summary mode.

+ * + *

This is output after the size value.

+ * + * @return the current end of summary text + */ + protected String getSummaryObjectEndText() { + return summaryObjectEndText; + } + + /** + *

Sets the end text to output when an Object is + * output in summary mode.

+ * + *

This is output after the size value.

+ * + *

null is accepted, but will be converted to + * an empty String.

+ * + * @param summaryObjectEndText the new end of summary text + */ + protected void setSummaryObjectEndText(String summaryObjectEndText) { + if (summaryObjectEndText == null) { + summaryObjectEndText = ""; + } + this.summaryObjectEndText = summaryObjectEndText; + } + + //---------------------------------------------------------------------------- + + /** + *

Default ToStringStyle.

+ * + *

This is an inner class rather than using + * StandardToStringStyle to ensure its immutability.

+ */ + private static final class DefaultToStringStyle extends ToStringStyle { + + /** + *

Constructor.

+ * + *

Use the static constant rather than instantiating.

+ */ + private DefaultToStringStyle() { + super(); + } + + /** + *

Ensure Singleton after serialization.

+ * + * @return the singleton + */ + private Object readResolve() { + return ToStringStyle.DEFAULT_STYLE; + } + + } + + //---------------------------------------------------------------------------- + + /** + *

ToStringStyle that does not print out + * the field names.

+ * + *

This is an inner class rather than using + * StandardToStringStyle to ensure its immutability. + */ + private static final class NoFieldNameToStringStyle extends ToStringStyle { + + /** + *

Constructor.

+ * + *

Use the static constant rather than instantiating.

+ */ + private NoFieldNameToStringStyle() { + super(); + this.setUseFieldNames(false); + } + + /** + *

Ensure Singleton after serialization.

+ * + * @return the singleton + */ + private Object readResolve() { + return ToStringStyle.NO_FIELD_NAMES_STYLE; + } + + } + + //---------------------------------------------------------------------------- + + /** + *

ToStringStyle that does not print out the + * classname, identity hashcode, content start or field name.

+ * + *

This is an inner class rather than using + * StandardToStringStyle to ensure its immutability.

+ */ + private static final class SimpleToStringStyle extends ToStringStyle { + + /** + *

Constructor.

+ * + *

Use the static constant rather than instantiating.

+ */ + private SimpleToStringStyle() { + super(); + this.setUseClassName(false); + this.setUseIdentityHashCode(false); + this.setUseFieldNames(false); + this.setContentStart(""); + this.setContentEnd(""); + } + + /** + *

Ensure Singleton after serialization.

+ * @return the singleton + */ + private Object readResolve() { + return ToStringStyle.SIMPLE_STYLE; + } + + } + + //---------------------------------------------------------------------------- + + /** + *

ToStringStyle that outputs on multiple lines.

+ * + *

This is an inner class rather than using + * StandardToStringStyle to ensure its immutability.

+ */ + private static final class MultiLineToStringStyle extends ToStringStyle { + + /** + *

Constructor.

+ * + *

Use the static constant rather than instantiating.

+ */ + private MultiLineToStringStyle() { + super(); + this.setContentStart("["); + this.setFieldSeparator(SystemUtils.LINE_SEPARATOR + " "); + this.setFieldSeparatorAtStart(true); + this.setContentEnd(SystemUtils.LINE_SEPARATOR + "]"); + } + + /** + *

Ensure Singleton after serialization.

+ * + * @return the singleton + */ + private Object readResolve() { + return ToStringStyle.MULTI_LINE_STYLE; + } + + } + + //---------------------------------------------------------------------------- + +// Removed, as the XML style needs more work for escaping characters, arrays, +// collections, maps and embedded beans. +// /** +// * ToStringStyle that outputs in XML style +// */ +// private static class XMLToStringStyle extends ToStringStyle { +// +// /** +// * Constructor - use the static constant rather than instantiating. +// */ +// private XMLToStringStyle() { +// super(); +// nullText = "null"; +// sizeStartText = "size="; +// sizeEndText = ""; +// } +// +// /** +// * @see ToStringStyle#appendStart(StringBuffer, Object) +// */ +// public void appendStart(StringBuffer buffer, Object object) { +// buffer.append('<'); +// buffer.append(getShortClassName(object.getClass())); +// buffer.append(" class=\""); +// appendClassName(buffer, object); +// buffer.append("\" hashCode=\""); +// appendIdentityHashCode(buffer, object); +// buffer.append("\">"); +// buffer.append(SystemUtils.LINE_SEPARATOR); +// buffer.append(" "); +// } +// +// /** +// * @see ToStringStyle#appendFieldStart(StringBuffer, String) +// */ +// protected void appendFieldStart(StringBuffer buffer, String fieldName) { +// buffer.append('<'); +// buffer.append(fieldName); +// buffer.append('>'); +// } +// +// /** +// * @see ToStringStyle#appendFieldEnd(StringBuffer, String) +// */ +// protected void appendFieldEnd(StringBuffer buffer, String fieldName) { +// buffer.append("'); +// buffer.append(SystemUtils.LINE_SEPARATOR); +// buffer.append(" "); +// } +// +// /** +// * @see ToStringStyle#appendEnd(StringBuffer, Object) +// */ +// public void appendEnd(StringBuffer buffer, Object object) { +// int len = buffer.length(); +// if (len > 2 && buffer.charAt(len - 1) == ' ' && buffer.charAt(len - 2) == ' ') { +// buffer.setLength(len - 2); +// } +// buffer.append(""); +// } +// +// } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/builder/package.html =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/builder/package.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/builder/package.html 30 Aug 2012 16:24:43 -0000 1.1 @@ -0,0 +1,7 @@ + + +Assists in creating consistent equals(Object), toString(), +hashCode(), and compareTo(Object) methods. +@since 1.0 + + Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/enum/Enum.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/enum/Enum.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/enum/Enum.java 30 Aug 2012 16:24:43 -0000 1.1 @@ -0,0 +1,595 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.enum; + +import java.io.Serializable; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang.ClassUtils; +import org.apache.commons.lang.StringUtils; + +/** + *

Abstract superclass for type-safe enums.

+ * + *

One feature of the C programming language lacking in Java is enumerations. The + * C implementation based on ints was poor and open to abuse. The original Java + * recommendation and most of the JDK also uses int constants. It has been recognised + * however that a more robust type-safe class-based solution can be designed. This + * class follows the basic Java type-safe enumeration pattern.

+ * + *

NOTE:Due to the way in which Java ClassLoaders work, comparing + * Enum objects should always be done using equals(), not ==. + * The equals() method will try == first so in most cases the effect is the same.

+ * + *

Of course, if you actually want (or don't mind) Enums in different class + * loaders being non-equal, then you can use ==.

+ * + *

Simple Enums

+ * + *

To use this class, it must be subclassed. For example:

+ * + *
+ * public final class ColorEnum extends Enum {
+ *   public static final ColorEnum RED = new ColorEnum("Red");
+ *   public static final ColorEnum GREEN = new ColorEnum("Green");
+ *   public static final ColorEnum BLUE = new ColorEnum("Blue");
+ *
+ *   private ColorEnum(String color) {
+ *     super(color);
+ *   }
+ * 
+ *   public static ColorEnum getEnum(String color) {
+ *     return (ColorEnum) getEnum(ColorEnum.class, color);
+ *   }
+ * 
+ *   public static Map getEnumMap() {
+ *     return getEnumMap(ColorEnum.class);
+ *   }
+ * 
+ *   public static List getEnumList() {
+ *     return getEnumList(ColorEnum.class);
+ *   }
+ * 
+ *   public static Iterator iterator() {
+ *     return iterator(ColorEnum.class);
+ *   }
+ * }
+ * 
+ * + *

As shown, each enum has a name. This can be accessed using getName.

+ * + *

The getEnum and iterator methods are recommended. + * Unfortunately, Java restrictions require these to be coded as shown in each subclass. + * An alternative choice is to use the {@link EnumUtils} class.

+ * + *

Subclassed Enums

+ *

A hierarchy of Enum classes can be built. In this case, the superclass is + * unaffected by the addition of subclasses (as per normal Java). The subclasses + * may add additional Enum constants of the type of the superclass. The + * query methods on the subclass will return all of the Enum constants from the + * superclass and subclass.

+ * + *
+ * public final class ExtraColorEnum extends ColorEnum {
+ *   // NOTE: Color enum declared above is final, change that to get this
+ *   // example to compile.
+ *   public static final ColorEnum YELLOW = new ExtraColorEnum("Yellow");
+ *
+ *   private ExtraColorEnum(String color) {
+ *     super(color);
+ *   }
+ * 
+ *   public static ColorEnum getEnum(String color) {
+ *     return (ColorEnum) getEnum(ExtraColorEnum.class, color);
+ *   }
+ * 
+ *   public static Map getEnumMap() {
+ *     return getEnumMap(ExtraColorEnum.class);
+ *   }
+ * 
+ *   public static List getEnumList() {
+ *     return getEnumList(ExtraColorEnum.class);
+ *   }
+ * 
+ *   public static Iterator iterator() {
+ *     return iterator(ExtraColorEnum.class);
+ *   }
+ * }
+ * 
+ * + *

This example will return RED, GREEN, BLUE, YELLOW from the List and iterator + * methods in that order. The RED, GREEN and BLUE instances will be the same (==) + * as those from the superclass ColorEnum. Note that YELLOW is declared as a + * ColorEnum and not an ExtraColorEnum.

+ * + *

Functional Enums

+ * + *

The enums can have functionality by defining subclasses and + * overriding the getEnumClass() method:

+ * + *
+ *   public static final OperationEnum PLUS = new PlusOperation();
+ *   private static final class PlusOperation extends OperationEnum {
+ *     private PlusOperation() {
+ *       super("Plus");
+ *     }
+ *     public int eval(int a, int b) {
+ *       return (a + b);
+ *     }
+ *   }
+ *   public static final OperationEnum MINUS = new MinusOperation();
+ *   private static final class MinusOperation extends OperationEnum {
+ *     private MinusOperation() {
+ *       super("Minus");
+ *     }
+ *     public int eval(int a, int b) {
+ *       return (a - b);
+ *     }
+ *   }
+ *
+ *   private OperationEnum(String color) {
+ *     super(color);
+ *   }
+ * 
+ *   public final Class getEnumClass() {     // NOTE: new method!
+ *     return OperationEnum.class;
+ *   }
+ *
+ *   public abstract double eval(double a, double b);
+ * 
+ *   public static OperationEnum getEnum(String name) {
+ *     return (OperationEnum) getEnum(OperationEnum.class, name);
+ *   }
+ * 
+ *   public static Map getEnumMap() {
+ *     return getEnumMap(OperationEnum.class);
+ *   }
+ * 
+ *   public static List getEnumList() {
+ *     return getEnumList(OperationEnum.class);
+ *   }
+ * 
+ *   public static Iterator iterator() {
+ *     return iterator(OperationEnum.class);
+ *   }
+ * }
+ * 
+ *

The code above will work on JDK 1.2. If JDK1.3 and later is used, + * the subclasses may be defined as anonymous.

+ * + * @author Apache Avalon project + * @author Stephen Colebourne + * @author Chris Webb + * @author Mike Bowler + * @since 1.0 + * @version $Id: Enum.java,v 1.1 2012/08/30 16:24:43 marcin Exp $ + */ +public abstract class Enum implements Comparable, Serializable { + + /** Lang version 1.0.1 serial compatability */ + private static final long serialVersionUID = -487045951170455942L; + + // After discussion, the default size for HashMaps is used, as the + // sizing algorithm changes across the JDK versions + /** + * An empty Map, as JDK1.2 didn't have an empty map. + */ + private static final Map EMPTY_MAP = Collections.unmodifiableMap(new HashMap(0)); + + /** + * Map, key of class name, value of Entry. + */ + private static final Map cEnumClasses = new HashMap(); + + /** + * The string representation of the Enum. + */ + private final String iName; + + /** + * The hashcode representation of the Enum. + */ + private transient final int iHashCode; + + /** + * The toString representation of the Enum. + * @since 2.0 + */ + protected transient String iToString = null; + + /** + *

Enable the iterator to retain the source code order.

+ */ + private static class Entry { + /** + * Map of Enum name to Enum. + */ + final Map map = new HashMap(); + /** + * Map of Enum name to Enum. + */ + final Map unmodifiableMap = Collections.unmodifiableMap(map); + /** + * List of Enums in source code order. + */ + final List list = new ArrayList(25); + /** + * Map of Enum name to Enum. + */ + final List unmodifiableList = Collections.unmodifiableList(list); + + /** + *

Restrictive constructor.

+ */ + private Entry() { + } + } + + /** + *

Constructor to add a new named item to the enumeration.

+ * + * @param name the name of the enum object, + * must not be empty or null + * @throws IllegalArgumentException if the name is null + * or an empty string + * @throws IllegalArgumentException if the getEnumClass() method returns + * a null or invalid Class + */ + protected Enum(String name) { + super(); + init(name); + iName = name; + iHashCode = 7 + getEnumClass().hashCode() + 3 * name.hashCode(); + // cannot create toString here as subclasses may want to include other data + } + + /** + * Initializes the enumeration. + * + * @param name the enum name + * @throws IllegalArgumentException if the name is null or empty or duplicate + * @throws IllegalArgumentException if the enumClass is null or invalid + */ + private void init(String name) { + if (StringUtils.isEmpty(name)) { + throw new IllegalArgumentException("The Enum name must not be empty or null"); + } + + Class enumClass = getEnumClass(); + if (enumClass == null) { + throw new IllegalArgumentException("getEnumClass() must not be null"); + } + Class cls = getClass(); + boolean ok = false; + while (cls != null && cls != Enum.class && cls != ValuedEnum.class) { + if (cls == enumClass) { + ok = true; + break; + } + cls = cls.getSuperclass(); + } + if (ok == false) { + throw new IllegalArgumentException("getEnumClass() must return a superclass of this class"); + } + + // create entry + Entry entry = (Entry) cEnumClasses.get(enumClass); + if (entry == null) { + entry = createEntry(enumClass); + cEnumClasses.put(enumClass, entry); + } + if (entry.map.containsKey(name)) { + throw new IllegalArgumentException("The Enum name must be unique, '" + name + "' has already been added"); + } + entry.map.put(name, this); + entry.list.add(this); + } + + /** + *

Handle the deserialization of the class to ensure that multiple + * copies are not wastefully created, or illegal enum types created.

+ * + * @return the resolved object + */ + protected Object readResolve() { + Entry entry = (Entry) cEnumClasses.get(getEnumClass()); + if (entry == null) { + return null; + } + return (Enum) entry.map.get(getName()); + } + + //-------------------------------------------------------------------------------- + + /** + *

Gets an Enum object by class and name.

+ * + * @param enumClass the class of the Enum to get, must not + * be null + * @param name the name of the Enum to get, + * may be null + * @return the enum object, or null if the enum does not exist + * @throws IllegalArgumentException if the enum class + * is null + */ + protected static Enum getEnum(Class enumClass, String name) { + Entry entry = getEntry(enumClass); + if (entry == null) { + return null; + } + return (Enum) entry.map.get(name); + } + + /** + *

Gets the Map of Enum objects by + * name using the Enum class.

+ * + *

If the requested class has no enum objects an empty + * Map is returned.

+ * + * @param enumClass the class of the Enum to get, + * must not be null + * @return the enum object Map + * @throws IllegalArgumentException if the enum class is null + * @throws IllegalArgumentException if the enum class is not a subclass of Enum + */ + protected static Map getEnumMap(Class enumClass) { + Entry entry = getEntry(enumClass); + if (entry == null) { + return EMPTY_MAP; + } + return entry.unmodifiableMap; + } + + /** + *

Gets the List of Enum objects using the + * Enum class.

+ * + *

The list is in the order that the objects were created (source code order). + * If the requested class has no enum objects an empty List is + * returned.

+ * + * @param enumClass the class of the Enum to get, + * must not be null + * @return the enum object Map + * @throws IllegalArgumentException if the enum class is null + * @throws IllegalArgumentException if the enum class is not a subclass of Enum + */ + protected static List getEnumList(Class enumClass) { + Entry entry = getEntry(enumClass); + if (entry == null) { + return Collections.EMPTY_LIST; + } + return entry.unmodifiableList; + } + + /** + *

Gets an Iterator over the Enum objects in + * an Enum class.

+ * + *

The Iterator is in the order that the objects were + * created (source code order). If the requested class has no enum + * objects an empty Iterator is returned.

+ * + * @param enumClass the class of the Enum to get, + * must not be null + * @return an iterator of the Enum objects + * @throws IllegalArgumentException if the enum class is null + * @throws IllegalArgumentException if the enum class is not a subclass of Enum + */ + protected static Iterator iterator(Class enumClass) { + return Enum.getEnumList(enumClass).iterator(); + } + + //----------------------------------------------------------------------- + /** + *

Gets an Entry from the map of Enums.

+ * + * @param enumClass the class of the Enum to get + * @return the enum entry + */ + private static Entry getEntry(Class enumClass) { + if (enumClass == null) { + throw new IllegalArgumentException("The Enum Class must not be null"); + } + if (Enum.class.isAssignableFrom(enumClass) == false) { + throw new IllegalArgumentException("The Class must be a subclass of Enum"); + } + Entry entry = (Entry) cEnumClasses.get(enumClass); + return entry; + } + + /** + *

Creates an Entry for storing the Enums.

+ * + *

This accounts for subclassed Enums.

+ * + * @param enumClass the class of the Enum to get + * @return the enum entry + */ + private static Entry createEntry(Class enumClass) { + Entry entry = new Entry(); + Class cls = enumClass.getSuperclass(); + while (cls != null && cls != Enum.class && cls != ValuedEnum.class) { + Entry loopEntry = (Entry) cEnumClasses.get(cls); + if (loopEntry != null) { + entry.list.addAll(loopEntry.list); + entry.map.putAll(loopEntry.map); + break; // stop here, as this will already have had superclasses added + } + cls = cls.getSuperclass(); + } + return entry; + } + + //----------------------------------------------------------------------- + /** + *

Retrieve the name of this Enum item, set in the constructor.

+ * + * @return the String name of this Enum item + */ + public final String getName() { + return iName; + } + + /** + *

Retrieves the Class of this Enum item, set in the constructor.

+ * + *

This is normally the same as getClass(), but for + * advanced Enums may be different. If overridden, it must return a + * constant value.

+ * + * @return the Class of the enum + * @since 2.0 + */ + public Class getEnumClass() { + return getClass(); + } + + /** + *

Tests for equality.

+ * + *

Two Enum objects are considered equal + * if they have the same class names and the same names. + * Identity is tested for first, so this method usually runs fast.

+ * + * @param other the other object to compare for equality + * @return true if the Enums are equal + */ + public final boolean equals(Object other) { + if (other == this) { + return true; + } else if (other == null) { + return false; + } else if (other.getClass() == this.getClass()) { + // shouldn't happen, but... + return iName.equals(((Enum) other).iName); + } else if (((Enum) other).getEnumClass().getName().equals(getEnumClass().getName())) { + // different classloaders + try { + // try to avoid reflection + return iName.equals(((Enum) other).iName); + + } catch (ClassCastException ex) { + // use reflection + try { + Method mth = other.getClass().getMethod("getName", null); + String name = (String) mth.invoke(other, null); + return iName.equals(name); + } catch (NoSuchMethodException ex2) { + // ignore - should never happen + } catch (IllegalAccessException ex2) { + // ignore - should never happen + } catch (InvocationTargetException ex2) { + // ignore - should never happen + } + return false; + } + } else { + return false; + } + } + + /** + *

Returns a suitable hashCode for the enumeration.

+ * + * @return a hashcode based on the name + */ + public final int hashCode() { + return iHashCode; + } + + /** + *

Tests for order.

+ * + *

The default ordering is alphabetic by name, but this + * can be overridden by subclasses.

+ * + * @see java.lang.Comparable#compareTo(Object) + * @param other the other object to compare to + * @return -ve if this is less than the other object, +ve if greater + * than, 0 of equal + * @throws ClassCastException if other is not an Enum + * @throws NullPointerException if other is null + */ + public int compareTo(Object other) { + if (other == this) { + return 0; + } + return iName.compareTo(((Enum) other).iName); + } + + /** + *

Human readable description of this Enum item.

+ * + * @return String in the form type[name], for example: + * Color[Red]. Note that the package name is stripped from + * the type name. + */ + public String toString() { + if (iToString == null) { + String shortName = ClassUtils.getShortClassName(getEnumClass()); + iToString = shortName + "[" + getName() + "]"; + } + return iToString; + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/enum/EnumUtils.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/enum/EnumUtils.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/enum/EnumUtils.java 30 Aug 2012 16:24:44 -0000 1.1 @@ -0,0 +1,160 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.enum; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + *

Utility class for accessing and manipulating {@link Enum}s.

+ * + * @see Enum + * @see ValuedEnum + * @author Stephen Colebourne + * @author Gary Gregory + * @since 1.0 + * @version $Id: EnumUtils.java,v 1.1 2012/08/30 16:24:44 marcin Exp $ + */ +public class EnumUtils { + + /** + * Public constructor. This class should not normally be instantiated. + * @since 2.0 + */ + public EnumUtils() { + } + + /** + *

Gets an Enum object by class and name.

+ * + * @param enumClass the class of the Enum to get + * @param name the name of the Enum to get, may be null + * @return the enum object + * @throws IllegalArgumentException if the enum class is null + */ + public static Enum getEnum(Class enumClass, String name) { + return Enum.getEnum(enumClass, name); + } + + /** + *

Gets a ValuedEnum object by class and value.

+ * + * @param enumClass the class of the Enum to get + * @param value the value of the Enum to get + * @return the enum object, or null if the enum does not exist + * @throws IllegalArgumentException if the enum class is null + */ + public static ValuedEnum getEnum(Class enumClass, int value) { + return (ValuedEnum) ValuedEnum.getEnum(enumClass, value); + } + + /** + *

Gets the Map of Enum objects by + * name using the Enum class.

+ * + *

If the requested class has no enum objects an empty + * Map is returned. The Map is unmodifiable.

+ * + * @param enumClass the class of the Enum to get + * @return the enum object Map + * @throws IllegalArgumentException if the enum class is null + * @throws IllegalArgumentException if the enum class is not a subclass + * of Enum + */ + public static Map getEnumMap(Class enumClass) { + return Enum.getEnumMap(enumClass); + } + + /** + *

Gets the List of Enum objects using + * the Enum class.

+ * + *

The list is in the order that the objects were created + * (source code order).

+ * + *

If the requested class has no enum objects an empty + * List is returned. The List is unmodifiable.

+ * + * @param enumClass the class of the Enum to get + * @return the enum object Map + * @throws IllegalArgumentException if the enum class is null + * @throws IllegalArgumentException if the enum class is not a subclass + * of Enum + */ + public static List getEnumList(Class enumClass) { + return Enum.getEnumList(enumClass); + } + + /** + *

Gets an Iterator over the Enum objects + * in an Enum class.

+ * + *

The iterator is in the order that the objects were created + * (source code order).

+ * + *

If the requested class has no enum objects an empty + * Iterator is returned. The Iterator + * is unmodifiable.

+ * + * @param enumClass the class of the Enum to get + * @return an Iterator of the Enum objects + * @throws IllegalArgumentException if the enum class is null + * @throws IllegalArgumentException if the enum class is not a subclass of Enum + */ + public static Iterator iterator(Class enumClass) { + return Enum.getEnumList(enumClass).iterator(); + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/enum/ValuedEnum.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/enum/ValuedEnum.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/enum/ValuedEnum.java 30 Aug 2012 16:24:43 -0000 1.1 @@ -0,0 +1,225 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.enum; + +import java.util.Iterator; +import java.util.List; + +import org.apache.commons.lang.ClassUtils; + +/** + *

Abstract superclass for type-safe enums with integer values suitable + * for use in switch statements.

+ * + *

NOTE:Due to the way in which Java ClassLoaders work, comparing + * Enum objects should always be done using the equals() method, + * not ==. The equals() method will try == first so + * in most cases the effect is the same.

+ * + *

To use this class, it must be subclassed. For example:

+ * + *
+ * public final class JavaVersionEnum extends ValuedEnum {
+ *   //standard enums for version of JVM
+ *   public static final int  JAVA1_0_VALUE  = 100;
+ *   public static final int  JAVA1_1_VALUE  = 110;
+ *   public static final int  JAVA1_2_VALUE  = 120;
+ *   public static final int  JAVA1_3_VALUE  = 130;
+ *   public static final JavaVersionEnum  JAVA1_0  = new JavaVersionEnum( "Java 1.0", JAVA1_0_VALUE );
+ *   public static final JavaVersionEnum  JAVA1_1  = new JavaVersionEnum( "Java 1.1", JAVA1_1_VALUE );
+ *   public static final JavaVersionEnum  JAVA1_2  = new JavaVersionEnum( "Java 1.2", JAVA1_2_VALUE );
+ *   public static final JavaVersionEnum  JAVA1_3  = new JavaVersionEnum( "Java 1.3", JAVA1_3_VALUE );
+ *
+ *   private JavaVersionEnum(String name, int value) {
+ *     super( name, value );
+ *   }
+ * 
+ *   public static JavaVersionEnum getEnum(String javaVersion) {
+ *     return (JavaVersionEnum) getEnum(JavaVersionEnum.class, javaVersion);
+ *   }
+ * 
+ *   public static JavaVersionEnum getEnum(int javaVersion) {
+ *     return (JavaVersionEnum) getEnum(JavaVersionEnum.class, javaVersion);
+ *   }
+ * 
+ *   public static Map getEnumMap() {
+ *     return getEnumMap(JavaVersionEnum.class);
+ *   }
+ * 
+ *   public static List getEnumList() {
+ *     return getEnumList(JavaVersionEnum.class);
+ *   }
+ * 
+ *   public static Iterator iterator() {
+ *     return iterator(JavaVersionEnum.class);
+ *   }
+ * }
+ * 
+ * + *

The above class could then be used as follows:

+ * + *
+ * public void doSomething(JavaVersion ver) {
+ *   switch (ver.getValue()) {
+ *     case JAVA1_0_VALUE:
+ *       // ...
+ *       break;
+ *     case JAVA1_1_VALUE:
+ *       // ...
+ *       break;
+ *     //...
+ *   }
+ * }
+ * 
+ * + *

As shown, each enum has a name and a value. These can be accessed using + * getName and getValue.

+ * + *

The getEnum and iterator methods are recommended. + * Unfortunately, Java restrictions require these to be coded as shown in each subclass. + * An alternative choice is to use the {@link EnumUtils} class.

+ * + * @author Apache Avalon project + * @author Stephen Colebourne + * @since 1.0 + * @version $Id: ValuedEnum.java,v 1.1 2012/08/30 16:24:43 marcin Exp $ + */ +public abstract class ValuedEnum extends Enum { + + /** Lang version 1.0.1 serial compatability */ + private static final long serialVersionUID = -7129650521543789085L; + + /** + * The value contained in enum. + */ + private final int iValue; + + /** + * Constructor for enum item. + * + * @param name the name of enum item + * @param value the value of enum item + */ + protected ValuedEnum(String name, int value) { + super(name); + iValue = value; + } + + /** + *

Gets an Enum object by class and value.

+ * + *

This method loops through the list of Enum, + * thus if there are many Enums this will be + * slow.

+ * + * @param enumClass the class of the Enum to get + * @param value the value of the Enum to get + * @return the enum object, or null if the enum does not exist + * @throws IllegalArgumentException if the enum class is null + */ + protected static Enum getEnum(Class enumClass, int value) { + if (enumClass == null) { + throw new IllegalArgumentException("The Enum Class must not be null"); + } + List list = Enum.getEnumList(enumClass); + for (Iterator it = list.iterator(); it.hasNext();) { + ValuedEnum enum = (ValuedEnum) it.next(); + if (enum.getValue() == value) { + return enum; + } + } + return null; + } + + /** + *

Get value of enum item.

+ * + * @return the enum item's value. + */ + public final int getValue() { + return iValue; + } + + /** + *

Tests for order.

+ * + *

The default ordering is numeric by value, but this + * can be overridden by subclasses.

+ * + * @see java.lang.Comparable#compareTo(Object) + * @param other the other object to compare to + * @return -ve if this is less than the other object, +ve if greater than, + * 0 of equal + * @throws ClassCastException if other is not an Enum + * @throws NullPointerException if other is null + */ + public int compareTo(Object other) { + return iValue - ((ValuedEnum) other).iValue; + } + + /** + *

Human readable description of this Enum item.

+ * + * @return String in the form type[name=value], for example: + * JavaVersion[Java 1.0=100]. Note that the package name is + * stripped from the type name. + */ + public String toString() { + if (iToString == null) { + String shortName = ClassUtils.getShortClassName(getEnumClass()); + iToString = shortName + "[" + getName() + "=" + getValue() + "]"; + } + return iToString; + } +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/enum/package.html =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/enum/package.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/enum/package.html 30 Aug 2012 16:24:44 -0000 1.1 @@ -0,0 +1,35 @@ + + +Provides an implementation of the C style 'enum' in the Java world. + +The classic example being an RGB color enumeration. +
+public final class ColorEnum extends Enum {
+    public static final ColorEnum RED = new ColorEnum("Red");
+    public static final ColorEnum GREEN = new ColorEnum("Green");
+    public static final ColorEnum BLUE = new ColorEnum("Blue");
+
+    private ColorEnum(String color) {
+        super(color);
+    }
+
+    public static ColorEnum getEnum(String color) {
+        return (ColorEnum) getEnum(ColorEnum.class, color);
+    }
+
+    public static Map getEnumMap() {
+        return getEnumMap(ColorEnum.class);
+    }
+
+    public static List getEnumList() {
+        return getEnumList(ColorEnum.class);
+    }
+
+    public static Iterator iterator() {
+        return iterator(ColorEnum.class);
+    }
+}
+
+@since 1.0 + + Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/exception/ExceptionUtils.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/exception/ExceptionUtils.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/exception/ExceptionUtils.java 30 Aug 2012 16:24:44 -0000 1.1 @@ -0,0 +1,716 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.exception; + +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.StringTokenizer; + +import org.apache.commons.lang.ArrayUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.SystemUtils; + +/** + *

Provides utilities for manipulating and examining + * Throwable objects.

+ * + * @author Daniel Rall + * @author Dmitri Plotnikov + * @author Stephen Colebourne + * @author Gary Gregory + * @author Pete Gieser + * @since 1.0 + * @version $Id: ExceptionUtils.java,v 1.1 2012/08/30 16:24:44 marcin Exp $ + */ +public class ExceptionUtils { + + /** + *

Used when printing stack frames to denote the start of a + * wrapped exception.

+ * + *

Package private for accessibility by test suite.

+ */ + static final String WRAPPED_MARKER = " [wrapped] "; + + /** + *

The names of methods commonly used to access a wrapped exception.

+ */ + private static String[] CAUSE_METHOD_NAMES = { + "getCause", + "getNextException", + "getTargetException", + "getException", + "getSourceException", + "getRootCause", + "getCausedByException", + "getNested" + }; + + /** + *

The Method object for JDK1.4 getCause.

+ */ + private static final Method THROWABLE_CAUSE_METHOD; + static { + Method getCauseMethod; + try { + getCauseMethod = Throwable.class.getMethod("getCause", null); + } catch (Exception e) { + getCauseMethod = null; + } + THROWABLE_CAUSE_METHOD = getCauseMethod; + } + + /** + *

Public constructor allows an instance of ExceptionUtils + * to be created, although that is not normally necessary.

+ */ + public ExceptionUtils() { + } + + //----------------------------------------------------------------------- + /** + *

Adds to the list of method names used in the search for Throwable + * objects.

+ * + * @param methodName the methodName to add to the list, null + * and empty strings are ignored + * @since 2.0 + */ + public static void addCauseMethodName(String methodName) { + if (StringUtils.isNotEmpty(methodName)) { + List list = new ArrayList(Arrays.asList(CAUSE_METHOD_NAMES)); + list.add(methodName); + CAUSE_METHOD_NAMES = (String[]) list.toArray(new String[list.size()]); + } + } + + /** + *

Introspects the Throwable to obtain the cause.

+ * + *

The method searches for methods with specific names that return a + * Throwable object. This will pick up most wrapping exceptions, + * including those from JDK 1.4, and + * {@link org.apache.commons.lang.exception.NestableException NestableException}. + * The method names can be added to using {@link #addCauseMethodName(String)}.

+ * + *

The default list searched for are:

+ *
    + *
  • getCause()
  • + *
  • getNextException()
  • + *
  • getTargetException()
  • + *
  • getException()
  • + *
  • getSourceException()
  • + *
  • getRootCause()
  • + *
  • getCausedByException()
  • + *
  • getNested()
  • + *
+ * + *

In the absence of any such method, the object is inspected for a + * detail field assignable to a Throwable.

+ * + *

If none of the above is found, returns null.

+ * + * @param throwable the throwable to introspect for a cause, may be null + * @return the cause of the Throwable, + * null if none found or null throwable input + */ + public static Throwable getCause(Throwable throwable) { + return getCause(throwable, CAUSE_METHOD_NAMES); + } + + /** + *

Introspects the Throwable to obtain the cause.

+ * + *
    + *
  1. Try known exception types.
  2. + *
  3. Try the supplied array of method names.
  4. + *
  5. Try the field 'detail'.
  6. + *
+ * + *

A null set of method names means use the default set. + * A null in the set of method names will be ignored.

+ * + * @param throwable the throwable to introspect for a cause, may be null + * @param methodNames the method names, null treated as default set + * @return the cause of the Throwable, + * null if none found or null throwable input + */ + public static Throwable getCause(Throwable throwable, String[] methodNames) { + if (throwable == null) { + return null; + } + Throwable cause = getCauseUsingWellKnownTypes(throwable); + if (cause == null) { + if (methodNames == null) { + methodNames = CAUSE_METHOD_NAMES; + } + for (int i = 0; i < methodNames.length; i++) { + String methodName = methodNames[i]; + if (methodName != null) { + cause = getCauseUsingMethodName(throwable, methodName); + if (cause != null) { + break; + } + } + } + + if (cause == null) { + cause = getCauseUsingFieldName(throwable, "detail"); + } + } + return cause; + } + + /** + *

Introspects the Throwable to obtain the root cause.

+ * + *

This method walks through the exception chain to the last element, + * "root" of the tree, using {@link #getCause(Throwable)}, and + * returns that exception.

+ * + * @param throwable the throwable to get the root cause for, may be null + * @return the root cause of the Throwable, + * null if none found or null throwable input + */ + public static Throwable getRootCause(Throwable throwable) { + Throwable cause = getCause(throwable); + if (cause != null) { + throwable = cause; + while ((throwable = getCause(throwable)) != null) { + cause = throwable; + } + } + return cause; + } + + /** + *

Finds a Throwable for known types.

+ * + *

Uses instanceof checks to examine the exception, + * looking for well known types which could contain chained or + * wrapped exceptions.

+ * + * @param throwable the exception to examine + * @return the wrapped exception, or null if not found + */ + private static Throwable getCauseUsingWellKnownTypes(Throwable throwable) { + if (throwable instanceof Nestable) { + return ((Nestable) throwable).getCause(); + } else if (throwable instanceof SQLException) { + return ((SQLException) throwable).getNextException(); + } else if (throwable instanceof InvocationTargetException) { + return ((InvocationTargetException) throwable).getTargetException(); + } else { + return null; + } + } + + /** + *

Finds a Throwable by method name.

+ * + * @param throwable the exception to examine + * @param methodName the name of the method to find and invoke + * @return the wrapped exception, or null if not found + */ + private static Throwable getCauseUsingMethodName(Throwable throwable, String methodName) { + Method method = null; + try { + method = throwable.getClass().getMethod(methodName, null); + } catch (NoSuchMethodException ignored) { + } catch (SecurityException ignored) { + } + + if (method != null && Throwable.class.isAssignableFrom(method.getReturnType())) { + try { + return (Throwable) method.invoke(throwable, ArrayUtils.EMPTY_OBJECT_ARRAY); + } catch (IllegalAccessException ignored) { + } catch (IllegalArgumentException ignored) { + } catch (InvocationTargetException ignored) { + } + } + return null; + } + + /** + *

Finds a Throwable by field name.

+ * + * @param throwable the exception to examine + * @param fieldName the name of the attribute to examine + * @return the wrapped exception, or null if not found + */ + private static Throwable getCauseUsingFieldName(Throwable throwable, String fieldName) { + Field field = null; + try { + field = throwable.getClass().getField(fieldName); + } catch (NoSuchFieldException ignored) { + } catch (SecurityException ignored) { + } + + if (field != null && Throwable.class.isAssignableFrom(field.getType())) { + try { + return (Throwable) field.get(throwable); + } catch (IllegalAccessException ignored) { + } catch (IllegalArgumentException ignored) { + } + } + return null; + } + + //----------------------------------------------------------------------- + /** + *

Checks if the Throwable class has a getCause method.

+ * + *

This is true for JDK 1.4 and above.

+ * + * @return true if Throwable is nestable + * @since 2.0 + */ + public static boolean isThrowableNested() { + return (THROWABLE_CAUSE_METHOD != null); + } + + /** + *

Checks whether this Throwable class can store a cause.

+ * + *

This method does not check whether it actually does store a cause.

+ * + * @param throwable the Throwable to examine, may be null + * @return boolean true if nested otherwise false + * @since 2.0 + */ + public static boolean isNestedThrowable(Throwable throwable) { + if (throwable == null) { + return false; + } + + if (throwable instanceof Nestable) { + return true; + } else if (throwable instanceof SQLException) { + return true; + } else if (throwable instanceof InvocationTargetException) { + return true; + } else if (isThrowableNested()) { + return true; + } + + Class cls = throwable.getClass(); + for (int i = 0, isize = CAUSE_METHOD_NAMES.length; i < isize; i++) { + try { + Method method = cls.getMethod(CAUSE_METHOD_NAMES[i], null); + if (method != null && Throwable.class.isAssignableFrom(method.getReturnType())) { + return true; + } + } catch (NoSuchMethodException ignored) { + } catch (SecurityException ignored) { + } + } + + try { + Field field = cls.getField("detail"); + if (field != null) { + return true; + } + } catch (NoSuchFieldException ignored) { + } catch (SecurityException ignored) { + } + + return false; + } + + //----------------------------------------------------------------------- + /** + *

Counts the number of Throwable objects in the + * exception chain.

+ * + *

A throwable without cause will return 1. + * A throwable with one cause will return 2 and so on. + * A null throwable will return 0.

+ * + * @param throwable the throwable to inspect, may be null + * @return the count of throwables, zero if null input + */ + public static int getThrowableCount(Throwable throwable) { + int count = 0; + while (throwable != null) { + count++; + throwable = ExceptionUtils.getCause(throwable); + } + return count; + } + + /** + *

Returns the list of Throwable objects in the + * exception chain.

+ * + *

A throwable without cause will return an array containing + * one element - the input throwable. + * A throwable with one cause will return an array containing + * two elements. - the input throwable and the cause throwable. + * A null throwable will return an array size zero.

+ * + * @param throwable the throwable to inspect, may be null + * @return the array of throwables, never null + */ + public static Throwable[] getThrowables(Throwable throwable) { + List list = new ArrayList(); + while (throwable != null) { + list.add(throwable); + throwable = ExceptionUtils.getCause(throwable); + } + return (Throwable[]) list.toArray(new Throwable[list.size()]); + } + + //----------------------------------------------------------------------- + /** + *

Returns the (zero based) index of the first Throwable + * that matches the specified type in the exception chain.

+ * + *

A null throwable returns -1. + * A null type returns -1. + * No match in the chain returns -1.

+ * + * @param throwable the throwable to inspect, may be null + * @param type the type to search for + * @return the index into the throwable chain, -1 if no match or null input + */ + public static int indexOfThrowable(Throwable throwable, Class type) { + return indexOfThrowable(throwable, type, 0); + } + + /** + *

Returns the (zero based) index of the first Throwable + * that matches the specified type in the exception chain from + * a specified index.

+ * + *

A null throwable returns -1. + * A null type returns -1. + * No match in the chain returns -1. + * A negative start index is treated as zero. + * A start index greater than the number of throwables returns -1.

+ * + * @param throwable the throwable to inspect, may be null + * @param type the type to search for + * @param fromIndex the (zero based) index of the starting position, + * negative treated as zero, larger than chain size returns -1 + * @return the index into the throwable chain, -1 if no match or null input + */ + public static int indexOfThrowable(Throwable throwable, Class type, int fromIndex) { + if (throwable == null) { + return -1; + } + if (fromIndex < 0) { + fromIndex = 0; + } + Throwable[] throwables = ExceptionUtils.getThrowables(throwable); + if (fromIndex >= throwables.length) { + return -1; + } + for (int i = fromIndex; i < throwables.length; i++) { + if (throwables[i].getClass().equals(type)) { + return i; + } + } + return -1; + } + + //----------------------------------------------------------------------- + /** + *

Prints a compact stack trace for the root cause of a throwable + * to System.err.

+ * + *

The compact stack trace starts with the root cause and prints + * stack frames up to the place where it was caught and wrapped. + * Then it prints the wrapped exception and continues with stack frames + * until the wrapper exception is caught and wrapped again, etc.

+ * + *

The method is equivalent to printStackTrace for throwables + * that don't have nested causes.

+ * + * @param throwable the throwable to output + * @since 2.0 + */ + public static void printRootCauseStackTrace(Throwable throwable) { + printRootCauseStackTrace(throwable, System.err); + } + + /** + *

Prints a compact stack trace for the root cause of a throwable.

+ * + *

The compact stack trace starts with the root cause and prints + * stack frames up to the place where it was caught and wrapped. + * Then it prints the wrapped exception and continues with stack frames + * until the wrapper exception is caught and wrapped again, etc.

+ * + *

The method is equivalent to printStackTrace for throwables + * that don't have nested causes.

+ * + * @param throwable the throwable to output, may be null + * @param stream the stream to output to, may not be null + * @throws IllegalArgumentException if the stream is null + * @since 2.0 + */ + public static void printRootCauseStackTrace(Throwable throwable, PrintStream stream) { + if (throwable == null) { + return; + } + if (stream == null) { + throw new IllegalArgumentException("The PrintStream must not be null"); + } + String trace[] = getRootCauseStackTrace(throwable); + for (int i = 0; i < trace.length; i++) { + stream.println(trace[i]); + } + stream.flush(); + } + + /** + *

Prints a compact stack trace for the root cause of a throwable.

+ * + *

The compact stack trace starts with the root cause and prints + * stack frames up to the place where it was caught and wrapped. + * Then it prints the wrapped exception and continues with stack frames + * until the wrapper exception is caught and wrapped again, etc.

+ * + *

The method is equivalent to printStackTrace for throwables + * that don't have nested causes.

+ * + * @param throwable the throwable to output, may be null + * @param writer the writer to output to, may not be null + * @throws IllegalArgumentException if the writer is null + * @since 2.0 + */ + public static void printRootCauseStackTrace(Throwable throwable, PrintWriter writer) { + if (throwable == null) { + return; + } + if (writer == null) { + throw new IllegalArgumentException("The PrintWriter must not be null"); + } + String trace[] = getRootCauseStackTrace(throwable); + for (int i = 0; i < trace.length; i++) { + writer.println(trace[i]); + } + writer.flush(); + } + + //----------------------------------------------------------------------- + /** + *

Creates a compact stack trace for the root cause of the supplied + * Throwable.

+ * + * @param throwable the throwable to examine, may be null + * @return an array of stack trace frames, never null + * @since 2.0 + */ + public static String[] getRootCauseStackTrace(Throwable throwable) { + if (throwable == null) { + return ArrayUtils.EMPTY_STRING_ARRAY; + } + Throwable throwables[] = getThrowables(throwable); + int count = throwables.length; + ArrayList frames = new ArrayList(); + List nextTrace = getStackFrameList(throwables[count - 1]); + for (int i = count; --i >= 0;) { + List trace = nextTrace; + if (i != 0) { + nextTrace = getStackFrameList(throwables[i - 1]); + removeCommonFrames(trace, nextTrace); + } + if (i == count - 1) { + frames.add(throwables[i].toString()); + } else { + frames.add(WRAPPED_MARKER + throwables[i].toString()); + } + for (int j = 0; j < trace.size(); j++) { + frames.add(trace.get(j)); + } + } + return (String[]) frames.toArray(new String[0]); + } + + /** + *

Removes common frames from the cause trace given the two stack traces.

+ * + * @param causeFrames stack trace of a cause throwable + * @param wrapperFrames stack trace of a wrapper throwable + * @throws IllegalArgumentException if either argument is null + * @since 2.0 + */ + public static void removeCommonFrames(List causeFrames, List wrapperFrames) { + if (causeFrames == null || wrapperFrames == null) { + throw new IllegalArgumentException("The List must not be null"); + } + int causeFrameIndex = causeFrames.size() - 1; + int wrapperFrameIndex = wrapperFrames.size() - 1; + while (causeFrameIndex >= 0 && wrapperFrameIndex >= 0) { + // Remove the frame from the cause trace if it is the same + // as in the wrapper trace + String causeFrame = (String) causeFrames.get(causeFrameIndex); + String wrapperFrame = (String) wrapperFrames.get(wrapperFrameIndex); + if (causeFrame.equals(wrapperFrame)) { + causeFrames.remove(causeFrameIndex); + } + causeFrameIndex--; + wrapperFrameIndex--; + } + } + + //----------------------------------------------------------------------- + /** + *

Gets the stack trace from a Throwable as a String.

+ * + * @param throwable the Throwable to be examined + * @return the stack trace as generated by the exception's + * printStackTrace(PrintWriter) method + */ + public static String getStackTrace(Throwable throwable) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw, true); + throwable.printStackTrace(pw); + return sw.getBuffer().toString(); + } + + /** + *

A way to get the entire nested stack-trace of an throwable.

+ * + * @param throwable the Throwable to be examined + * @return the nested stack trace, with the root cause first + * @since 2.0 + */ + public static String getFullStackTrace(Throwable throwable) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw, true); + Throwable[] ts = getThrowables(throwable); + for (int i = 0; i < ts.length; i++) { + ts[i].printStackTrace(pw); + if (isNestedThrowable(ts[i])) { + break; + } + } + return sw.getBuffer().toString(); + } + + //----------------------------------------------------------------------- + /** + *

Captures the stack trace associated with the specified + * Throwable object, decomposing it into a list of + * stack frames.

+ * + * @param throwable the Throwable to exaamine, may be null + * @return an array of strings describing each stack frame, never null + */ + public static String[] getStackFrames(Throwable throwable) { + if (throwable == null) { + return ArrayUtils.EMPTY_STRING_ARRAY; + } + return getStackFrames(getStackTrace(throwable)); + } + + /** + *

Functionality shared between the + * getStackFrames(Throwable) methods of this and the + * {@link org.apache.commons.lang.exception.NestableDelegate} + * classes.

+ */ + static String[] getStackFrames(String stackTrace) { + String linebreak = SystemUtils.LINE_SEPARATOR; + StringTokenizer frames = new StringTokenizer(stackTrace, linebreak); + List list = new LinkedList(); + while (frames.hasMoreTokens()) { + list.add(frames.nextToken()); + } + return (String[]) list.toArray(new String[list.size()]); + } + + /** + *

Produces a List of stack frames - the message + * is not included.

+ * + *

This works in most cases - it will only fail if the exception + * message contains a line that starts with: + * "   at".

+ * + * @param t is any throwable + * @return List of stack frames + */ + static List getStackFrameList(Throwable t) { + String stackTrace = getStackTrace(t); + String linebreak = SystemUtils.LINE_SEPARATOR; + StringTokenizer frames = new StringTokenizer(stackTrace, linebreak); + List list = new LinkedList(); + boolean traceStarted = false; + while (frames.hasMoreTokens()) { + String token = frames.nextToken(); + // Determine if the line starts with at + int at = token.indexOf("at"); + if (at != -1 && token.substring(0, at).trim().length() == 0) { + traceStarted = true; + list.add(token); + } else if (traceStarted) { + break; + } + } + return list; + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/exception/Nestable.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/exception/Nestable.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/exception/Nestable.java 30 Aug 2012 16:24:44 -0000 1.1 @@ -0,0 +1,203 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.exception; + +import java.io.PrintStream; +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 Daniel Rall + * @author Kasper Nielsen + * @author Steven Caswell + * @author Pete Gieser + * @since 1.0 + * @version $Id: Nestable.java,v 1.1 2012/08/30 16:24:44 marcin Exp $ + */ +public interface Nestable { + + /** + * Returns the reference to the exception or error that caused the + * exception implementing the Nestable to be thrown. + * + * @return throwable that caused the original exception + */ + public Throwable getCause(); + + /** + * Returns the error message of this and any nested + * Throwable. + * + * @return the error message + */ + public String getMessage(); + + /** + * Returns the error message of the Throwable in the chain + * of Throwables at the specified index, numbererd from 0. + * + * @param index the index of the Throwable in the chain of + * Throwables + * @return the error message, or null if the Throwable at the + * specified index in the chain does not contain a message + * @throws IndexOutOfBoundsException if the index argument is + * negative or not less than the count of Throwables in the + * chain + */ + public String getMessage(int index); + + /** + * Returns the error message of this and any nested Throwables + * in an array of Strings, one element for each message. Any + * Throwable not containing a message is represented in the + * array by a null. This has the effect of cause the length of the returned + * array to be equal to the result of the {@link #getThrowableCount()} + * operation. + * + * @return the error messages + */ + public String[] getMessages(); + + /** + * Returns the Throwable in the chain of + * Throwables at the specified index, numbererd from 0. + * + * @param index the index, numbered from 0, of the Throwable in + * the chain of Throwables + * @return the Throwable + * @throws IndexOutOfBoundsException if the index argument is + * negative or not less than the count of Throwables in the + * chain + */ + public Throwable getThrowable(int index); + + /** + * Returns the number of nested Throwables represented by + * this Nestable, including this Nestable. + * + * @return the throwable count + */ + public int getThrowableCount(); + + /** + * Returns this Nestable and any nested Throwables + * in an array of Throwables, one element for each + * Throwable. + * + * @return the Throwables + */ + public Throwable[] getThrowables(); + + /** + * Returns the index, numbered from 0, of the first occurrence of the + * specified type in the chain of Throwables, or -1 if the + * specified type is not found in the chain. + * + * @param type Class to be found + * @return index of the first occurrence of the type in the chain, or -1 if + * the type is not found + */ + public int indexOfThrowable(Class type); + + /** + * Returns the index, numbered from 0, of the first Throwable + * that matches the specified type in the chain of Throwables + * with an index greater than or equal to the specified index, or -1 if + * the type is not found. + * + * @param type Class to be found + * @param fromIndex the index, numbered from 0, of the starting position in + * the chain to be searched + * @return index of the first occurrence of the type in the chain, or -1 if + * the type is not found + * @throws IndexOutOfBoundsException if the fromIndex argument + * is negative or not less than the count of Throwables in the + * chain + */ + public int indexOfThrowable(Class type, int fromIndex); + + /** + * Prints the stack trace of this exception to the specified print + * writer. Includes information from the exception, if any, + * which caused this exception. + * + * @param out PrintWriter to use for output. + */ + public void printStackTrace(PrintWriter out); + + /** + * Prints the stack trace of this exception to the specified print + * stream. Includes inforamation from the exception, if any, + * which caused this exception. + * + * @param out PrintStream to use for output. + */ + public void printStackTrace(PrintStream 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 + * super.printStackTrace(out); in most cases. + * + * @param out The writer to use. + */ + public void printPartialStackTrace(PrintWriter out); + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/exception/NestableDelegate.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/exception/NestableDelegate.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/exception/NestableDelegate.java 30 Aug 2012 16:24:44 -0000 1.1 @@ -0,0 +1,410 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.exception; + +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.Serializable; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +/** + *

A shared implementation of the nestable exception functionality.

+ *

+ * The code is shared between + * {@link org.apache.commons.lang.exception.NestableError NestableError}, + * {@link org.apache.commons.lang.exception.NestableException NestableException} and + * {@link org.apache.commons.lang.exception.NestableRuntimeException NestableRuntimeException}. + *

+ * + * @author Rafal Krzewski + * @author Daniel Rall + * @author Kasper Nielsen + * @author Steven Caswell + * @author Sean C. Sullivan + * @author Stephen Colebourne + * @since 1.0 + * @version $Id: NestableDelegate.java,v 1.1 2012/08/30 16:24:44 marcin Exp $ + */ +public class NestableDelegate implements Serializable { + + /** + * Constructor error message. + */ + private transient 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 we're + * wrapping (which must be a {@link + * org.apache.commons.lang.exception.Nestable} implementation). + */ + private Throwable nestable = null; + + /** + * Whether to print the stack trace top-down. + * This public flag may be set by calling code, typically in initialisation. + * @since 2.0 + */ + public static boolean topDown = true; + + /** + * Whether to trim the repeated stack trace. + * This public flag may be set by calling code, typically in initialisation. + * @since 2.0 + */ + public static boolean trimStackFrames = true; + + /** + * Constructs a new NestableDelegate instance to manage the + * specified Nestable. + * + * @param nestable the Nestable implementation (must extend + * {@link java.lang.Throwable}) + * @since 2.0 + */ + public NestableDelegate(Nestable nestable) { + if (nestable instanceof Throwable) { + this.nestable = (Throwable) nestable; + } else { + throw new IllegalArgumentException(MUST_BE_THROWABLE); + } + } + + /** + * Returns the error message of the Throwable in the chain + * of Throwables at the specified index, numbererd from 0. + * + * @param index the index of the Throwable in the chain of + * Throwables + * @return the error message, or null if the Throwable at the + * specified index in the chain does not contain a message + * @throws IndexOutOfBoundsException if the index argument is + * negative or not less than the count of Throwables in the + * chain + * @since 2.0 + */ + public String getMessage(int index) { + Throwable t = this.getThrowable(index); + if (Nestable.class.isInstance(t)) { + return ((Nestable) t).getMessage(0); + } else { + return t.getMessage(); + } + } + + /** + * Returns the full message contained by the Nestable + * and any nested Throwables. + * + * @param baseMsg the base message to use when creating the full + * message. Should be generally be called via + * nestableHelper.getMessage(super.getMessage()), + * where super is an instance of {@link + * java.lang.Throwable}. + * @return The concatenated message for this and all nested + * Throwables + * @since 2.0 + */ + public String getMessage(String baseMsg) { + StringBuffer msg = new StringBuffer(); + if (baseMsg != null) { + msg.append(baseMsg); + } + + Throwable nestedCause = ExceptionUtils.getCause(this.nestable); + 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); + } + + /** + * Returns the error message of this and any nested Throwables + * in an array of Strings, one element for each message. Any + * Throwable not containing a message is represented in the + * array by a null. This has the effect of cause the length of the returned + * array to be equal to the result of the {@link #getThrowableCount()} + * operation. + * + * @return the error messages + * @since 2.0 + */ + public String[] getMessages() { + Throwable[] throwables = this.getThrowables(); + String[] msgs = new String[throwables.length]; + for (int i = 0; i < throwables.length; i++) { + msgs[i] = + (Nestable.class.isInstance(throwables[i]) + ? ((Nestable) throwables[i]).getMessage(0) + : throwables[i].getMessage()); + } + return msgs; + } + + /** + * Returns the Throwable in the chain of + * Throwables at the specified index, numbererd from 0. + * + * @param index the index, numbered from 0, of the Throwable in + * the chain of Throwables + * @return the Throwable + * @throws IndexOutOfBoundsException if the index argument is + * negative or not less than the count of Throwables in the + * chain + * @since 2.0 + */ + public Throwable getThrowable(int index) { + if (index == 0) { + return this.nestable; + } + Throwable[] throwables = this.getThrowables(); + return throwables[index]; + } + + /** + * Returns the number of Throwables contained in the + * Nestable contained by this delegate. + * + * @return the throwable count + * @since 2.0 + */ + public int getThrowableCount() { + return ExceptionUtils.getThrowableCount(this.nestable); + } + + /** + * Returns this delegate's Nestable and any nested + * Throwables in an array of Throwables, one + * element for each Throwable. + * + * @return the Throwables + * @since 2.0 + */ + public Throwable[] getThrowables() { + return ExceptionUtils.getThrowables(this.nestable); + } + + /** + * Returns the index, numbered from 0, of the first Throwable + * that matches the specified type in the chain of Throwables + * held in this delegate's Nestable with an index greater than + * or equal to the specified index, or -1 if the type is not found. + * + * @param type Class to be found + * @param fromIndex the index, numbered from 0, of the starting position in + * the chain to be searched + * @return index of the first occurrence of the type in the chain, or -1 if + * the type is not found + * @throws IndexOutOfBoundsException if the fromIndex argument + * is negative or not less than the count of Throwables in the + * chain + * @since 2.0 + */ + public int indexOfThrowable(Class type, int fromIndex) { + if (fromIndex < 0) { + throw new IndexOutOfBoundsException("The start index was out of bounds: " + fromIndex); + } + Throwable[] throwables = ExceptionUtils.getThrowables(this.nestable); + if (fromIndex >= throwables.length) { + throw new IndexOutOfBoundsException("The start index was out of bounds: " + + fromIndex + " >= " + throwables.length); + } + for (int i = fromIndex; i < throwables.length; i++) { + if (throwables[i].getClass().equals(type)) { + return i; + } + } + return -1; + } + + /** + * Prints the stack trace of this exception the the standar error + * stream. + */ + public void printStackTrace() { + printStackTrace(System.err); + } + + /** + * Prints the stack trace of this exception to the specified + * stream. + * + * @param out PrintStream to use for output. + * @see #printStackTrace(PrintWriter) + */ + 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 + * writer. If the Throwable class has a getCause + * method (i.e. running on jre1.4 or higher), this method just + * uses Throwable's printStackTrace() method. Otherwise, generates + * the stack-trace, by taking into account the 'topDown' and + * 'trimStackFrames' parameters. The topDown and trimStackFrames + * are set to 'true' by default (produces jre1.4-like stack trace). + * + * @param out PrintWriter to use for output. + */ + public void printStackTrace(PrintWriter out) { + Throwable throwable = this.nestable; + // if running on jre1.4 or higher, use default printStackTrace + if (ExceptionUtils.isThrowableNested()) { + if (throwable instanceof Nestable) { + ((Nestable)throwable).printPartialStackTrace(out); + } else { + throwable.printStackTrace(out); + } + return; + } + + // generating the nested stack trace + List stacks = new ArrayList(); + while (throwable != null) { + String[] st = getStackFrames(throwable); + stacks.add(st); + throwable = ExceptionUtils.getCause(throwable); + } + + // If NOT topDown, reverse the stack + String separatorLine = "Caused by: "; + if (!topDown) { + separatorLine = "Rethrown as: "; + Collections.reverse(stacks); + } + + // Remove the repeated lines in the stack + if (trimStackFrames) trimStackFrames(stacks); + + synchronized (out) { + for (Iterator iter=stacks.iterator(); iter.hasNext();) { + String[] st = (String[]) iter.next(); + for (int i=0, len=st.length; i < len; i++) { + out.println(st[i]); + } + if (iter.hasNext()) + out.print(separatorLine); + } + } + } + + /** + * Captures the stack trace associated with the specified + * Throwable object, decomposing it into a list of + * stack frames. + * + * @param t The Throwable. + * @return An array of strings describing each stack frame. + * @since 2.0 + */ + protected String[] getStackFrames(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); + } + return ExceptionUtils.getStackFrames(sw.getBuffer().toString()); + } + + /** + * Trims the stack frames. The first set is left untouched. The rest + * of the frames are truncated from the bottom by comparing with + * one just on top. + * + * @param stacks The list containing String[] elements + * @since 2.0 + */ + protected void trimStackFrames(List stacks) { + for (int size=stacks.size(), i=size-1; i > 0; i--) { + String[] curr = (String[]) stacks.get(i); + String[] next = (String[]) stacks.get(i-1); + + List currList = new ArrayList(Arrays.asList(curr)); + List nextList = new ArrayList(Arrays.asList(next)); + ExceptionUtils.removeCommonFrames(currList, nextList); + + int trimmed = curr.length - currList.size(); + if (trimmed > 0) { + currList.add("\t... "+trimmed+" more"); + stacks.set( + i, + currList.toArray(new String[currList.size()]) + ); + } + } + } +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/exception/NestableError.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/exception/NestableError.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/exception/NestableError.java 30 Aug 2012 16:24:44 -0000 1.1 @@ -0,0 +1,190 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.exception; + +import java.io.PrintStream; +import java.io.PrintWriter; + +/** + * The base class of all errors which can contain other exceptions. + * + * @author Daniel Rall + * @see org.apache.commons.lang.exception.NestableException + * @since 1.0 + * @version $Id: NestableError.java,v 1.1 2012/08/30 16:24:44 marcin Exp $ + */ +public class NestableError extends Error 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 NestableError without specified + * detail message. + */ + public NestableError() { + super(); + } + + /** + * Constructs a new NestableError with specified + * detail message. + * + * @param msg The error message. + */ + public NestableError(String msg) { + super(msg); + } + + /** + * Constructs a new NestableError with specified + * nested Throwable. + * + * @param cause the exception or error that caused this exception to be + * thrown + */ + public NestableError(Throwable cause) { + super(); + this.cause = cause; + } + + /** + * Constructs a new NestableError with specified + * detail message and nested Throwable. + * + * @param msg the error message + * @param cause the exception or error that caused this exception to be + * thrown + */ + public NestableError(String msg, Throwable cause) { + super(msg); + this.cause = cause; + } + + public Throwable getCause() { + return cause; + } + + /** + * Returns the detail message string of this throwable. If it was + * created with a null message, returns the following: + * (cause==null ? null : cause.toString()). + */ + public String getMessage() { + if (super.getMessage() != null) { + return super.getMessage(); + } else if (cause != null) { + return cause.toString(); + } else { + return null; + } + } + + public String getMessage(int index) { + if (index == 0) { + return super.getMessage(); + } else { + return delegate.getMessage(index); + } + } + + public String[] getMessages() { + return delegate.getMessages(); + } + + public Throwable getThrowable(int index) { + return delegate.getThrowable(index); + } + + public int getThrowableCount() { + return delegate.getThrowableCount(); + } + + public Throwable[] getThrowables() { + return delegate.getThrowables(); + } + + public int indexOfThrowable(Class type) { + return delegate.indexOfThrowable(type, 0); + } + + public int indexOfThrowable(Class type, int fromIndex) { + return delegate.indexOfThrowable(type, fromIndex); + } + + public void printStackTrace() { + delegate.printStackTrace(); + } + + public void printStackTrace(PrintStream out) { + delegate.printStackTrace(out); + } + + public void printStackTrace(PrintWriter out) { + delegate.printStackTrace(out); + } + + public final void printPartialStackTrace(PrintWriter out) { + super.printStackTrace(out); + } +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/exception/NestableException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/exception/NestableException.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/exception/NestableException.java 30 Aug 2012 16:24:44 -0000 1.1 @@ -0,0 +1,251 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.exception; + +import java.io.PrintStream; +import java.io.PrintWriter; + +/** + * 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 NestedException, when the + * exception is finally printed out using any of the + * printStackTrace() methods, the stacktrace will contain + * the information about all exceptions thrown and caught on + * the way. + *

Running the following program + *

+ *  1 import org.apache.commons.lang.exception.NestableException;
+ *  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 NestableException("foo", e);
+ * 17          }
+ * 18      }
+ * 19
+ * 20      public static void b() throws Exception {
+ * 21          try {
+ * 22              c();
+ * 23          } catch(Exception e) {
+ * 24              throw new NestableException("bar", e);
+ * 25          }
+ * 26      }
+ * 27
+ * 28      public static void c() throws Exception {
+ * 29          throw new Exception("baz");
+ * 30      }
+ * 31 }
+ * 
+ *

Yields the following stacktrace: + *

+ * org.apache.commons.lang.exception.NestableException: foo
+ *         at Test.a(Test.java:16)
+ *         at Test.main(Test.java:6)
+ * Caused by: org.apache.commons.lang.exception.NestableException: bar
+ *         at Test.b(Test.java:24)
+ *         at Test.a(Test.java:14)
+ *         ... 1 more
+ * Caused by: java.lang.Exception: baz
+ *         at Test.c(Test.java:29)
+ *         at Test.b(Test.java:22)
+ *         ... 2 more
+ * 

+ * + * @author Rafal Krzewski + * @author Daniel Rall + * @author Kasper Nielsen + * @author Steven Caswell + * @since 1.0 + * @version $Id: NestableException.java,v 1.1 2012/08/30 16:24:44 marcin Exp $ + */ +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 NestableException without specified + * detail message. + */ + public NestableException() { + super(); + } + + /** + * Constructs a new NestableException with specified + * detail message. + * + * @param msg The error message. + */ + public NestableException(String msg) { + super(msg); + } + + /** + * Constructs a new NestableException with specified + * nested Throwable. + * + * @param cause the exception or error that caused this exception to be + * thrown + */ + public NestableException(Throwable cause) { + super(); + this.cause = cause; + } + + /** + * Constructs a new NestableException with specified + * detail message and nested Throwable. + * + * @param msg the error message + * @param cause the exception or error that caused this exception to be + * thrown + */ + public NestableException(String msg, Throwable cause) { + super(msg); + this.cause = cause; + } + + public Throwable getCause() { + return cause; + } + + /** + * Returns the detail message string of this throwable. If it was + * created with a null message, returns the following: + * (cause==null ? null : cause.toString()). + */ + public String getMessage() { + if (super.getMessage() != null) { + return super.getMessage(); + } else if (cause != null) { + return cause.toString(); + } else { + return null; + } + } + + public String getMessage(int index) { + if (index == 0) { + return super.getMessage(); + } else { + return delegate.getMessage(index); + } + } + + public String[] getMessages() { + return delegate.getMessages(); + } + + public Throwable getThrowable(int index) { + return delegate.getThrowable(index); + } + + public int getThrowableCount() { + return delegate.getThrowableCount(); + } + + public Throwable[] getThrowables() { + return delegate.getThrowables(); + } + + public int indexOfThrowable(Class type) { + return delegate.indexOfThrowable(type, 0); + } + + public int indexOfThrowable(Class type, int fromIndex) { + return delegate.indexOfThrowable(type, fromIndex); + } + + public void printStackTrace() { + delegate.printStackTrace(); + } + + public void printStackTrace(PrintStream out) { + delegate.printStackTrace(out); + } + + public void printStackTrace(PrintWriter out) { + delegate.printStackTrace(out); + } + + public final void printPartialStackTrace(PrintWriter out) { + super.printStackTrace(out); + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/exception/NestableRuntimeException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/exception/NestableRuntimeException.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/exception/NestableRuntimeException.java 30 Aug 2012 16:24:44 -0000 1.1 @@ -0,0 +1,195 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.exception; + +import java.io.PrintStream; +import java.io.PrintWriter; + +/** + * The base class of all runtime exceptions which can contain other + * exceptions. + * + * @see org.apache.commons.lang.exception.NestableException + * @author Rafal Krzewski + * @author Daniel Rall + * @author Kasper Nielsen + * @author Steven Caswell + * @since 1.0 + * @version $Id: NestableRuntimeException.java,v 1.1 2012/08/30 16:24:44 marcin Exp $ + */ +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 NestableRuntimeException without specified + * detail message. + */ + public NestableRuntimeException() { + super(); + } + + /** + * Constructs a new NestableRuntimeException with specified + * detail message. + * + * @param msg the error message + */ + public NestableRuntimeException(String msg) { + super(msg); + } + + /** + * Constructs a new NestableRuntimeException with specified + * nested Throwable. + * + * @param cause the exception or error that caused this exception to be + * thrown + */ + public NestableRuntimeException(Throwable cause) { + super(); + this.cause = cause; + } + + /** + * Constructs a new NestableRuntimeException with specified + * detail message and nested Throwable. + * + * @param msg the error message + * @param cause the exception or error that caused this exception to be + * thrown + */ + public NestableRuntimeException(String msg, Throwable cause) { + super(msg); + this.cause = cause; + } + + public Throwable getCause() { + return cause; + } + + /** + * Returns the detail message string of this throwable. If it was + * created with a null message, returns the following: + * (cause==null ? null : cause.toString()). + */ + public String getMessage() { + if (super.getMessage() != null) { + return super.getMessage(); + } else if (cause != null) { + return cause.toString(); + } else { + return null; + } + } + + public String getMessage(int index) { + if (index == 0) { + return super.getMessage(); + } else { + return delegate.getMessage(index); + } + } + + public String[] getMessages() { + return delegate.getMessages(); + } + + public Throwable getThrowable(int index) { + return delegate.getThrowable(index); + } + + public int getThrowableCount() { + return delegate.getThrowableCount(); + } + + public Throwable[] getThrowables() { + return delegate.getThrowables(); + } + + public int indexOfThrowable(Class type) { + return delegate.indexOfThrowable(type, 0); + } + + public int indexOfThrowable(Class type, int fromIndex) { + return delegate.indexOfThrowable(type, fromIndex); + } + + public void printStackTrace() { + delegate.printStackTrace(); + } + + public void printStackTrace(PrintStream out) { + delegate.printStackTrace(out); + } + + public void printStackTrace(PrintWriter out) { + delegate.printStackTrace(out); + } + + public final void printPartialStackTrace(PrintWriter out) { + super.printStackTrace(out); + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/exception/package.html =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/exception/package.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/exception/package.html 30 Aug 2012 16:24:44 -0000 1.1 @@ -0,0 +1,11 @@ + + +Provides JDK 1.4 style Nested Exception functionality for those on prior Java +versions. +

Includes a static utility to create version independent Nested +Exception which can handle JDK 1.4 Exceptions as well as others.

+

Lastly, {@link org.apache.commons.lang.exception.ExceptionUtils} +also contains Throwable manipulation and examination routines.

+@since 1.0 + + Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/math/DoubleRange.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/math/DoubleRange.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/math/DoubleRange.java 30 Aug 2012 16:24:43 -0000 1.1 @@ -0,0 +1,448 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.math; + +import java.io.Serializable; + +/** + *

DoubleRange represents an inclusive range of doubles.

+ * + * @author Stephen Colebourne + * @since 2.0 + * @version $Id: DoubleRange.java,v 1.1 2012/08/30 16:24:43 marcin Exp $ + */ +public final class DoubleRange extends Range implements Serializable { + + private static final long serialVersionUID = 71849363892740L; + + /** + * The minimum number in this range (inclusive). + */ + private final double min; + /** + * The maximum number in this range (inclusive). + */ + private final double max; + + /** + * Cached output minObject (class is immutable). + */ + private transient Double minObject = null; + /** + * Cached output maxObject (class is immutable). + */ + private transient Double maxObject = null; + /** + * Cached output hashCode (class is immutable). + */ + private transient int hashCode = 0; + /** + * Cached output toString (class is immutable). + */ + private transient String toString = null; + + /** + *

Constructs a new DoubleRange using the specified + * number as both the minimum and maximum in this range.

+ * + * @param number the number to use for this range + * @throws IllegalArgumentException if the number is NaN + */ + public DoubleRange(double number) { + super(); + if (Double.isNaN(number)) { + throw new IllegalArgumentException("The number must not be NaN"); + } + this.min = number; + this.max = number; + } + + /** + *

Constructs a new DoubleRange using the specified + * number as both the minimum and maximum in this range.

+ * + * @param number the number to use for this range, must not + * be null + * @throws IllegalArgumentException if the number is null + * @throws IllegalArgumentException if the number is NaN + */ + public DoubleRange(Number number) { + super(); + if (number == null) { + throw new IllegalArgumentException("The number must not be null"); + } + this.min = number.doubleValue(); + this.max = number.doubleValue(); + if (Double.isNaN(min) || Double.isNaN(max)) { + throw new IllegalArgumentException("The number must not be NaN"); + } + if (number instanceof Double) { + this.minObject = (Double) number; + this.maxObject = (Double) number; + } + } + + /** + *

Constructs a new DoubleRange with the specified + * minimum and maximum numbers (both inclusive).

+ * + *

The arguments may be passed in the order (min,max) or (max,min). The + * getMinimum and getMaximum methods will return the correct values.

+ * + * @param number1 first number that defines the edge of the range, inclusive + * @param number2 second number that defines the edge of the range, inclusive + * @throws IllegalArgumentException if either number is NaN + */ + public DoubleRange(double number1, double number2) { + super(); + if (Double.isNaN(number1) || Double.isNaN(number2)) { + throw new IllegalArgumentException("The numbers must not be NaN"); + } + if (number2 < number1) { + this.min = number2; + this.max = number1; + } else { + this.min = number1; + this.max = number2; + } + } + + /** + *

Constructs a new DoubleRange with the specified + * minimum and maximum numbers (both inclusive).

+ * + *

The arguments may be passed in the order (min,max) or (max,min). The + * getMinimum and getMaximum methods will return the correct values.

+ * + * @param number1 first number that defines the edge of the range, inclusive + * @param number2 second number that defines the edge of the range, inclusive + * @throws IllegalArgumentException if either number is null + * @throws IllegalArgumentException if either number is NaN + */ + public DoubleRange(Number number1, Number number2) { + super(); + if (number1 == null || number2 == null) { + throw new IllegalArgumentException("The numbers must not be null"); + } + double number1val = number1.doubleValue(); + double number2val = number2.doubleValue(); + if (Double.isNaN(number1val) || Double.isNaN(number2val)) { + throw new IllegalArgumentException("The numbers must not be NaN"); + } + if (number2val < number1val) { + this.min = number2val; + this.max = number1val; + if (number2 instanceof Double) { + this.minObject = (Double) number2; + } + if (number1 instanceof Double) { + this.maxObject = (Double) number1; + } + } else { + this.min = number1val; + this.max = number2val; + if (number1 instanceof Double) { + this.minObject = (Double) number1; + } + if (number2 instanceof Double) { + this.maxObject = (Double) number2; + } + } + } + + // Accessors + //-------------------------------------------------------------------- + + /** + *

Returns the minimum number in this range.

+ * + * @return the minimum number in this range + */ + public Number getMinimumNumber() { + if (minObject == null) { + minObject = new Double(min); + } + return minObject; + } + + /** + *

Gets the minimum number in this range as a long.

+ * + *

This conversion can lose information for large values or decimals.

+ * + * @return the minimum number in this range + */ + public long getMinimumLong() { + return (long) min; + } + + /** + *

Gets the minimum number in this range as a int.

+ * + *

This conversion can lose information for large values or decimals.

+ * + * @return the minimum number in this range + */ + public int getMinimumInteger() { + return (int) min; + } + + /** + *

Gets the minimum number in this range as a double.

+ * + * @return the minimum number in this range + */ + public double getMinimumDouble() { + return min; + } + + /** + *

Gets the minimum number in this range as a float.

+ * + *

This conversion can lose information for large values.

+ * + * @return the minimum number in this range + */ + public float getMinimumFloat() { + return (float) min; + } + + /** + *

Returns the maximum number in this range.

+ * + * @return the maximum number in this range + */ + public Number getMaximumNumber() { + if (maxObject == null) { + maxObject = new Double(max); + } + return maxObject; + } + + /** + *

Gets the maximum number in this range as a long.

+ * + *

This conversion can lose information for large values or decimals.

+ * + * @return the maximum number in this range + */ + public long getMaximumLong() { + return (long) max; + } + + /** + *

Gets the maximum number in this range as a int.

+ * + *

This conversion can lose information for large values or decimals.

+ * + * @return the maximum number in this range + */ + public int getMaximumInteger() { + return (int) max; + } + + /** + *

Gets the maximum number in this range as a double.

+ * + * @return the maximum number in this range + */ + public double getMaximumDouble() { + return max; + } + + /** + *

Gets the maximum number in this range as a float.

+ * + *

This conversion can lose information for large values.

+ * + * @return the maximum number in this range + */ + public float getMaximumFloat() { + return (float) max; + } + + // Tests + //-------------------------------------------------------------------- + + /** + *

Tests whether the specified number occurs within + * this range using double comparison.

+ * + *

null is handled and returns false.

+ * + * @param number the number to test, may be null + * @return true if the specified number occurs within this range + */ + public boolean containsNumber(Number number) { + if (number == null) { + return false; + } + return containsDouble(number.doubleValue()); + } + + /** + *

Tests whether the specified double occurs within + * this range using double comparison.

+ * + *

This implementation overrides the superclass for performance as it is + * the most common case.

+ * + * @param value the double to test + * @return true if the specified number occurs within this + * range by double comparison + */ + public boolean containsDouble(double value) { + return (value >= min && value <= max); + } + + // Range tests + //-------------------------------------------------------------------- + + /** + *

Tests whether the specified range occurs entirely within this range + * using double comparison.

+ * + *

null is handled and returns false.

+ * + * @param range the range to test, may be null + * @return true if the specified range occurs entirely within this range + * @throws IllegalArgumentException if the range is not of this type + */ + public boolean containsRange(Range range) { + if (range == null) { + return false; + } + return containsDouble(range.getMinimumDouble()) + && containsDouble(range.getMaximumDouble()); + } + + /** + *

Tests whether the specified range overlaps with this range + * using double comparison.

+ * + *

null is handled and returns false.

+ * + * @param range the range to test, may be null + * @return true if the specified range overlaps with this range + */ + public boolean overlapsRange(Range range) { + if (range == null) { + return false; + } + return range.containsDouble(min) + || range.containsDouble(max) + || containsDouble(range.getMinimumDouble()); + } + + // Basics + //-------------------------------------------------------------------- + + /** + *

Compares this range to another object to test if they are equal.

. + * + *

To be equal, the class, minimum and maximum must be equal.

+ * + * @param obj the reference object with which to compare + * @return true if this object is equal + */ + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof DoubleRange == false) { + return false; + } + DoubleRange range = (DoubleRange) obj; + return (Double.doubleToLongBits(min) == Double.doubleToLongBits(range.min) && + Double.doubleToLongBits(max) == Double.doubleToLongBits(range.max)); + } + + /** + *

Gets a hashCode for the range.

+ * + * @return a hash code value for this object + */ + public int hashCode() { + if (hashCode == 0) { + hashCode = 17; + hashCode = 37 * hashCode + getClass().hashCode(); + long lng = Double.doubleToLongBits(min); + hashCode = 37 * hashCode + ((int) (lng ^ (lng >> 32))); + lng = Double.doubleToLongBits(max); + hashCode = 37 * hashCode + ((int) (lng ^ (lng >> 32))); + } + return hashCode; + } + + /** + *

Gets the range as a String.

+ * + *

The format of the String is 'Range[min,max]'.

+ * + * @return the String representation of this range + */ + public String toString() { + if (toString == null) { + StringBuffer buf = new StringBuffer(32); + buf.append("Range["); + buf.append(min); + buf.append(','); + buf.append(max); + buf.append(']'); + toString = buf.toString(); + } + return toString; + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/math/FloatRange.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/math/FloatRange.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/math/FloatRange.java 30 Aug 2012 16:24:43 -0000 1.1 @@ -0,0 +1,442 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.math; + +import java.io.Serializable; + +/** + *

FloatRange represents an inclusive range of floats.

+ * + * @author Stephen Colebourne + * @since 2.0 + * @version $Id: FloatRange.java,v 1.1 2012/08/30 16:24:43 marcin Exp $ + */ +public final class FloatRange extends Range implements Serializable { + + private static final long serialVersionUID = 71849363892750L; + + /** + * The minimum number in this range (inclusive). + */ + private final float min; + /** + * The maximum number in this range (inclusive). + */ + private final float max; + + /** + * Cached output minObject (class is immutable). + */ + private transient Float minObject = null; + /** + * Cached output maxObject (class is immutable). + */ + private transient Float maxObject = null; + /** + * Cached output hashCode (class is immutable). + */ + private transient int hashCode = 0; + /** + * Cached output toString (class is immutable). + */ + private transient String toString = null; + + /** + *

Constructs a new FloatRange using the specified + * number as both the minimum and maximum in this range.

+ * + * @param number the number to use for this range + * @throws IllegalArgumentException if the number is NaN + */ + public FloatRange(float number) { + super(); + if (Float.isNaN(number)) { + throw new IllegalArgumentException("The number must not be NaN"); + } + this.min = number; + this.max = number; + } + + /** + *

Constructs a new FloatRange using the specified + * number as both the minimum and maximum in this range.

+ * + * @param number the number to use for this range, must not + * be null + * @throws IllegalArgumentException if the number is null + * @throws IllegalArgumentException if the number is NaN + */ + public FloatRange(Number number) { + super(); + if (number == null) { + throw new IllegalArgumentException("The number must not be null"); + } + this.min = number.floatValue(); + this.max = number.floatValue(); + if (Float.isNaN(min) || Float.isNaN(max)) { + throw new IllegalArgumentException("The number must not be NaN"); + } + if (number instanceof Float) { + this.minObject = (Float) number; + this.maxObject = (Float) number; + } + } + + /** + *

Constructs a new FloatRange with the specified + * minimum and maximum numbers (both inclusive).

+ * + *

The arguments may be passed in the order (min,max) or (max,min). The + * getMinimum and getMaximum methods will return the correct values.

+ * + * @param number1 first number that defines the edge of the range, inclusive + * @param number2 second number that defines the edge of the range, inclusive + * @throws IllegalArgumentException if either number is NaN + */ + public FloatRange(float number1, float number2) { + super(); + if (Float.isNaN(number1) || Float.isNaN(number2)) { + throw new IllegalArgumentException("The numbers must not be NaN"); + } + if (number2 < number1) { + this.min = number2; + this.max = number1; + } else { + this.min = number1; + this.max = number2; + } + } + + /** + *

Constructs a new FloatRange with the specified + * minimum and maximum numbers (both inclusive).

+ * + *

The arguments may be passed in the order (min,max) or (max,min). The + * getMinimum and getMaximum methods will return the correct values.

+ * + * @param number1 first number that defines the edge of the range, inclusive + * @param number2 second number that defines the edge of the range, inclusive + * @throws IllegalArgumentException if either number is null + * @throws IllegalArgumentException if either number is NaN + */ + public FloatRange(Number number1, Number number2) { + super(); + if (number1 == null || number2 == null) { + throw new IllegalArgumentException("The numbers must not be null"); + } + float number1val = number1.floatValue(); + float number2val = number2.floatValue(); + if (Float.isNaN(number1val) || Float.isNaN(number2val)) { + throw new IllegalArgumentException("The numbers must not be NaN"); + } + if (number2val < number1val) { + this.min = number2val; + this.max = number1val; + if (number2 instanceof Float) { + this.minObject = (Float) number2; + } + if (number1 instanceof Float) { + this.maxObject = (Float) number1; + } + } else { + this.min = number1val; + this.max = number2val; + if (number1 instanceof Float) { + this.minObject = (Float) number1; + } + if (number2 instanceof Float) { + this.maxObject = (Float) number2; + } + } + } + + // Accessors + //-------------------------------------------------------------------- + + /** + *

Returns the minimum number in this range.

+ * + * @return the minimum number in this range + */ + public Number getMinimumNumber() { + if (minObject == null) { + minObject = new Float(min); + } + return minObject; + } + + /** + *

Gets the minimum number in this range as a long.

+ * + *

This conversion can lose information for large values or decimals.

+ * + * @return the minimum number in this range + */ + public long getMinimumLong() { + return (long) min; + } + + /** + *

Gets the minimum number in this range as a int.

+ * + *

This conversion can lose information for large values or decimals.

+ * + * @return the minimum number in this range + */ + public int getMinimumInteger() { + return (int) min; + } + + /** + *

Gets the minimum number in this range as a double.

+ * + * @return the minimum number in this range + */ + public double getMinimumDouble() { + return min; + } + + /** + *

Gets the minimum number in this range as a float.

+ * + * @return the minimum number in this range + */ + public float getMinimumFloat() { + return min; + } + + /** + *

Returns the maximum number in this range.

+ * + * @return the maximum number in this range + */ + public Number getMaximumNumber() { + if (maxObject == null) { + maxObject = new Float(max); + } + return maxObject; + } + + /** + *

Gets the maximum number in this range as a long.

+ * + *

This conversion can lose information for large values or decimals.

+ * + * @return the maximum number in this range + */ + public long getMaximumLong() { + return (long) max; + } + + /** + *

Gets the maximum number in this range as a int.

+ * + *

This conversion can lose information for large values or decimals.

+ * + * @return the maximum number in this range + */ + public int getMaximumInteger() { + return (int) max; + } + + /** + *

Gets the maximum number in this range as a double.

+ * + * @return the maximum number in this range + */ + public double getMaximumDouble() { + return max; + } + + /** + *

Gets the maximum number in this range as a float.

+ * + * @return the maximum number in this range + */ + public float getMaximumFloat() { + return max; + } + + // Tests + //-------------------------------------------------------------------- + + /** + *

Tests whether the specified number occurs within + * this range using float comparison.

+ * + *

null is handled and returns false.

+ * + * @param number the number to test, may be null + * @return true if the specified number occurs within this range + */ + public boolean containsNumber(Number number) { + if (number == null) { + return false; + } + return containsFloat(number.floatValue()); + } + + /** + *

Tests whether the specified float occurs within + * this range using float comparison.

+ * + *

This implementation overrides the superclass for performance as it is + * the most common case.

+ * + * @param value the float to test + * @return true if the specified number occurs within this + * range by float comparison + */ + public boolean containsFloat(float value) { + return (value >= min && value <= max); + } + + // Range tests + //-------------------------------------------------------------------- + + /** + *

Tests whether the specified range occurs entirely within this range + * using float comparison.

+ * + *

null is handled and returns false.

+ * + * @param range the range to test, may be null + * @return true if the specified range occurs entirely within this range + * @throws IllegalArgumentException if the range is not of this type + */ + public boolean containsRange(Range range) { + if (range == null) { + return false; + } + return containsFloat(range.getMinimumFloat()) && + containsFloat(range.getMaximumFloat()); + } + + /** + *

Tests whether the specified range overlaps with this range + * using float comparison.

+ * + *

null is handled and returns false.

+ * + * @param range the range to test, may be null + * @return true if the specified range overlaps with this range + */ + public boolean overlapsRange(Range range) { + if (range == null) { + return false; + } + return range.containsFloat(min) || + range.containsFloat(max) || + containsFloat(range.getMinimumFloat()); + } + + // Basics + //-------------------------------------------------------------------- + + /** + *

Compares this range to another object to test if they are equal.

. + * + *

To be equal, the class, minimum and maximum must be equal.

+ * + * @param obj the reference object with which to compare + * @return true if this object is equal + */ + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof FloatRange == false) { + return false; + } + FloatRange range = (FloatRange) obj; + return (Float.floatToIntBits(min) == Float.floatToIntBits(range.min) && + Float.floatToIntBits(max) == Float.floatToIntBits(range.max)); + } + + /** + *

Gets a hashCode for the range.

+ * + * @return a hash code value for this object + */ + public int hashCode() { + if (hashCode == 0) { + hashCode = 17; + hashCode = 37 * hashCode + getClass().hashCode(); + hashCode = 37 * hashCode + Float.floatToIntBits(min); + hashCode = 37 * hashCode + Float.floatToIntBits(max); + } + return hashCode; + } + + /** + *

Gets the range as a String.

+ * + *

The format of the String is 'Range[min,max]'.

+ * + * @return the String representation of this range + */ + public String toString() { + if (toString == null) { + StringBuffer buf = new StringBuffer(32); + buf.append("Range["); + buf.append(min); + buf.append(','); + buf.append(max); + buf.append(']'); + toString = buf.toString(); + } + return toString; + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/math/Fraction.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/math/Fraction.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/math/Fraction.java 30 Aug 2012 16:24:43 -0000 1.1 @@ -0,0 +1,794 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.math; + +import java.io.Serializable; + +/** + *

Fraction is a Number implementation that + * stores fractions accurately.

+ * + *

This class is immutable, and interoperable with most methods that accept + * a Number.

+ * + * @author Travis Reeder + * @author Stephen Colebourne + * @author Tim O'Brien + * @author Pete Gieser + * @since 2.0 + * @version $Id: Fraction.java,v 1.1 2012/08/30 16:24:43 marcin Exp $ + */ +public final class Fraction extends Number implements Serializable, Comparable { + + /** Serialization lock, Lang version 2.0 */ + private static final long serialVersionUID = 65382027393090L; + + /** + * Fraction representation of 0. + */ + public static final Fraction ZERO = new Fraction(0, 1); + /** + * Fraction representation of 1. + */ + public static final Fraction ONE = new Fraction(1, 1); + /** + * Fraction representation of 1/2. + */ + public static final Fraction ONE_HALF = new Fraction(1, 2); + /** + * Fraction representation of 1/3. + */ + public static final Fraction ONE_THIRD = new Fraction(1, 3); + /** + * Fraction representation of 2/3. + */ + public static final Fraction TWO_THIRDS = new Fraction(2, 3); + /** + * Fraction representation of 1/4. + */ + public static final Fraction ONE_QUARTER = new Fraction(1, 4); + /** + * Fraction representation of 2/4. + */ + public static final Fraction TWO_QUARTERS = new Fraction(2, 4); + /** + * Fraction representation of 3/4. + */ + public static final Fraction THREE_QUARTERS = new Fraction(3, 4); + /** + * Fraction representation of 1/5. + */ + public static final Fraction ONE_FIFTH = new Fraction(1, 5); + /** + * Fraction representation of 2/5. + */ + public static final Fraction TWO_FIFTHS = new Fraction(2, 5); + /** + * Fraction representation of 3/5. + */ + public static final Fraction THREE_FIFTHS = new Fraction(3, 5); + /** + * Fraction representation of 4/5. + */ + public static final Fraction FOUR_FIFTHS = new Fraction(4, 5); + + + /** + * The numerator number part of the fraction (the three in three sevenths). + */ + private final int numerator; + /** + * The denominator number part of the fraction (the seven in three sevenths). + */ + private final int denominator; + + /** + * Cached output hashCode (class is immutable). + */ + private transient int hashCode = 0; + /** + * Cached output toString (class is immutable). + */ + private transient String toString = null; + /** + * Cached output toProperString (class is immutable). + */ + private transient String toProperString = null; + + /** + *

Constructs a Fraction instance with the 2 parts + * of a fraction Y/Z.

+ * + * @param numerator the numerator, for example the three in 'three sevenths' + * @param denominator the denominator, for example the seven in 'three sevenths' + */ + private Fraction(int numerator, int denominator) { + super(); + this.numerator = numerator; + this.denominator = denominator; + } + + /** + *

Creates a Fraction instance with the 2 parts + * of a fraction Y/Z.

+ * + *

Any negative signs are resolved to be on the numerator.

+ * + * @param numerator the numerator, for example the three in 'three sevenths' + * @param denominator the denominator, for example the seven in 'three sevenths' + * @return a new fraction instance + * @throws ArithmeticException if the denomiator is zero + */ + public static Fraction getFraction(int numerator, int denominator) { + if (denominator == 0) { + throw new ArithmeticException("The denominator must not be zero"); + } + if (denominator < 0) { + numerator = -numerator; + denominator = -denominator; + } + return new Fraction(numerator, denominator); + } + + /** + *

Creates a Fraction instance with the 3 parts + * of a fraction X Y/Z.

+ * + *

The negative sign must be passed in on the whole number part.

+ * + * @param whole the whole number, for example the one in 'one and three sevenths' + * @param numerator the numerator, for example the three in 'one and three sevenths' + * @param denominator the denominator, for example the seven in 'one and three sevenths' + * @return a new fraction instance + * @throws ArithmeticException if the denomiator is zero + * @throws ArithmeticException if the denomiator is negative + * @throws ArithmeticException if the numerator is negative + * @throws ArithmeticException if the resulting numerator exceeds + * Integer.MAX_VALUE + */ + public static Fraction getFraction(int whole, int numerator, int denominator) { + if (denominator == 0) { + throw new ArithmeticException("The denominator must not be zero"); + } + if (denominator < 0) { + throw new ArithmeticException("The denominator must not be negative"); + } + if (numerator < 0) { + throw new ArithmeticException("The numerator must not be negative"); + } + double numeratorValue = 0; + if (whole < 0) { + numeratorValue = (double) whole * denominator - numerator; + } else { + numeratorValue = (double) whole * denominator + numerator; + } + if (Math.abs(numeratorValue) > Integer.MAX_VALUE) { + throw new ArithmeticException("Numerator too large to represent as an Integer."); + } + return new Fraction((int) numeratorValue, denominator); + } + + /** + *

Creates a Fraction instance with the 2 parts + * of a fraction Y/Z.

+ * + *

Any negative signs are resolved to be on the numerator.

+ * + * @param numerator the numerator, for example the three in 'three sevenths' + * @param denominator the denominator, for example the seven in 'three sevenths' + * @return a new fraction instance, with the numerator and denominator reduced + * @throws ArithmeticException if the denomiator is zero + */ + public static Fraction getReducedFraction(int numerator, int denominator) { + if (denominator == 0) { + throw new ArithmeticException("The denominator must not be zero"); + } + if (denominator < 0) { + numerator = -numerator; + denominator = -denominator; + } + int gcd = greatestCommonDivisor(Math.abs(numerator), denominator); + return new Fraction(numerator / gcd, denominator / gcd); + } + + /** + *

Creates a Fraction instance from a double value.

+ * + *

This method uses the + * continued fraction algorithm, computing a maximum of + * 25 convergents and bounding the denominator by 10,000.

+ * + * @param value the double value to convert + * @return a new fraction instance that is close to the value + * @throws ArithmeticException if |value| > Integer.MAX_VALUE + * or value = NaN + * @throws ArithmeticException if the calculated denomiator is zero + * @throws ArithmeticException if the the algorithm does not converge + */ + public static Fraction getFraction(double value) { + int sign = (value < 0 ? -1 : 1); + value = Math.abs(value); + if (value > Integer.MAX_VALUE || Double.isNaN(value)) { + throw new ArithmeticException + ("The value must not be greater than Integer.MAX_VALUE or NaN"); + } + int wholeNumber = (int) value; + value -= wholeNumber; + + int numer0 = 0; // the pre-previous + int denom0 = 1; // the pre-previous + int numer1 = 1; // the previous + int denom1 = 0; // the previous + int numer2 = 0; // the current, setup in calculation + int denom2 = 0; // the current, setup in calculation + int a1 = (int) value; + int a2 = 0; + double x1 = 1; + double x2 = 0; + double y1 = value - a1; + double y2 = 0; + double delta1, delta2 = Double.MAX_VALUE; + double fraction; + int i = 1; +// System.out.println("---"); + do { + delta1 = delta2; + a2 = (int) (x1 / y1); + x2 = y1; + y2 = x1 - a2 * y1; + numer2 = a1 * numer1 + numer0; + denom2 = a1 * denom1 + denom0; + fraction = (double) numer2 / (double) denom2; + delta2 = Math.abs(value - fraction); +// System.out.println(numer2 + " " + denom2 + " " + fraction + " " + delta2 + " " + y1); + a1 = a2; + x1 = x2; + y1 = y2; + numer0 = numer1; + denom0 = denom1; + numer1 = numer2; + denom1 = denom2; + i++; +// System.out.println(">>" + delta1 +" "+ delta2+" "+(delta1 > delta2)+" "+i+" "+denom2); + } while ((delta1 > delta2) && (denom2 <= 10000) && (denom2 > 0) && (i < 25)); + if (i == 25) { + throw new ArithmeticException("Unable to convert double to fraction"); + } + return getReducedFraction((numer0 + wholeNumber * denom0) * sign, denom0); + } + + /** + *

Creates a Fraction from a String.

+ * + *

The formats accepted are:

+ * + *

+ *

    + *
  1. double String containing a dot
  2. + *
  3. 'X Y/Z'
  4. + *
  5. 'Y/Z'
  6. + *
+ * and a .

+ * + * @param str the string to parse, must not be null + * @return the new Fraction instance + * @throws IllegalArgumentException if the string is null + * @throws NumberFormatException if the number format is invalid + */ + public static Fraction getFraction(String str) { + if (str == null) { + throw new IllegalArgumentException("The string must not be null"); + } + // parse double format + int pos = str.indexOf('.'); + if (pos >= 0) { + return getFraction(Double.parseDouble(str)); + } + + // parse X Y/Z format + pos = str.indexOf(' '); + if (pos > 0) { + int whole = Integer.parseInt(str.substring(0, pos)); + str = str.substring(pos + 1); + pos = str.indexOf('/'); + if (pos < 0) { + throw new NumberFormatException("The fraction could not be parsed as the format X Y/Z"); + } else { + int denom = Integer.parseInt(str.substring(pos + 1)); + return getFraction( + Integer.parseInt(str.substring(0, pos)) + whole * denom, + denom + ); + } + } + + // parse Y/Z format + pos = str.indexOf('/'); + if (pos < 0) { + // simple whole number + return getFraction(Integer.parseInt(str), 1); + } else { + return getFraction( + Integer.parseInt(str.substring(0, pos)), + Integer.parseInt(str.substring(pos + 1)) + ); + } + } + + // Accessors + //------------------------------------------------------------------- + + /** + *

Gets the numerator part of the fraction.

+ * + *

This method may return a value greater than the denominator, an + * improper fraction, such as the seven in 7/4.

+ * + * @return the numerator fraction part + */ + public int getNumerator() { + return numerator; + } + + /** + *

Gets the denominator part of the fraction.

+ * + * @return the denominator fraction part + */ + public int getDenominator() { + return denominator; + } + + /** + *

Gets the proper numerator, always positive.

+ * + *

An improper fraction 7/4 can be resolved into a proper one, 1 3/4. + * This method returns the 3 from the proper fraction.

+ * + *

If the fraction is negative such as -7/4, it can be resolved into + * -1 3/4, so this method returns the positive proper numerator, 3.

+ * + * @return the numerator fraction part of a proper fraction, always positive + */ + public int getProperNumerator() { + return Math.abs(numerator % denominator); + } + + /** + *

Gets the proper whole part of the fraction.

+ * + *

An improper fraction 7/4 can be resolved into a proper one, 1 3/4. + * This method returns the 1 from the proper fraction.

+ * + *

If the fraction is negative such as -7/4, it can be resolved into + * -1 3/4, so this method returns the positive whole part -1.

+ * + * @return the whole fraction part of a proper fraction, that includes the sign + */ + public int getProperWhole() { + return numerator / denominator; + } + + // Number methods + //------------------------------------------------------------------- + + /** + *

Gets the fraction as an int. This returns the whole number + * part of the fraction.

+ * + * @return the whole number fraction part + */ + public int intValue() { + return numerator / denominator; + } + + /** + *

Gets the fraction as a long. This returns the whole number + * part of the fraction.

+ * + * @return the whole number fraction part + */ + public long longValue() { + return (long) numerator / denominator; + } + + /** + *

Gets the fraction as a float. This calculates the fraction + * as the numerator divided by denominator.

+ * + * @return the fraction as a float + */ + public float floatValue() { + return ((float) numerator) / ((float) denominator); + } + + /** + *

Gets the fraction as a double. This calculates the fraction + * as the numerator divided by denominator.

+ * + * @return the fraction as a double + */ + public double doubleValue() { + return ((double) numerator) / ((double) denominator); + } + + // Calculations + //------------------------------------------------------------------- + + /** + *

Reduce the fraction to the smallest values for the numerator and + * denominator, returning the result..

+ * + * @return a new reduce fraction instance, or this if no simplification possible + */ + public Fraction reduce() { + int gcd = greatestCommonDivisor(Math.abs(numerator), denominator); + return Fraction.getFraction(numerator / gcd, denominator / gcd); + } + + /** + *

Gets a fraction that is the invert (1/fraction) of this one.

+ * + *

The returned fraction is not reduced.

+ * + * @return a new fraction instance with the numerator and denominator inverted + * @throws ArithmeticException if the numerator is zero + */ + public Fraction invert() { + if (numerator == 0) { + throw new ArithmeticException("Unable to invert a fraction with a zero numerator"); + } + return getFraction(denominator, numerator); + } + + /** + *

Gets a fraction that is the negative (-fraction) of this one.

+ * + *

The returned fraction is not reduced.

+ * + * @return a new fraction instance with the opposite signed numerator + */ + public Fraction negate() { + return getFraction(-numerator, denominator); + } + + /** + *

Gets a fraction that is the positive equivalent of this one.

+ *

More precisely:

(fraction >= 0 ? this : -fraction)

+ * + *

The returned fraction is not reduced.

+ * + * @return this if it is positive, or a new positive fraction + * instance with the opposite signed numerator + */ + public Fraction abs() { + if (numerator >= 0) { + return this; + } + return getFraction(-numerator, denominator); + } + + /** + *

Gets a fraction that is raised to the passed in power.

+ * + *

The returned fraction is not reduced.

+ * + * @param power the power to raise the fraction to + * @return this if the power is one, ONE if the power + * is zero (even if the fraction equals ZERO) or a new fraction instance + * raised to the appropriate power + * @throws ArithmeticException if the resulting numerator or denominator exceeds + * Integer.MAX_VALUE + */ + public Fraction pow(int power) { + if (power == 1) { + return this; + } else if (power == 0) { + return ONE; + } else { + double denominatorValue = Math.pow(denominator, power); + double numeratorValue = Math.pow(numerator, power); + if (numeratorValue > Integer.MAX_VALUE || denominatorValue > Integer.MAX_VALUE) { + throw new ArithmeticException("Integer overflow"); + } + if (power < 0) { + return getFraction((int) Math.pow(denominator, -power), + (int) Math.pow(numerator, -power)); + } + return getFraction((int) Math.pow(numerator, power), + (int) Math.pow(denominator, power)); + } + } + + /** + *

Gets the greatest common divisor of two numbers.

+ * + * @param number1 a positive number + * @param number2 a positive number + * @return the greatest common divisor, never zero + */ + private static int greatestCommonDivisor(int number1, int number2) { + int remainder = number1 % number2; + while (remainder != 0) { + number1 = number2; + number2 = remainder; + remainder = number1 % number2; + } + return number2; + } + + // Arithmetic + //------------------------------------------------------------------- + + /** + *

Adds the value of this fraction to another, returning the result in + * reduced form.

+ * + * @param fraction the fraction to add, must not be null + * @return a Fraction instance with the resulting values + * @throws IllegalArgumentException if the fraction is null + * @throws ArithmeticException if the resulting numerator or denominator exceeds + * Integer.MAX_VALUE + */ + public Fraction add(Fraction fraction) { + if (fraction == null) { + throw new IllegalArgumentException("The fraction must not be null"); + } + if (numerator == 0) { + return fraction; + } + if (fraction.numerator == 0) { + return this; + } + // Compute lcd explicitly to limit overflow + int gcd = greatestCommonDivisor(Math.abs(fraction.denominator), Math.abs(denominator)); + int thisResidue = denominator/gcd; + int thatResidue = fraction.denominator/gcd; + double denominatorValue = Math.abs((double) gcd * thisResidue * thatResidue); + double numeratorValue = (double) numerator * thatResidue + fraction.numerator * thisResidue; + if (Math.abs(numeratorValue) > Integer.MAX_VALUE || + Math.abs(denominatorValue) > Integer.MAX_VALUE) { + throw new ArithmeticException("Integer overflow"); + } + return Fraction.getReducedFraction((int) numeratorValue, (int) denominatorValue); + } + + /** + *

Subtracts the value of another fraction from the value of this one, + * returning the result in reduced form.

+ * + * @param fraction the fraction to subtract, must not be null + * @return a Fraction instance with the resulting values + * @throws IllegalArgumentException if the fraction is null + * @throws ArithmeticException if the resulting numerator or denominator exceeds + * Integer.MAX_VALUE + */ + public Fraction subtract(Fraction fraction) { + if (fraction == null) { + throw new IllegalArgumentException("The fraction must not be null"); + } + return add(fraction.negate()); + } + + /** + *

Multiplies the value of this fraction by another, returning the result + * in reduced form.

+ * + * @param fraction the fraction to multipy by, must not be null + * @return a Fraction instance with the resulting values + * @throws IllegalArgumentException if the fraction is null + * @throws ArithmeticException if the resulting numerator or denominator exceeds + * Integer.MAX_VALUE + */ + public Fraction multiplyBy(Fraction fraction) { + if (fraction == null) { + throw new IllegalArgumentException("The fraction must not be null"); + } + if (numerator == 0 || fraction.numerator == 0) { + return ZERO; + } + double numeratorValue = (double) numerator * fraction.numerator; + double denominatorValue = (double) denominator * fraction.denominator; + if (Math.abs(numeratorValue) > Integer.MAX_VALUE || + Math.abs(denominatorValue) > Integer.MAX_VALUE) { + throw new ArithmeticException("Integer overflow"); + } + return getReducedFraction((int) numeratorValue, (int) denominatorValue); + } + + /** + *

Divide the value of this fraction by another, returning the result + * in reduced form.

+ * + * @param fraction the fraction to divide by, must not be null + * @return a Fraction instance with the resulting values + * @throws IllegalArgumentException if the fraction is null + * @throws ArithmeticException if the fraction to divide by is zero + * @throws ArithmeticException if the resulting numerator or denominator exceeds + * Integer.MAX_VALUE + */ + public Fraction divideBy(Fraction fraction) { + if (fraction == null) { + throw new IllegalArgumentException("The fraction must not be null"); + } + if (fraction.numerator == 0) { + throw new ArithmeticException("The fraction to divide by must not be zero"); + } + if (numerator == 0) { + return ZERO; + } + double numeratorValue = (double) numerator * fraction.denominator; + double denominatorValue = (double) denominator * fraction.numerator; + if (Math.abs(numeratorValue) > Integer.MAX_VALUE || + Math.abs(denominatorValue) > Integer.MAX_VALUE) { + throw new ArithmeticException("Integer overflow"); + } + return getReducedFraction((int) numeratorValue, (int) denominatorValue); + } + + // Basics + //------------------------------------------------------------------- + + /** + *

Compares this fraction to another object to test if they are equal.

. + * + *

To be equal, both values must be equal. Thus 2/4 is not equal to 1/2.

+ * + * @param obj the reference object with which to compare + * @return true if this object is equal + */ + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof Fraction == false) { + return false; + } + Fraction other = (Fraction) obj; + return (numerator == other.numerator && + denominator == other.denominator); + } + + /** + *

Gets a hashCode for the fraction.

+ * + * @return a hash code value for this object + */ + public int hashCode() { + if (hashCode == 0) { + hashCode = 17; + hashCode = 37 * hashCode + numerator; + hashCode = 37 * hashCode + denominator; + } + return hashCode; + } + + /** + *

Compares this object to another based on size.

+ * + * @param object the object to compare to + * @return -1 if this is less, 0 if equal, +1 if greater + * @throws ClassCastException if the object is not a Fraction + * @throws NullPointerException if the object is null + */ + public int compareTo(Object object) { + Fraction other = (Fraction) object; + if (numerator == other.numerator && denominator == other.denominator) { + return 0; + } + + // otherwise see which is less + long first = (long) numerator * (long) other.denominator; + long second = (long) other.numerator * (long) denominator; + if (first == second) { + return 0; + } else if (first < second) { + return -1; + } else { + return 1; + } + } + + /** + *

Gets the fraction as a String.

+ * + *

The format used is 'numerator/denominator' always. + * + * @return a String form of the fraction + */ + public String toString() { + if (toString == null) { + toString = new StringBuffer(32) + .append(numerator) + .append('/') + .append(denominator).toString(); + } + return toString; + } + + /** + *

Gets the fraction as a proper String in the format X Y/Z.

+ * + *

The format used in 'wholeNumber numerator/denominator'. + * If the whole number is zero it will be ommitted. If the numerator is zero, + * only the whole number is returned.

+ * + * @return a String form of the fraction + */ + public String toProperString() { + if (toProperString == null) { + if (numerator == 0) { + toProperString = "0"; + } else if (numerator == denominator) { + toProperString = "1"; + } else if (Math.abs(numerator) > denominator) { + int properNumerator = getProperNumerator(); + if (properNumerator == 0) { + toProperString = Integer.toString(getProperWhole()); + } else { + toProperString = new StringBuffer(32) + .append(getProperWhole()).append(' ') + .append(properNumerator).append('/') + .append(denominator).toString(); + } + } else { + toProperString = new StringBuffer(32) + .append(numerator).append('/') + .append(denominator).toString(); + } + } + return toProperString; + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/math/IntRange.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/math/IntRange.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/math/IntRange.java 30 Aug 2012 16:24:43 -0000 1.1 @@ -0,0 +1,416 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.math; + +import java.io.Serializable; + +/** + *

IntRange represents an inclusive range of ints.

+ * + * @author Stephen Colebourne + * @since 2.0 + * @version $Id: IntRange.java,v 1.1 2012/08/30 16:24:43 marcin Exp $ + */ +public final class IntRange extends Range implements Serializable { + + private static final long serialVersionUID = 71849363892730L; + + /** + * The minimum number in this range (inclusive). + */ + private final int min; + /** + * The maximum number in this range (inclusive). + */ + private final int max; + + /** + * Cached output minObject (class is immutable). + */ + private transient Integer minObject = null; + /** + * Cached output maxObject (class is immutable). + */ + private transient Integer maxObject = null; + /** + * Cached output hashCode (class is immutable). + */ + private transient int hashCode = 0; + /** + * Cached output toString (class is immutable). + */ + private transient String toString = null; + + /** + *

Constructs a new IntRange using the specified + * number as both the minimum and maximum in this range.

+ * + * @param number the number to use for this range + */ + public IntRange(int number) { + super(); + this.min = number; + this.max = number; + } + + /** + *

Constructs a new IntRange using the specified + * number as both the minimum and maximum in this range.

+ * + * @param number the number to use for this range, must not be null + * @throws IllegalArgumentException if the number is null + */ + public IntRange(Number number) { + super(); + if (number == null) { + throw new IllegalArgumentException("The number must not be null"); + } + this.min = number.intValue(); + this.max = number.intValue(); + if (number instanceof Integer) { + this.minObject = (Integer) number; + this.maxObject = (Integer) number; + } + } + + /** + *

Constructs a new IntRange with the specified + * minimum and maximum numbers (both inclusive).

+ * + *

The arguments may be passed in the order (min,max) or (max,min). The + * getMinimum and getMaximum methods will return the correct values.

+ * + * @param number1 first number that defines the edge of the range, inclusive + * @param number2 second number that defines the edge of the range, inclusive + */ + public IntRange(int number1, int number2) { + super(); + if (number2 < number1) { + this.min = number2; + this.max = number1; + } else { + this.min = number1; + this.max = number2; + } + } + + /** + *

Constructs a new IntRange with the specified + * minimum and maximum numbers (both inclusive).

+ * + *

The arguments may be passed in the order (min,max) or (max,min). The + * getMinimum and getMaximum methods will return the correct values.

+ * + * @param number1 first number that defines the edge of the range, inclusive + * @param number2 second number that defines the edge of the range, inclusive + * @throws IllegalArgumentException if either number is null + */ + public IntRange(Number number1, Number number2) { + super(); + if (number1 == null || number2 == null) { + throw new IllegalArgumentException("The numbers must not be null"); + } + int number1val = number1.intValue(); + int number2val = number2.intValue(); + if (number2val < number1val) { + this.min = number2val; + this.max = number1val; + if (number2 instanceof Integer) { + this.minObject = (Integer) number2; + } + if (number1 instanceof Integer) { + this.maxObject = (Integer) number1; + } + } else { + this.min = number1val; + this.max = number2val; + if (number1 instanceof Integer) { + this.minObject = (Integer) number1; + } + if (number2 instanceof Integer) { + this.maxObject = (Integer) number2; + } + } + } + + // Accessors + //-------------------------------------------------------------------- + + /** + *

Returns the minimum number in this range.

+ * + * @return the minimum number in this range + */ + public Number getMinimumNumber() { + if (minObject == null) { + minObject = new Integer(min); + } + return minObject; + } + + /** + *

Gets the minimum number in this range as a long.

+ * + * @return the minimum number in this range + */ + public long getMinimumLong() { + return min; + } + + /** + *

Gets the minimum number in this range as a int.

+ * + * @return the minimum number in this range + */ + public int getMinimumInteger() { + return min; + } + + /** + *

Gets the minimum number in this range as a double.

+ * + * @return the minimum number in this range + */ + public double getMinimumDouble() { + return min; + } + + /** + *

Gets the minimum number in this range as a float.

+ * + * @return the minimum number in this range + */ + public float getMinimumFloat() { + return min; + } + + /** + *

Returns the maximum number in this range.

+ * + * @return the maximum number in this range + */ + public Number getMaximumNumber() { + if (maxObject == null) { + maxObject = new Integer(max); + } + return maxObject; + } + + /** + *

Gets the maximum number in this range as a long.

+ * + * @return the maximum number in this range + */ + public long getMaximumLong() { + return max; + } + + /** + *

Gets the maximum number in this range as a int.

+ * + * @return the maximum number in this range + */ + public int getMaximumInteger() { + return max; + } + + /** + *

Gets the maximum number in this range as a double.

+ * + * @return the maximum number in this range + */ + public double getMaximumDouble() { + return max; + } + + /** + *

Gets the maximum number in this range as a float.

+ * + * @return the maximum number in this range + */ + public float getMaximumFloat() { + return max; + } + + // Tests + //-------------------------------------------------------------------- + + /** + *

Tests whether the specified number occurs within + * this range using int comparison.

+ * + *

null is handled and returns false.

+ * + * @param number the number to test, may be null + * @return true if the specified number occurs within this range + */ + public boolean containsNumber(Number number) { + if (number == null) { + return false; + } + return containsInteger(number.intValue()); + } + + /** + *

Tests whether the specified int occurs within + * this range using int comparison.

+ * + *

This implementation overrides the superclass for performance as it is + * the most common case.

+ * + * @param value the int to test + * @return true if the specified number occurs within this + * range by int comparison + */ + public boolean containsInteger(int value) { + return (value >= min && value <= max); + } + + // Range tests + //-------------------------------------------------------------------- + + /** + *

Tests whether the specified range occurs entirely within this range + * using int comparison.

+ * + *

null is handled and returns false.

+ * + * @param range the range to test, may be null + * @return true if the specified range occurs entirely within this range + * @throws IllegalArgumentException if the range is not of this type + */ + public boolean containsRange(Range range) { + if (range == null) { + return false; + } + return containsInteger(range.getMinimumInteger()) && + containsInteger(range.getMaximumInteger()); + } + + /** + *

Tests whether the specified range overlaps with this range + * using int comparison.

+ * + *

null is handled and returns false.

+ * + * @param range the range to test, may be null + * @return true if the specified range overlaps with this range + */ + public boolean overlapsRange(Range range) { + if (range == null) { + return false; + } + return range.containsInteger(min) || + range.containsInteger(max) || + containsInteger(range.getMinimumInteger()); + } + + // Basics + //-------------------------------------------------------------------- + + /** + *

Compares this range to another object to test if they are equal.

. + * + *

To be equal, the class, minimum and maximum must be equal.

+ * + * @param obj the reference object with which to compare + * @return true if this object is equal + */ + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof IntRange == false) { + return false; + } + IntRange range = (IntRange) obj; + return (min == range.min && max == range.max); + } + + /** + *

Gets a hashCode for the range.

+ * + * @return a hash code value for this object + */ + public int hashCode() { + if (hashCode == 0) { + hashCode = 17; + hashCode = 37 * hashCode + getClass().hashCode(); + hashCode = 37 * hashCode + min; + hashCode = 37 * hashCode + max; + } + return hashCode; + } + + /** + *

Gets the range as a String.

+ * + *

The format of the String is 'Range[min,max]'.

+ * + * @return the String representation of this range + */ + public String toString() { + if (toString == null) { + StringBuffer buf = new StringBuffer(32); + buf.append("Range["); + buf.append(min); + buf.append(','); + buf.append(max); + buf.append(']'); + toString = buf.toString(); + } + return toString; + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/math/JVMRandom.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/math/JVMRandom.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/math/JVMRandom.java 30 Aug 2012 16:24:43 -0000 1.1 @@ -0,0 +1,186 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.math; + +import java.util.Random; + +/** + *

JVMRandom is a wrapper that supports all possible + * Random methods via the {@link java.lang.Math#random()} method + * and its system-wide {@link Random} object.

+ * + * @author Henri Yandell + * @since 2.0 + * @version $Id: JVMRandom.java,v 1.1 2012/08/30 16:24:43 marcin Exp $ + */ +public final class JVMRandom extends Random { + + /** + * Ensures that only the constructor can call reseed. + */ + private boolean constructed = false; + + public JVMRandom() { + this.constructed = true; + } + + /** + * Unsupported in 2.0. + */ + public synchronized void setSeed(long seed) { + if (this.constructed) { + throw new UnsupportedOperationException(); + } + } + + /** + * Unsupported in 2.0. + */ + public synchronized double nextGaussian() { + throw new UnsupportedOperationException(); + } + + /** + * Unsupported in 2.0. + */ + public void nextBytes(byte[] byteArray) { + throw new UnsupportedOperationException(); + } + + /** + *

Returns the next pseudorandom, uniformly distributed int value + * from the Math.random() sequence.

+ * + * @return the random int + */ + public int nextInt() { + return nextInt(Integer.MAX_VALUE); + } + /** + *

Returns a pseudorandom, uniformly distributed int value between + * 0 (inclusive) and the specified value (exclusive), from + * the Math.random() sequence.

+ * + * @param n the specified exclusive max-value + * @return the random int + * @throws IllegalArgumentException when n <= 0 + */ + public int nextInt(int n) { + if (n <= 0) { + throw new IllegalArgumentException( + "Upper bound for nextInt must be positive" + ); + } + // TODO: check this cannot return 'n' + return (int)(Math.random() * n); + } + /** + *

Returns the next pseudorandom, uniformly distributed long value + * from the Math.random() sequence.

+ * @return the random long + */ + public long nextLong() { + // possible loss of precision? + return nextLong(Long.MAX_VALUE); + } + + + /** + *

Returns a pseudorandom, uniformly distributed long value between + * 0 (inclusive) and the specified value (exclusive), from + * the Math.random() sequence.

+ * + * @param n the specified exclusive max-value + * @return the random long + * @throws IllegalArgumentException when n <= 0 + */ + public static long nextLong(long n) { + if (n <= 0) { + throw new IllegalArgumentException( + "Upper bound for nextInt must be positive" + ); + } + // TODO: check this cannot return 'n' + return (long)(Math.random() * n); + } + + /** + *

Returns the next pseudorandom, uniformly distributed boolean value + * from the Math.random() sequence.

+ * + * @return the random boolean + */ + public boolean nextBoolean() { + return (Math.random() > 0.5); + } + /** + *

Returns the next pseudorandom, uniformly distributed float value + * between 0.0 and 1.0 from the Math.random() + * sequence.

+ * + * @return the random float + */ + public float nextFloat() { + return (float)Math.random(); + } + /** + *

Synonymous to the Math.random() call.

+ * + * @return the random double + */ + public double nextDouble() { + return Math.random(); + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/math/LongRange.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/math/LongRange.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/math/LongRange.java 30 Aug 2012 16:24:43 -0000 1.1 @@ -0,0 +1,423 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.math; + +import java.io.Serializable; + +/** + *

LongRange represents an inclusive range of longs.

+ * + * @author Stephen Colebourne + * @since 2.0 + * @version $Id: LongRange.java,v 1.1 2012/08/30 16:24:43 marcin Exp $ + */ +public final class LongRange extends Range implements Serializable { + + private static final long serialVersionUID = 71849363892720L; + + /** + * The minimum number in this range (inclusive). + */ + private final long min; + /** + * The maximum number in this range (inclusive). + */ + private final long max; + + /** + * Cached output minObject (class is immutable). + */ + private transient Long minObject = null; + /** + * Cached output maxObject (class is immutable). + */ + private transient Long maxObject = null; + /** + * Cached output hashCode (class is immutable). + */ + private transient int hashCode = 0; + /** + * Cached output toString (class is immutable). + */ + private transient String toString = null; + + /** + *

Constructs a new LongRange using the specified + * number as both the minimum and maximum in this range.

+ * + * @param number the number to use for this range + */ + public LongRange(long number) { + super(); + this.min = number; + this.max = number; + } + + /** + *

Constructs a new LongRange using the specified + * number as both the minimum and maximum in this range.

+ * + * @param number the number to use for this range, must not + * be null + * @throws IllegalArgumentException if the number is null + */ + public LongRange(Number number) { + super(); + if (number == null) { + throw new IllegalArgumentException("The number must not be null"); + } + this.min = number.longValue(); + this.max = number.longValue(); + if (number instanceof Long) { + this.minObject = (Long) number; + this.maxObject = (Long) number; + } + } + + /** + *

Constructs a new LongRange with the specified + * minimum and maximum numbers (both inclusive).

+ * + *

The arguments may be passed in the order (min,max) or (max,min). The + * getMinimum and getMaximum methods will return the correct values.

+ * + * @param number1 first number that defines the edge of the range, inclusive + * @param number2 second number that defines the edge of the range, inclusive + */ + public LongRange(long number1, long number2) { + super(); + if (number2 < number1) { + this.min = number2; + this.max = number1; + } else { + this.min = number1; + this.max = number2; + } + } + + /** + *

Constructs a new LongRange with the specified + * minimum and maximum numbers (both inclusive).

+ * + *

The arguments may be passed in the order (min,max) or (max,min). The + * getMinimum and getMaximum methods will return the correct values.

+ * + * @param number1 first number that defines the edge of the range, inclusive + * @param number2 second number that defines the edge of the range, inclusive + * @throws IllegalArgumentException if either number is null + */ + public LongRange(Number number1, Number number2) { + super(); + if (number1 == null || number2 == null) { + throw new IllegalArgumentException("The numbers must not be null"); + } + long number1val = number1.longValue(); + long number2val = number2.longValue(); + if (number2val < number1val) { + this.min = number2val; + this.max = number1val; + if (number2 instanceof Long) { + this.minObject = (Long) number2; + } + if (number1 instanceof Long) { + this.maxObject = (Long) number1; + } + } else { + this.min = number1val; + this.max = number2val; + if (number1 instanceof Long) { + this.minObject = (Long) number1; + } + if (number2 instanceof Long) { + this.maxObject = (Long) number2; + } + } + } + + // Accessors + //-------------------------------------------------------------------- + + /** + *

Returns the minimum number in this range.

+ * + * @return the minimum number in this range + */ + public Number getMinimumNumber() { + if (minObject == null) { + minObject = new Long(min); + } + return minObject; + } + + /** + *

Gets the minimum number in this range as a long.

+ * + * @return the minimum number in this range + */ + public long getMinimumLong() { + return min; + } + + /** + *

Gets the minimum number in this range as a int.

+ * + *

This conversion can lose information for large values.

+ * + * @return the minimum number in this range + */ + public int getMinimumInteger() { + return (int) min; + } + + /** + *

Gets the minimum number in this range as a double.

+ * + *

This conversion can lose information for large values.

+ * + * @return the minimum number in this range + */ + public double getMinimumDouble() { + return min; + } + + /** + *

Gets the minimum number in this range as a float.

+ * + *

This conversion can lose information for large values.

+ * + * @return the minimum number in this range + */ + public float getMinimumFloat() { + return min; + } + + /** + *

Returns the maximum number in this range.

+ * + * @return the maximum number in this range + */ + public Number getMaximumNumber() { + if (maxObject == null) { + maxObject = new Long(max); + } + return maxObject; + } + + /** + *

Gets the maximum number in this range as a long.

+ * + * @return the maximum number in this range + */ + public long getMaximumLong() { + return max; + } + + /** + *

Gets the maximum number in this range as a int.

+ * + *

This conversion can lose information for large values.

+ */ + public int getMaximumInteger() { + return (int) max; + } + + /** + *

Gets the maximum number in this range as a double.

+ * + *

This conversion can lose information for large values.

+ */ + public double getMaximumDouble() { + return max; + } + + /** + *

Gets the maximum number in this range as a float.

+ * + *

This conversion can lose information for large values.

+ */ + public float getMaximumFloat() { + return max; + } + + // Tests + //-------------------------------------------------------------------- + + /** + *

Tests whether the specified number occurs within + * this range using long comparison.

+ * + *

null is handled and returns false.

+ * + * @param number the number to test, may be null + * @return true if the specified number occurs within this range + */ + public boolean containsNumber(Number number) { + if (number == null) { + return false; + } + return containsLong(number.longValue()); + } + + /** + *

Tests whether the specified long occurs within + * this range using long comparison.

+ * + *

This implementation overrides the superclass for performance as it is + * the most common case.

+ * + * @param value the long to test + * @return true if the specified number occurs within this + * range by long comparison + */ + public boolean containsLong(long value) { + return (value >= min && value <= max); + } + + // Range tests + //-------------------------------------------------------------------- + + /** + *

Tests whether the specified range occurs entirely within this range + * using long comparison.

+ * + *

null is handled and returns false.

+ * + * @param range the range to test, may be null + * @return true if the specified range occurs entirely within this range + * @throws IllegalArgumentException if the range is not of this type + */ + public boolean containsRange(Range range) { + if (range == null) { + return false; + } + return containsLong(range.getMinimumLong()) && + containsLong(range.getMaximumLong()); + } + + /** + *

Tests whether the specified range overlaps with this range + * using long comparison.

+ * + *

null is handled and returns false.

+ * + * @param range the range to test, may be null + * @return true if the specified range overlaps with this range + */ + public boolean overlapsRange(Range range) { + if (range == null) { + return false; + } + return range.containsLong(min) || + range.containsLong(max) || + containsLong(range.getMinimumLong()); + } + + // Basics + //-------------------------------------------------------------------- + + /** + *

Compares this range to another object to test if they are equal.

. + * + *

To be equal, the class, minimum and maximum must be equal.

+ * + * @param obj the reference object with which to compare + * @return true if this object is equal + */ + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof LongRange == false) { + return false; + } + LongRange range = (LongRange) obj; + return (min == range.min && max == range.max); + } + + /** + *

Gets a hashCode for the range.

+ * + * @return a hash code value for this object + */ + public int hashCode() { + if (hashCode == 0) { + hashCode = 17; + hashCode = 37 * hashCode + getClass().hashCode(); + hashCode = 37 * hashCode + ((int) (min ^ (min >> 32))); + hashCode = 37 * hashCode + ((int) (max ^ (max >> 32))); + } + return hashCode; + } + + /** + *

Gets the range as a String.

+ * + *

The format of the String is 'Range[min,max]'.

+ * + * @return the String representation of this range + */ + public String toString() { + if (toString == null) { + StringBuffer buf = new StringBuffer(32); + buf.append("Range["); + buf.append(min); + buf.append(','); + buf.append(max); + buf.append(']'); + toString = buf.toString(); + } + return toString; + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/math/NumberRange.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/math/NumberRange.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/math/NumberRange.java 30 Aug 2012 16:24:43 -0000 1.1 @@ -0,0 +1,274 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.math; + +import java.io.Serializable; + +/** + *

NumberRange represents an inclusive range of + * {@link java.lang.Number} objects of the same type.

+ * + * @author Christopher Elkins + * @author Stephen Colebourne + * @since 2.0 (previously in org.apache.commons.lang) + * @version $Id: NumberRange.java,v 1.1 2012/08/30 16:24:43 marcin Exp $ + */ +public final class NumberRange extends Range implements Serializable { + + private static final long serialVersionUID = 71849363892710L; + + /** + * The minimum number in this range. + */ + private final Number min; + /** + * The maximum number in this range. + */ + private final Number max; + + /** + * Cached output hashCode (class is immutable). + */ + private transient int hashCode = 0; + /** + * Cached output toString (class is immutable). + */ + private transient String toString = null; + + /** + *

Constructs a new NumberRange using the specified + * number as both the minimum and maximum in this range.

+ * + * @param num the number to use for this range + * @throws IllegalArgumentException if the number is null + * @throws IllegalArgumentException if the number doesn't implement Comparable + * @throws IllegalArgumentException if the number is Double.NaN or Float.NaN + */ + public NumberRange(Number num) { + if (num == null) { + throw new IllegalArgumentException("The number must not be null"); + } + if (num instanceof Comparable == false) { + throw new IllegalArgumentException("The number must implement Comparable"); + } + if (num instanceof Double && ((Double) num).isNaN()) { + throw new IllegalArgumentException("The number must not be NaN"); + } + if (num instanceof Float && ((Float) num).isNaN()) { + throw new IllegalArgumentException("The number must not be NaN"); + } + + this.min = num; + this.max = num; + } + + /** + *

Constructs a new NumberRange with the specified + * minimum and maximum numbers (both inclusive).

+ * + *

The arguments may be passed in the order (min,max) or (max,min). The + * {@link #getMinimumNumber()} and {@link #getMaximumNumber()} methods will return the + * correct value.

+ * + *

This constructor is designed to be used with two Number + * objects of the same type. If two objects of different types are passed in, + * an exception is thrown.

+ * + * @param num1 first number that defines the edge of the range, inclusive + * @param num2 second number that defines the edge of the range, inclusive + * @throws IllegalArgumentException if either number is null + * @throws IllegalArgumentException if the numbers are of different types + * @throws IllegalArgumentException if the numbers don't implement Comparable + */ + public NumberRange(Number num1, Number num2) { + if (num1 == null || num2 == null) { + throw new IllegalArgumentException("The numbers must not be null"); + } + if (num1.getClass() != num2.getClass()) { + throw new IllegalArgumentException("The numbers must be of the same type"); + } + if (num1 instanceof Comparable == false) { + throw new IllegalArgumentException("The numbers must implement Comparable"); + } + if (num1 instanceof Double) { + if (((Double) num1).isNaN() || ((Double) num2).isNaN()) { + throw new IllegalArgumentException("The number must not be NaN"); + } + } else if (num1 instanceof Float) { + if (((Float) num1).isNaN() || ((Float) num2).isNaN()) { + throw new IllegalArgumentException("The number must not be NaN"); + } + } + + int compare = ((Comparable) num1).compareTo(num2); + if (compare == 0) { + this.min = num1; + this.max = num1; + } else if (compare > 0) { + this.min = num2; + this.max = num1; + } else { + this.min = num1; + this.max = num2; + } + } + + // Accessors + //-------------------------------------------------------------------- + + /** + *

Returns the minimum number in this range.

+ * + * @return the minimum number in this range + */ + public Number getMinimumNumber() { + return min; + } + + /** + *

Returns the maximum number in this range.

+ * + * @return the maximum number in this range + */ + public Number getMaximumNumber() { + return max; + } + + // Tests + //-------------------------------------------------------------------- + + /** + *

Tests whether the specified number occurs within + * this range.

+ * + *

null is handled and returns false.

+ * + * @param number the number to test, may be null + * @return true if the specified number occurs within this range + * @throws IllegalArgumentException if the number is of a different type to the range + */ + public boolean containsNumber(Number number) { + if (number == null) { + return false; + } + if (number.getClass() != min.getClass()) { + throw new IllegalArgumentException("The number must be of the same type as the range numbers"); + } + int compareMin = ((Comparable) min).compareTo(number); + int compareMax = ((Comparable) max).compareTo(number); + return (compareMin <= 0 && compareMax >= 0); + } + + // Range tests + //-------------------------------------------------------------------- + // use Range implementations + + // Basics + //-------------------------------------------------------------------- + + /** + *

Compares this range to another object to test if they are equal.

. + * + *

To be equal, the class, minimum and maximum must be equal.

+ * + * @param obj the reference object with which to compare + * @return true if this object is equal + */ + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof NumberRange == false) { + return false; + } + NumberRange range = (NumberRange) obj; + return min.equals(range.min) && max.equals(range.max); + } + + /** + *

Gets a hashCode for the range.

+ * + * @return a hash code value for this object + */ + public int hashCode() { + if (hashCode == 0) { + hashCode = 17; + hashCode = 37 * hashCode + getClass().hashCode(); + hashCode = 37 * hashCode + min.hashCode(); + hashCode = 37 * hashCode + max.hashCode(); + } + return hashCode; + } + + /** + *

Gets the range as a String.

+ * + *

The format of the String is 'Range[min,max]'.

+ * + * @return the String representation of this range + */ + public String toString() { + if (toString == null) { + StringBuffer buf = new StringBuffer(32); + buf.append("Range["); + buf.append(min); + buf.append(','); + buf.append(max); + buf.append(']'); + toString = buf.toString(); + } + return toString; + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/math/NumberUtils.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/math/NumberUtils.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/math/NumberUtils.java 30 Aug 2012 16:24:43 -0000 1.1 @@ -0,0 +1,1224 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.math; + +import java.math.BigDecimal; +import java.math.BigInteger; + +import org.apache.commons.lang.StringUtils; + +/** + *

Provides extra functionality for Java Number classes.

+ * + * @author Henri Yandell + * @author Rand McNeely + * @author Stephen Colebourne + * @author Steve Downey + * @author Eric Pugh + * @author Phil Steitz + * @author Matthew Hawthorne + * @author Gary Gregory + * @since 2.0 + * @version $Id: NumberUtils.java,v 1.1 2012/08/30 16:24:43 marcin Exp $ + */ +public class NumberUtils { + + /** Reusable Long constant for zero. */ + public static final Long LONG_ZERO = new Long(0L); + /** Reusable Long constant for one. */ + public static final Long LONG_ONE = new Long(1L); + /** Reusable Long constant for minus one. */ + public static final Long LONG_MINUS_ONE = new Long(-1L); + /** Reusable Integer constant for zero. */ + public static final Integer INTEGER_ZERO = new Integer(0); + /** Reusable Integer constant for one. */ + public static final Integer INTEGER_ONE = new Integer(1); + /** Reusable Integer constant for minus one. */ + public static final Integer INTEGER_MINUS_ONE = new Integer(-1); + /** Reusable Short constant for zero. */ + public static final Short SHORT_ZERO = new Short((short) 0); + /** Reusable Short constant for one. */ + public static final Short SHORT_ONE = new Short((short) 1); + /** Reusable Short constant for minus one. */ + public static final Short SHORT_MINUS_ONE = new Short((short) -1); + /** Reusable Byte constant for zero. */ + public static final Byte BYTE_ZERO = new Byte((byte) 0); + /** Reusable Byte constant for one. */ + public static final Byte BYTE_ONE = new Byte((byte) 1); + /** Reusable Byte constant for minus one. */ + public static final Byte BYTE_MINUS_ONE = new Byte((byte) -1); + /** Reusable Double constant for zero. */ + public static final Double DOUBLE_ZERO = new Double(0.0d); + /** Reusable Double constant for one. */ + public static final Double DOUBLE_ONE = new Double(1.0d); + /** Reusable Double constant for minus one. */ + public static final Double DOUBLE_MINUS_ONE = new Double(-1.0d); + /** Reusable Float constant for zero. */ + public static final Float FLOAT_ZERO = new Float(0.0f); + /** Reusable Float constant for one. */ + public static final Float FLOAT_ONE = new Float(1.0f); + /** Reusable Float constant for minus one. */ + public static final Float FLOAT_MINUS_ONE = new Float(-1.0f); + + /** + *

NumberUtils instances should NOT be constructed in standard programming. + * Instead, the class should be used as NumberUtils.stringToInt("6");.

+ * + *

This constructor is public to permit tools that require a JavaBean instance + * to operate.

+ */ + public NumberUtils() { + } + + //----------------------------------------------------------------------- + /** + *

Convert a String to an int, returning + * zero if the conversion fails.

+ * + *

If the string is null, zero is returned.

+ * + * @param str the string to convert, may be null + * @return the int represented by the string, or zero if + * conversion fails + */ + public static int stringToInt(String str) { + return stringToInt(str, 0); + } + + /** + *

Convert a String to an int, returning a + * default value if the conversion fails.

+ * + *

If the string is null, the default value is returned.

+ * + * @param str the string to convert, may be null + * @param defaultValue the default value + * @return the int represented by the string, or the default if conversion fails + */ + public static int stringToInt(String str, int defaultValue) { + try { + return Integer.parseInt(str); + } catch (NumberFormatException nfe) { + return defaultValue; + } + } + + //----------------------------------------------------------------------- + // must handle Long, Float, Integer, Float, Short, + // BigDecimal, BigInteger and Byte + // useful methods: + // Byte.decode(String) + // Byte.valueOf(String,int radix) + // Byte.valueOf(String) + // Double.valueOf(String) + // Float.valueOf(String) + // new Float(String) + // Integer.valueOf(String,int radix) + // Integer.valueOf(String) + // Integer.decode(String) + // Integer.getInteger(String) + // Integer.getInteger(String,int val) + // Integer.getInteger(String,Integer val) + // new Integer(String) + // new Double(String) + // new Byte(String) + // new Long(String) + // Long.getLong(String) + // Long.getLong(String,int) + // Long.getLong(String,Integer) + // Long.valueOf(String,int) + // Long.valueOf(String) + // new Short(String) + // Short.decode(String) + // Short.valueOf(String,int) + // Short.valueOf(String) + // new BigDecimal(String) + // new BigInteger(String) + // new BigInteger(String,int radix) + // Possible inputs: + // 45 45.5 45E7 4.5E7 Hex Oct Binary xxxF xxxD xxxf xxxd + // plus minus everything. Prolly more. A lot are not separable. + + /** + *

Turns a string value into a java.lang.Number.

+ * + *

First, the value is examined for a type qualifier on the end + * ('f','F','d','D','l','L'). If it is found, it starts + * trying to create successively larger types from the type specified + * until one is found that can represent the value.

+ * + *

If a type specifier is not found, it will check for a decimal point + * and then try successively larger types from Integer to + * BigInteger and from Float to + * BigDecimal.

+ * + *

If the string starts with 0x or -0x, it + * will be interpreted as a hexadecimal integer. Values with leading + * 0's will not be interpreted as octal.

+ * + *

Returns null if the string is null.

+ * + *

This method does not trim the input string, i.e., strings with leading + * or trailing spaces will generate NumberFormatExceptions.

+ * + * @param str String containing a number, may be null + * @return Number created from the string + * @throws NumberFormatException if the value cannot be converted + */ + public static Number createNumber(String str) throws NumberFormatException { + if (str == null) { + return null; + } + if (StringUtils.isBlank(str)) { + throw new NumberFormatException("A blank string is not a valid number"); + } + if (str.startsWith("--")) { + // this is protection for poorness in java.lang.BigDecimal. + // it accepts this as a legal value, but it does not appear + // to be in specification of class. OS X Java parses it to + // a wrong value. + return null; + } + if (str.startsWith("0x") || str.startsWith("-0x")) { + return createInteger(str); + } + char lastChar = str.charAt(str.length() - 1); + String mant; + String dec; + String exp; + int decPos = str.indexOf('.'); + int expPos = str.indexOf('e') + str.indexOf('E') + 1; + + if (decPos > -1) { + + if (expPos > -1) { + if (expPos < decPos) { + throw new NumberFormatException(str + " is not a valid number."); + } + dec = str.substring(decPos + 1, expPos); + } else { + dec = str.substring(decPos + 1); + } + mant = str.substring(0, decPos); + } else { + if (expPos > -1) { + mant = str.substring(0, expPos); + } else { + mant = str; + } + dec = null; + } + if (!Character.isDigit(lastChar)) { + if (expPos > -1 && expPos < str.length() - 1) { + exp = str.substring(expPos + 1, str.length() - 1); + } else { + exp = null; + } + //Requesting a specific type.. + String numeric = str.substring(0, str.length() - 1); + boolean allZeros = isAllZeros(mant) && isAllZeros(exp); + switch (lastChar) { + case 'l' : + case 'L' : + if (dec == null + && exp == null + && isDigits(numeric.substring(1)) + && (numeric.charAt(0) == '-' || Character.isDigit(numeric.charAt(0)))) { + try { + return createLong(numeric); + } catch (NumberFormatException nfe) { + //Too big for a long + } + return createBigInteger(numeric); + + } + throw new NumberFormatException(str + " is not a valid number."); + case 'f' : + case 'F' : + try { + Float f = NumberUtils.createFloat(numeric); + if (!(f.isInfinite() || (f.floatValue() == 0.0F && !allZeros))) { + //If it's too big for a float or the float value = 0 and the string + //has non-zeros in it, then float doens't have the presision we want + return f; + } + + } catch (NumberFormatException nfe) { + } + //Fall through + case 'd' : + case 'D' : + try { + Double d = NumberUtils.createDouble(numeric); + if (!(d.isInfinite() || (d.floatValue() == 0.0D && !allZeros))) { + return d; + } + } catch (NumberFormatException nfe) { + } + try { + return createBigDecimal(numeric); + } catch (NumberFormatException e) { + } + //Fall through + default : + throw new NumberFormatException(str + " is not a valid number."); + + } + } else { + //User doesn't have a preference on the return type, so let's start + //small and go from there... + if (expPos > -1 && expPos < str.length() - 1) { + exp = str.substring(expPos + 1, str.length()); + } else { + exp = null; + } + if (dec == null && exp == null) { + //Must be an int,long,bigint + try { + return createInteger(str); + } catch (NumberFormatException nfe) { + } + try { + return createLong(str); + } catch (NumberFormatException nfe) { + } + return createBigInteger(str); + + } else { + //Must be a float,double,BigDec + boolean allZeros = isAllZeros(mant) && isAllZeros(exp); + try { + Float f = createFloat(str); + if (!(f.isInfinite() || (f.floatValue() == 0.0F && !allZeros))) { + return f; + } + } catch (NumberFormatException nfe) { + } + try { + Double d = createDouble(str); + if (!(d.isInfinite() || (d.doubleValue() == 0.0D && !allZeros))) { + return d; + } + } catch (NumberFormatException nfe) { + } + + return createBigDecimal(str); + + } + } + } + + /** + *

Utility method for {@link #createNumber(java.lang.String)}.

+ * + *

Returns true if s is null.

+ * + * @param str the String to check + * @return if it is all zeros or null + */ + private static boolean isAllZeros(String str) { + if (str == null) { + return true; + } + for (int i = str.length() - 1; i >= 0; i--) { + if (str.charAt(i) != '0') { + return false; + } + } + return str.length() > 0; + } + + //----------------------------------------------------------------------- + /** + *

Convert a String to a Float.

+ * + *

Returns null if the string is null.

+ * + * @param str a String to convert, may be null + * @return converted Float + * @throws NumberFormatException if the value cannot be converted + */ + public static Float createFloat(String str) { + if (str == null) { + return null; + } + return Float.valueOf(str); + } + + /** + *

Convert a String to a Double.

+ * + *

Returns null if the string is null.

+ * + * @param str a String to convert, may be null + * @return converted Double + * @throws NumberFormatException if the value cannot be converted + */ + public static Double createDouble(String str) { + if (str == null) { + return null; + } + return Double.valueOf(str); + } + + /** + *

Convert a String to a Integer, handling + * hex and octal notations.

+ * + *

Returns null if the string is null.

+ * + * @param str a String to convert, may be null + * @return converted Integer + * @throws NumberFormatException if the value cannot be converted + */ + public static Integer createInteger(String str) { + if (str == null) { + return null; + } + // decode() handles 0xAABD and 0777 (hex and octal) as well. + return Integer.decode(str); + } + + /** + *

Convert a String to a Long.

+ * + *

Returns null if the string is null.

+ * + * @param str a String to convert, may be null + * @return converted Long + * @throws NumberFormatException if the value cannot be converted + */ + public static Long createLong(String str) { + if (str == null) { + return null; + } + return Long.valueOf(str); + } + + /** + *

Convert a String to a BigInteger.

+ * + *

Returns null if the string is null.

+ * + * @param str a String to convert, may be null + * @return converted BigInteger + * @throws NumberFormatException if the value cannot be converted + */ + public static BigInteger createBigInteger(String str) { + if (str == null) { + return null; + } + return new BigInteger(str); + } + + /** + *

Convert a String to a BigDecimal.

+ * + *

Returns null if the string is null.

+ * + * @param str a String to convert, may be null + * @return converted BigDecimal + * @throws NumberFormatException if the value cannot be converted + */ + public static BigDecimal createBigDecimal(String str) { + if (str == null) { + return null; + } + // handle JDK1.3.1 bug where "" throws IndexOutOfBoundsException + if (StringUtils.isBlank(str)) { + throw new NumberFormatException("A blank string is not a valid number"); + } + return new BigDecimal(str); + } + + // Min in array + //-------------------------------------------------------------------- + /** + *

Returns the minimum value in an array.

+ * + * @param array an array, must not be null or empty + * @return the minimum value in the array + * @throws IllegalArgumentException if array is null + * @throws IllegalArgumentException if array is empty + */ + public static long min(long[] array) { + // Validates input + if (array == null) { + throw new IllegalArgumentException("The Array must not be null"); + } else if (array.length == 0) { + throw new IllegalArgumentException("Array cannot be empty."); + } + + // Finds and returns min + long min = array[0]; + for (int i = 1; i < array.length; i++) { + if (array[i] < min) { + min = array[i]; + } + } + + return min; + } + + /** + *

Returns the minimum value in an array.

+ * + * @param array an array, must not be null or empty + * @return the minimum value in the array + * @throws IllegalArgumentException if array is null + * @throws IllegalArgumentException if array is empty + */ + public static int min(int[] array) { + // Validates input + if (array == null) { + throw new IllegalArgumentException("The Array must not be null"); + } else if (array.length == 0) { + throw new IllegalArgumentException("Array cannot be empty."); + } + + // Finds and returns min + int min = array[0]; + for (int j = 1; j < array.length; j++) { + if (array[j] < min) { + min = array[j]; + } + } + + return min; + } + + /** + *

Returns the minimum value in an array.

+ * + * @param array an array, must not be null or empty + * @return the minimum value in the array + * @throws IllegalArgumentException if array is null + * @throws IllegalArgumentException if array is empty + */ + public static short min(short[] array) { + // Validates input + if (array == null) { + throw new IllegalArgumentException("The Array must not be null"); + } else if (array.length == 0) { + throw new IllegalArgumentException("Array cannot be empty."); + } + + // Finds and returns min + short min = array[0]; + for (int i = 1; i < array.length; i++) { + if (array[i] < min) { + min = array[i]; + } + } + + return min; + } + + /** + *

Returns the minimum value in an array.

+ * + * @param array an array, must not be null or empty + * @return the minimum value in the array + * @throws IllegalArgumentException if array is null + * @throws IllegalArgumentException if array is empty + */ + public static double min(double[] array) { + // Validates input + if (array == null) { + throw new IllegalArgumentException("The Array must not be null"); + } else if (array.length == 0) { + throw new IllegalArgumentException("Array cannot be empty."); + } + + // Finds and returns min + double min = array[0]; + for (int i = 1; i < array.length; i++) { + if (array[i] < min) { + min = array[i]; + } + } + + return min; + } + + /** + *

Returns the minimum value in an array.

+ * + * @param array an array, must not be null or empty + * @return the minimum value in the array + * @throws IllegalArgumentException if array is null + * @throws IllegalArgumentException if array is empty + */ + public static float min(float[] array) { + // Validates input + if (array == null) { + throw new IllegalArgumentException("The Array must not be null"); + } else if (array.length == 0) { + throw new IllegalArgumentException("Array cannot be empty."); + } + + // Finds and returns min + float min = array[0]; + for (int i = 1; i < array.length; i++) { + if (array[i] < min) { + min = array[i]; + } + } + + return min; + } + + // Max in array + //-------------------------------------------------------------------- + /** + *

Returns the maximum value in an array.

+ * + * @param array an array, must not be null or empty + * @return the minimum value in the array + * @throws IllegalArgumentException if array is null + * @throws IllegalArgumentException if array is empty + */ + public static long max(long[] array) { + // Validates input + if (array == null) { + throw new IllegalArgumentException("The Array must not be null"); + } else if (array.length == 0) { + throw new IllegalArgumentException("Array cannot be empty."); + } + + // Finds and returns max + long max = array[0]; + for (int j = 1; j < array.length; j++) { + if (array[j] > max) { + max = array[j]; + } + } + + return max; + } + + /** + *

Returns the maximum value in an array.

+ * + * @param array an array, must not be null or empty + * @return the minimum value in the array + * @throws IllegalArgumentException if array is null + * @throws IllegalArgumentException if array is empty + */ + public static int max(int[] array) { + // Validates input + if (array == null) { + throw new IllegalArgumentException("The Array must not be null"); + } else if (array.length == 0) { + throw new IllegalArgumentException("Array cannot be empty."); + } + + // Finds and returns max + int max = array[0]; + for (int j = 1; j < array.length; j++) { + if (array[j] > max) { + max = array[j]; + } + } + + return max; + } + + /** + *

Returns the maximum value in an array.

+ * + * @param array an array, must not be null or empty + * @return the minimum value in the array + * @throws IllegalArgumentException if array is null + * @throws IllegalArgumentException if array is empty + */ + public static short max(short[] array) { + // Validates input + if (array == null) { + throw new IllegalArgumentException("The Array must not be null"); + } else if (array.length == 0) { + throw new IllegalArgumentException("Array cannot be empty."); + } + + // Finds and returns max + short max = array[0]; + for (int i = 1; i < array.length; i++) { + if (array[i] > max) { + max = array[i]; + } + } + + return max; + } + + /** + *

Returns the maximum value in an array.

+ * + * @param array an array, must not be null or empty + * @return the minimum value in the array + * @throws IllegalArgumentException if array is null + * @throws IllegalArgumentException if array is empty + */ + public static double max(double[] array) { + // Validates input + if (array== null) { + throw new IllegalArgumentException("The Array must not be null"); + } else if (array.length == 0) { + throw new IllegalArgumentException("Array cannot be empty."); + } + + // Finds and returns max + double max = array[0]; + for (int j = 1; j < array.length; j++) { + if (array[j] > max) { + max = array[j]; + } + } + + return max; + } + + /** + *

Returns the maximum value in an array.

+ * + * @param array an array, must not be null or empty + * @return the minimum value in the array + * @throws IllegalArgumentException if array is null + * @throws IllegalArgumentException if array is empty + */ + public static float max(float[] array) { + // Validates input + if (array == null) { + throw new IllegalArgumentException("The Array must not be null"); + } else if (array.length == 0) { + throw new IllegalArgumentException("Array cannot be empty."); + } + + // Finds and returns max + float max = array[0]; + for (int j = 1; j < array.length; j++) { + if (array[j] > max) { + max = array[j]; + } + } + + return max; + } + + // 3 param min + //----------------------------------------------------------------------- + /** + *

Gets the minimum of three long values.

+ * + * @param a value 1 + * @param b value 2 + * @param c value 3 + * @return the smallest of the values + */ + public static long min(long a, long b, long c) { + if (b < a) { + a = b; + } + if (c < a) { + a = c; + } + return a; + } + + /** + *

Gets the minimum of three int values.

+ * + * @param a value 1 + * @param b value 2 + * @param c value 3 + * @return the smallest of the values + */ + public static int min(int a, int b, int c) { + if (b < a) { + a = b; + } + if (c < a) { + a = c; + } + return a; + } + + /** + *

Gets the minimum of three short values.

+ * + * @param a value 1 + * @param b value 2 + * @param c value 3 + * @return the smallest of the values + */ + public static short min(short a, short b, short c) { + if (b < a) { + a = b; + } + if (c < a) { + a = c; + } + return a; + } + + /** + *

Gets the minimum of three byte values.

+ * + * @param a value 1 + * @param b value 2 + * @param c value 3 + * @return the smallest of the values + */ + public static byte min(byte a, byte b, byte c) { + if (b < a) { + a = b; + } + if (c < a) { + a = c; + } + return a; + } + + /** + *

Gets the minimum of three double values.

+ * + *

If any value is NaN, NaN is + * returned. Infinity is handled.

+ * + * @param a value 1 + * @param b value 2 + * @param c value 3 + * @return the smallest of the values + */ + public static double min(double a, double b, double c) { + return Math.min(Math.min(a, b), c); + } + + /** + *

Gets the minimum of three float values.

+ * + *

If any value is NaN, NaN is + * returned. Infinity is handled.

+ * + * @param a value 1 + * @param b value 2 + * @param c value 3 + * @return the smallest of the values + */ + public static float min(float a, float b, float c) { + return Math.min(Math.min(a, b), c); + } + + // 3 param max + //----------------------------------------------------------------------- + /** + *

Gets the maximum of three long values.

+ * + * @param a value 1 + * @param b value 2 + * @param c value 3 + * @return the largest of the values + */ + public static long max(long a, long b, long c) { + if (b > a) { + a = b; + } + if (c > a) { + a = c; + } + return a; + } + + /** + *

Gets the maximum of three int values.

+ * + * @param a value 1 + * @param b value 2 + * @param c value 3 + * @return the largest of the values + */ + public static int max(int a, int b, int c) { + if (b > a) { + a = b; + } + if (c > a) { + a = c; + } + return a; + } + + /** + *

Gets the maximum of three short values.

+ * + * @param a value 1 + * @param b value 2 + * @param c value 3 + * @return the largest of the values + */ + public static short max(short a, short b, short c) { + if (b > a) { + a = b; + } + if (c > a) { + a = c; + } + return a; + } + + /** + *

Gets the maximum of three byte values.

+ * + * @param a value 1 + * @param b value 2 + * @param c value 3 + * @return the largest of the values + */ + public static byte max(byte a, byte b, byte c) { + if (b > a) { + a = b; + } + if (c > a) { + a = c; + } + return a; + } + + /** + *

Gets the maximum of three double values.

+ * + *

If any value is NaN, NaN is + * returned. Infinity is handled.

+ * + * @param a value 1 + * @param b value 2 + * @param c value 3 + * @return the largest of the values + */ + public static double max(double a, double b, double c) { + return Math.max(Math.max(a, b), c); + } + + /** + *

Gets the maximum of three float values.

+ * + *

If any value is NaN, NaN is + * returned. Infinity is handled.

+ * + * @param a value 1 + * @param b value 2 + * @param c value 3 + * @return the largest of the values + */ + public static float max(float a, float b, float c) { + return Math.max(Math.max(a, b), c); + } + + //----------------------------------------------------------------------- + /** + *

Compares two doubles for order.

+ * + *

This method is more comprehensive than the standard Java greater + * than, less than and equals operators.

+ *
    + *
  • It returns -1 if the first value is less than the second.
  • + *
  • It returns +1 if the first value is greater than the second.
  • + *
  • It returns 0 if the values are equal.
  • + *
+ * + *

+ * The ordering is as follows, largest to smallest: + *

    + *
  • NaN + *
  • Positive infinity + *
  • Maximum double + *
  • Normal positve numbers + *
  • +0.0 + *
  • -0.0 + *
  • Normal negative numbers + *
  • Minimum double (-Double.MAX_VALUE) + *
  • Negative infinity + *
+ *

+ * + *

Comparing NaN with NaN will + * return 0.

+ * + * @param lhs the first double + * @param rhs the second double + * @return -1 if lhs is less, +1 if greater, + * 0 if equal to rhs + */ + public static int compare(double lhs, double rhs) { + if (lhs < rhs) { + return -1; + } + if (lhs > rhs) { + return +1; + } + // Need to compare bits to handle 0.0 == -0.0 being true + // compare should put -0.0 < +0.0 + // Two NaNs are also == for compare purposes + // where NaN == NaN is false + long lhsBits = Double.doubleToLongBits(lhs); + long rhsBits = Double.doubleToLongBits(rhs); + if (lhsBits == rhsBits) { + return 0; + } + // Something exotic! A comparison to NaN or 0.0 vs -0.0 + // Fortunately NaN's long is > than everything else + // Also negzeros bits < poszero + // NAN: 9221120237041090560 + // MAX: 9218868437227405311 + // NEGZERO: -9223372036854775808 + if (lhsBits < rhsBits) { + return -1; + } else { + return +1; + } + } + + /** + *

Compares two floats for order.

+ * + *

This method is more comprhensive than the standard Java greater than, + * less than and equals operators.

+ *
    + *
  • It returns -1 if the first value is less than the second. + *
  • It returns +1 if the first value is greater than the second. + *
  • It returns 0 if the values are equal. + *
+ * + *

The ordering is as follows, largest to smallest: + *

    + *
  • NaN + *
  • Positive infinity + *
  • Maximum float + *
  • Normal positve numbers + *
  • +0.0 + *
  • -0.0 + *
  • Normal negative numbers + *
  • Minimum float (-Float.MAX_VALUE) + *
  • Negative infinity + *
+ * + *

Comparing NaN with NaN will return + * 0.

+ * + * @param lhs the first float + * @param rhs the second float + * @return -1 if lhs is less, +1 if greater, + * 0 if equal to rhs + */ + public static int compare(float lhs, float rhs) { + if (lhs < rhs) { + return -1; + } + if (lhs > rhs) { + return +1; + } + //Need to compare bits to handle 0.0 == -0.0 being true + // compare should put -0.0 < +0.0 + // Two NaNs are also == for compare purposes + // where NaN == NaN is false + int lhsBits = Float.floatToIntBits(lhs); + int rhsBits = Float.floatToIntBits(rhs); + if (lhsBits == rhsBits) { + return 0; + } + //Something exotic! A comparison to NaN or 0.0 vs -0.0 + //Fortunately NaN's int is > than everything else + //Also negzeros bits < poszero + //NAN: 2143289344 + //MAX: 2139095039 + //NEGZERO: -2147483648 + if (lhsBits < rhsBits) { + return -1; + } else { + return +1; + } + } + + //----------------------------------------------------------------------- + /** + *

Checks whether the String contains only + * digit characters.

+ * + *

Null and empty String will return + * false.

+ * + * @param str the String to check + * @return true if str contains only unicode numeric + */ + public static boolean isDigits(String str) { + if ((str == null) || (str.length() == 0)) { + return false; + } + for (int i = 0; i < str.length(); i++) { + if (!Character.isDigit(str.charAt(i))) { + return false; + } + } + return true; + } + + /** + *

Checks whether the String a valid Java number.

+ * + *

Valid numbers include hexadecimal marked with the 0x + * qualifier, scientific notation and numbers marked with a type + * qualifier (e.g. 123L).

+ * + *

Null and empty String will return + * false.

+ * + * @param str the String to check + * @return true if the string is a correctly formatted number + */ + public static boolean isNumber(String str) { + if ((str == null) || (str.length() == 0)) { + return false; + } + char[] chars = str.toCharArray(); + int sz = chars.length; + boolean hasExp = false; + boolean hasDecPoint = false; + boolean allowSigns = false; + boolean foundDigit = false; + // deal with any possible sign up front + int start = (chars[0] == '-') ? 1 : 0; + if (sz > start + 1) { + if (chars[start] == '0' && chars[start + 1] == 'x') { + int i = start + 2; + if (i == sz) { + return false; // str == "0x" + } + // checking hex (it can't be anything else) + for (; i < chars.length; i++) { + if ((chars[i] < '0' || chars[i] > '9') + && (chars[i] < 'a' || chars[i] > 'f') + && (chars[i] < 'A' || chars[i] > 'F')) { + return false; + } + } + return true; + } + } + sz--; // don't want to loop to the last char, check it afterwords + // for type qualifiers + int i = start; + // loop to the next to last char or to the last char if we need another digit to + // make a valid number (e.g. chars[0..5] = "1234E") + while (i < sz || (i < sz + 1 && allowSigns && !foundDigit)) { + if (chars[i] >= '0' && chars[i] <= '9') { + foundDigit = true; + allowSigns = false; + + } else if (chars[i] == '.') { + if (hasDecPoint || hasExp) { + // two decimal points or dec in exponent + return false; + } + hasDecPoint = true; + } else if (chars[i] == 'e' || chars[i] == 'E') { + // we've already taken care of hex. + if (hasExp) { + // two E's + return false; + } + if (!foundDigit) { + return false; + } + hasExp = true; + allowSigns = true; + } else if (chars[i] == '+' || chars[i] == '-') { + if (!allowSigns) { + return false; + } + allowSigns = false; + foundDigit = false; // we need a digit after the E + } else { + return false; + } + i++; + } + if (i < chars.length) { + if (chars[i] >= '0' && chars[i] <= '9') { + // no type qualifier, OK + return true; + } + if (chars[i] == 'e' || chars[i] == 'E') { + // can't have an E at the last byte + return false; + } + if (!allowSigns + && (chars[i] == 'd' + || chars[i] == 'D' + || chars[i] == 'f' + || chars[i] == 'F')) { + return foundDigit; + } + if (chars[i] == 'l' + || chars[i] == 'L') { + // not allowing L with an exponoent + return foundDigit && !hasExp; + } + // last character is illegal + return false; + } + // allowSigns is true iff the val ends in 'E' + // found digit it to make sure weird stuff like '.' and '1E-' doesn't pass + return !allowSigns && foundDigit; + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/math/RandomUtils.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/math/RandomUtils.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/math/RandomUtils.java 30 Aug 2012 16:24:43 -0000 1.1 @@ -0,0 +1,153 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.math; + +import java.util.Random; + +/** + *

RandomUtils is a wrapper that supports all possible + * {@link java.util.Random} methods via the {@link java.lang.Math#random()} + * method and its system-wide Random object. + * + * @author Henri Yandell + * @since 2.0 + * @version $Id: RandomUtils.java,v 1.1 2012/08/30 16:24:43 marcin Exp $ + */ +public class RandomUtils { + + public static final Random JVM_RANDOM = new JVMRandom(); + +// should be possible for JVM_RANDOM? +// public static void nextBytes(byte[]) { +// public synchronized double nextGaussian(); +// } + + /** + *

Returns the next pseudorandom, uniformly distributed int value + * from the Math.random() sequence.

+ * + * @return the random int + */ + public static int nextInt() { + return nextInt(JVM_RANDOM); + } + public static int nextInt(Random rnd) { + return rnd.nextInt(); + } + /** + *

Returns a pseudorandom, uniformly distributed int value + * between 0 (inclusive) and the specified value + * (exclusive), from the Math.random() sequence.

+ * + * @param n the specified exclusive max-value + * + * @return the random int + */ + public static int nextInt(int n) { + return nextInt(JVM_RANDOM, n); + } + public static int nextInt(Random rnd, int n) { + // check this cannot return 'n' + return rnd.nextInt(n); + } + /** + *

Returns the next pseudorandom, uniformly distributed long value + * from the Math.random() sequence.

+ * + * @return the random long + */ + public static long nextLong() { + return nextLong(JVM_RANDOM); + } + public static long nextLong(Random rnd) { + return rnd.nextLong(); + } + /** + *

Returns the next pseudorandom, uniformly distributed boolean value + * from the Math.random() sequence.

+ * + * @return the random boolean + */ + public static boolean nextBoolean() { + return nextBoolean(JVM_RANDOM); + } + public static boolean nextBoolean(Random rnd) { + return rnd.nextBoolean(); + } + /** + *

Returns the next pseudorandom, uniformly distributed float value + * between 0.0 and 1.0 from the Math.random() + * sequence.

+ * + * @return the random float + */ + public static float nextFloat() { + return nextFloat(JVM_RANDOM); + } + public static float nextFloat(Random rnd) { + return rnd.nextFloat(); + } + /** + *

Synonymous to the Math.random() call.

+ * + * @return the random double + */ + public static double nextDouble() { + return nextDouble(JVM_RANDOM); + } + public static double nextDouble(Random rnd) { + return rnd.nextDouble(); + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/math/Range.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/math/Range.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/math/Range.java 30 Aug 2012 16:24:43 -0000 1.1 @@ -0,0 +1,468 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.math; + +/** + *

Range represents a range of numbers of the same type.

+ * + *

Specific subclasses hold the range values as different types. Each + * subclass should be immutable and {@link java.io.Serializable Serializable} + * if possible.

+ * + * @author Stephen Colebourne + * @since 2.0 + * @version $Id: Range.java,v 1.1 2012/08/30 16:24:43 marcin Exp $ + */ +public abstract class Range { + + /** + *

Constructs a new range.

+ */ + public Range() { + super(); + } + + // Accessors + //-------------------------------------------------------------------- + + /** + *

Gets the minimum number in this range.

+ * + * @return the minimum number in this range + */ + public abstract Number getMinimumNumber(); + + /** + *

Gets the minimum number in this range as a long.

+ * + *

This implementation uses the {@link #getMinimumNumber()} method. + * Subclasses may be able to optimise this.

+ * + * @return the minimum number in this range + */ + public long getMinimumLong() { + return getMinimumNumber().longValue(); + } + + /** + *

Gets the minimum number in this range as a int.

+ * + *

This implementation uses the {@link #getMinimumNumber()} method. + * Subclasses may be able to optimise this.

+ * + * @return the minimum number in this range + */ + public int getMinimumInteger() { + return getMinimumNumber().intValue(); + } + + /** + *

Gets the minimum number in this range as a double.

+ * + *

This implementation uses the {@link #getMinimumNumber()} method. + * Subclasses may be able to optimise this.

+ * + * @return the minimum number in this range + */ + public double getMinimumDouble() { + return getMinimumNumber().doubleValue(); + } + + /** + *

Gets the minimum number in this range as a float.

+ * + *

This implementation uses the {@link #getMinimumNumber()} method. + * Subclasses may be able to optimise this.

+ * + * @return the minimum number in this range + */ + public float getMinimumFloat() { + return getMinimumNumber().floatValue(); + } + + /** + *

Gets the maximum number in this range.

+ * + * @return the maximum number in this range + */ + public abstract Number getMaximumNumber(); + + /** + *

Gets the maximum number in this range as a long.

+ * + *

This implementation uses the {@link #getMaximumNumber()} method. + * Subclasses may be able to optimise this.

+ * + * @return the maximum number in this range + */ + public long getMaximumLong() { + return getMaximumNumber().longValue(); + } + + /** + *

Gets the maximum number in this range as a int.

+ * + *

This implementation uses the {@link #getMaximumNumber()} method. + * Subclasses may be able to optimise this.

+ * + * @return the maximum number in this range + */ + public int getMaximumInteger() { + return getMaximumNumber().intValue(); + } + + /** + *

Gets the maximum number in this range as a double.

+ * + *

This implementation uses the {@link #getMaximumNumber()} method. + * Subclasses may be able to optimise this.

+ * + * @return the maximum number in this range + */ + public double getMaximumDouble() { + return getMaximumNumber().doubleValue(); + } + + /** + *

Gets the maximum number in this range as a float.

+ * + *

This implementation uses the {@link #getMaximumNumber()} method. + * Subclasses may be able to optimise this.

+ * + * @return the maximum number in this range + */ + public float getMaximumFloat() { + return getMaximumNumber().floatValue(); + } + + // Include tests + //-------------------------------------------------------------------- + + /** + *

Tests whether the specified Number occurs within + * this range.

+ * + *

The exact comparison implementation varies by subclass. It is + * intended that an int specific subclass will compare using + * int comparison.

+ * + *

null is handled and returns false.

+ * + * @param number the number to test, may be null + * @return true if the specified number occurs within this range + * @throws IllegalArgumentException if the Number cannot be compared + */ + public abstract boolean containsNumber(Number number); + + /** + *

Tests whether the specified Number occurs within + * this range using long comparison..

+ * + *

null is handled and returns false.

+ * + *

This implementation forwards to the {@link #containsLong(long)} method.

+ * + * @param value the long to test, may be null + * @return true if the specified number occurs within this + * range by long comparison + */ + public boolean containsLong(Number value) { + if (value == null) { + return false; + } + return containsLong(value.longValue()); + } + + /** + *

Tests whether the specified long occurs within + * this range using long comparison.

+ * + *

This implementation uses the {@link #getMinimumLong()} and + * {@link #getMaximumLong()} methods and should be good for most uses.

+ * + * @param value the long to test + * @return true if the specified number occurs within this + * range by long comparison + */ + public boolean containsLong(long value) { + return (value >= getMinimumLong() && value <= getMaximumLong()); + } + + /** + *

Tests whether the specified Number occurs within + * this range using int comparison..

+ * + *

null is handled and returns false.

+ * + *

This implementation forwards to the {@link #containsInteger(int)} method.

+ * + * @param value the integer to test, may be null + * @return true if the specified number occurs within this + * range by int comparison + */ + public boolean containsInteger(Number value) { + if (value == null) { + return false; + } + return containsInteger(value.intValue()); + } + + /** + *

Tests whether the specified int occurs within + * this range using int comparison.

+ * + *

This implementation uses the {@link #getMinimumInteger()} and + * {@link #getMaximumInteger()} methods and should be good for most uses.

+ * + * @param value the int to test + * @return true if the specified number occurs within this + * range by int comparison + */ + public boolean containsInteger(int value) { + return (value >= getMinimumInteger() && value <= getMaximumInteger()); + } + + /** + *

Tests whether the specified Number occurs within + * this range using double comparison..

+ * + *

null is handled and returns false.

+ * + *

This implementation forwards to the {@link #containsDouble(double)} method.

+ * + * @param value the double to test, may be null + * @return true if the specified number occurs within this + * range by double comparison + */ + public boolean containsDouble(Number value) { + if (value == null) { + return false; + } + return containsDouble(value.doubleValue()); + } + + /** + *

Tests whether the specified double occurs within + * this range using double comparison.

+ * + *

This implementation uses the {@link #getMinimumDouble()} and + * {@link #getMaximumDouble()} methods and should be good for most uses.

+ * + * @param value the double to test + * @return true if the specified number occurs within this + * range by double comparison + */ + public boolean containsDouble(double value) { + int compareMin = NumberUtils.compare(getMinimumDouble(), value); + int compareMax = NumberUtils.compare(getMaximumDouble(), value); + return (compareMin <= 0 && compareMax >= 0); + } + + /** + *

Tests whether the specified Number occurs within + * this range using float comparison.

+ * + *

null is handled and returns false.

+ * + *

This implementation forwards to the {@link #containsFloat(float)} method.

+ * + * @param value the float to test, may be null + * @return true if the specified number occurs within this + * range by float comparison + */ + public boolean containsFloat(Number value) { + if (value == null) { + return false; + } + return containsFloat(value.floatValue()); + } + + /** + *

Tests whether the specified float occurs within + * this range using float comparison.

+ * + *

This implementation uses the {@link #getMinimumFloat()} and + * {@link #getMaximumFloat()} methods and should be good for most uses.

+ * + * @param value the float to test + * @return true if the specified number occurs within this + * range by float comparison + */ + public boolean containsFloat(float value) { + int compareMin = NumberUtils.compare(getMinimumFloat(), value); + int compareMax = NumberUtils.compare(getMaximumFloat(), value); + return (compareMin <= 0 && compareMax >= 0); + } + + // Range tests + //-------------------------------------------------------------------- + + /** + *

Tests whether the specified range occurs entirely within this range.

+ * + *

The exact comparison implementation varies by subclass. It is + * intended that an int specific subclass will compare using + * int comparison.

+ * + *

null is handled and returns false.

+ * + *

This implementation uses the {@link #containsNumber(Number)} method. + * Subclasses may be able to optimise this.

+ * + * @param range the range to test, may be null + * @return true if the specified range occurs entirely within + * this range; otherwise, false + * @throws IllegalArgumentException if the Range cannot be compared + */ + public boolean containsRange(Range range) { + if (range == null) { + return false; + } + return containsNumber(range.getMinimumNumber()) + && containsNumber(range.getMaximumNumber()); + } + + /** + *

Tests whether the specified range overlaps with this range.

+ * + *

The exact comparison implementation varies by subclass. It is + * intended that an int specific subclass will compare using + * int comparison.

+ * + *

null is handled and returns false.

+ * + *

This implementation uses the {@link #containsNumber(Number)} and + * {@link #containsRange(Range)} methods. + * Subclasses may be able to optimise this.

+ * + * @param range the range to test, may be null + * @return true if the specified range overlaps with this + * range; otherwise, false + * @throws IllegalArgumentException if the Range cannot be compared + */ + public boolean overlapsRange(Range range) { + if (range == null) { + return false; + } + return range.containsNumber(getMinimumNumber()) + || range.containsNumber(getMaximumNumber()) + || containsNumber(range.getMinimumNumber()); + } + + // Basics + //-------------------------------------------------------------------- + + /** + *

Compares this range to another object to test if they are equal.

. + * + *

To be equal, the class, minimum and maximum must be equal.

+ * + *

This implementation uses the {@link #getMinimumNumber()} and + * {@link #getMaximumNumber()} methods. + * Subclasses may be able to optimise this.

+ * + * @param obj the reference object with which to compare + * @return true if this object is equal + */ + public boolean equals(Object obj) { + if (obj == this) { + return true; + } else if (obj == null || obj.getClass() != getClass()) { + return false; + } else { + Range range = (Range) obj; + return getMinimumNumber().equals(range.getMinimumNumber()) && + getMaximumNumber().equals(range.getMaximumNumber()); + } + } + + /** + *

Gets a hashCode for the range.

+ * + *

This implementation uses the {@link #getMinimumNumber()} and + * {@link #getMaximumNumber()} methods. + * Subclasses may be able to optimise this.

+ * + * @return a hash code value for this object + */ + public int hashCode() { + int result = 17; + result = 37 * result + getClass().hashCode(); + result = 37 * result + getMinimumNumber().hashCode(); + result = 37 * result + getMaximumNumber().hashCode(); + return result; + } + + /** + *

Gets the range as a String.

+ * + *

The format of the String is 'Range[min,max]'.

+ * + *

This implementation uses the {@link #getMinimumNumber()} and + * {@link #getMaximumNumber()} methods. + * Subclasses may be able to optimise this.

+ * + * @return the String representation of this range + */ + public String toString() { + StringBuffer buf = new StringBuffer(32); + buf.append("Range["); + buf.append(getMinimumNumber()); + buf.append(','); + buf.append(getMaximumNumber()); + buf.append(']'); + return buf.toString(); + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/math/package.html =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/math/package.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/math/package.html 30 Aug 2012 16:24:43 -0000 1.1 @@ -0,0 +1,7 @@ + + +Extends java.math for business mathematical classes. This package is intended for business +mathematical classes, not scientific ones. +@since 2.0 + + Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/time/DateFormatUtils.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/time/DateFormatUtils.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/time/DateFormatUtils.java 30 Aug 2012 16:24:43 -0000 1.1 @@ -0,0 +1,298 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.time; + +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +/** + *

Date and time formatting utilites and constants.

+ * + *

Formatting is performed using the + * {@link org.apache.commons.lang.time.FastDateFormat} class.

+ * + * @author Apache Ant - DateUtils + * @author Stephane Bailliez + * @author Stefan Bodewig + * @author Stephen Colebourne + * @author Gary Gregory + * @since 2.0 + * @version $Id: DateFormatUtils.java,v 1.1 2012/08/30 16:24:43 marcin Exp $ + */ +public class DateFormatUtils { + + /** + * ISO8601 formatter for date-time witout time zone. + * The format used is yyyy-MM-dd'T'HH:mm:ss. + */ + public static final FastDateFormat ISO_DATETIME_FORMAT + = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss"); + + /** + * ISO8601 formatter for date-time with time zone. + * The format used is yyyy-MM-dd'T'HH:mm:ssZZ. + */ + public static final FastDateFormat ISO_DATETIME_TIME_ZONE_FORMAT + = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ssZZ"); + + /** + * ISO8601 formatter for date without time zone. + * The format used is yyyy-MM-dd. + */ + public static final FastDateFormat ISO_DATE_FORMAT + = FastDateFormat.getInstance("yyyy-MM-dd"); + + /** + * ISO8601-like formatter for date with time zone. + * The format used is yyyy-MM-ddZZ. + * This pattern does not comply with the formal ISO8601 specification + * as the standard does not allow a time zone without a time. + */ + public static final FastDateFormat ISO_DATE_TIME_ZONE_FORMAT + = FastDateFormat.getInstance("yyyy-MM-ddZZ"); + + /** + * ISO8601 formatter for time without time zone. + * The format used is 'T'HH:mm:ss. + */ + public static final FastDateFormat ISO_TIME_FORMAT + = FastDateFormat.getInstance("'T'HH:mm:ss"); + + /** + * ISO8601 formatter for time with time zone. + * The format used is 'T'HH:mm:ssZZ. + */ + public static final FastDateFormat ISO_TIME_TIME_ZONE_FORMAT + = FastDateFormat.getInstance("'T'HH:mm:ssZZ"); + + /** + * ISO8601-like formatter for time without time zone. + * The format used is HH:mm:ss. + * This pattern does not comply with the formal ISO8601 specification + * as the standard requires the 'T' prefix for times. + */ + public static final FastDateFormat ISO_TIME_NO_T_FORMAT + = FastDateFormat.getInstance("HH:mm:ss"); + + /** + * ISO8601-like formatter for time with time zone. + * The format used is HH:mm:ssZZ. + * This pattern does not comply with the formal ISO8601 specification + * as the standard requires the 'T' prefix for times. + */ + public static final FastDateFormat ISO_TIME_NO_T_TIME_ZONE_FORMAT + = FastDateFormat.getInstance("HH:mm:ssZZ"); + + /** + * SMTP (and probably other) date headers. + * The format used is EEE, dd MMM yyyy HH:mm:ss Z in US locale. + */ + public static final FastDateFormat SMTP_DATETIME_FORMAT + = FastDateFormat.getInstance("EEE, dd MMM yyyy HH:mm:ss Z", Locale.US); + + //----------------------------------------------------------------------- + /** + *

DateFormatUtils instances should NOT be constructed in standard programming.

+ * + *

This constructor is public to permit tools that require a JavaBean instance + * to operate.

+ */ + public DateFormatUtils() { + } + + /** + *

Format a date/time into a specific pattern using the UTC time zone.

+ * + * @param millis the date to format expressed in milliseconds + * @param pattern the pattern to use to format the date + * @return the formatted date + */ + public static String formatUTC(long millis, String pattern) { + return format(new Date(millis), pattern, DateUtils.UTC_TIME_ZONE, null); + } + + /** + *

Format a date/time into a specific pattern using the UTC time zone.

+ * + * @param date the date to format + * @param pattern the pattern to use to format the date + * @return the formatted date + */ + public static String formatUTC(Date date, String pattern) { + return format(date, pattern, DateUtils.UTC_TIME_ZONE, null); + } + + /** + *

Format a date/time into a specific pattern using the UTC time zone.

+ * + * @param millis the date to format expressed in milliseconds + * @param pattern the pattern to use to format the date + * @param locale the locale to use, may be null + * @return the formatted date + */ + public static String formatUTC(long millis, String pattern, Locale locale) { + return format(new Date(millis), pattern, DateUtils.UTC_TIME_ZONE, locale); + } + + /** + *

Format a date/time into a specific pattern using the UTC time zone.

+ * + * @param date the date to format + * @param pattern the pattern to use to format the date + * @param locale the locale to use, may be null + * @return the formatted date + */ + public static String formatUTC(Date date, String pattern, Locale locale) { + return format(date, pattern, DateUtils.UTC_TIME_ZONE, locale); + } + + /** + *

Format a date/time into a specific pattern.

+ * + * @param millis the date to format expressed in milliseconds + * @param pattern the pattern to use to format the date + * @return the formatted date + */ + public static String format(long millis, String pattern) { + return format(new Date(millis), pattern, null, null); + } + + /** + *

Format a date/time into a specific pattern.

+ * + * @param date the date to format + * @param pattern the pattern to use to format the date + * @return the formatted date + */ + public static String format(Date date, String pattern) { + return format(date, pattern, null, null); + } + + /** + *

Format a date/time into a specific pattern in a time zone.

+ * + * @param millis the time expressed in milliseconds + * @param pattern the pattern to use to format the date + * @param timeZone the time zone to use, may be null + * @return the formatted date + */ + public static String format(long millis, String pattern, TimeZone timeZone) { + return format(new Date(millis), pattern, timeZone, null); + } + + /** + *

Format a date/time into a specific pattern in a time zone.

+ * + * @param date the date to format + * @param pattern the pattern to use to format the date + * @param timeZone the time zone to use, may be null + * @return the formatted date + */ + public static String format(Date date, String pattern, TimeZone timeZone) { + return format(date, pattern, timeZone, null); + } + + /** + *

Format a date/time into a specific pattern in a locale.

+ * + * @param millis the date to format expressed in milliseconds + * @param pattern the pattern to use to format the date + * @param locale the locale to use, may be null + * @return the formatted date + */ + public static String format(long millis, String pattern, Locale locale) { + return format(new Date(millis), pattern, null, locale); + } + + /** + *

Format a date/time into a specific pattern in a locale.

+ * + * @param date the date to format + * @param pattern the pattern to use to format the date + * @param locale the locale to use, may be null + * @return the formatted date + */ + public static String format(Date date, String pattern, Locale locale) { + return format(date, pattern, null, locale); + } + + /** + *

Format a date/time into a specific pattern in a time zone and locale.

+ * + * @param millis the date to format expressed in milliseconds + * @param pattern the pattern to use to format the date + * @param timeZone the time zone to use, may be null + * @param locale the locale to use, may be null + * @return the formatted date + */ + public static String format(long millis, String pattern, TimeZone timeZone, Locale locale) { + return format(new Date(millis), pattern, timeZone, locale); + } + + /** + *

Format a date/time into a specific pattern in a time zone and locale.

+ * + * @param date the date to format + * @param pattern the pattern to use to format the date + * @param timeZone the time zone to use, may be null + * @param locale the locale to use, may be null + * @return the formatted date + */ + public static String format(Date date, String pattern, TimeZone timeZone, Locale locale) { + FastDateFormat df = FastDateFormat.getInstance(pattern, timeZone, locale); + return df.format(date); + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/time/DateUtils.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/time/DateUtils.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/time/DateUtils.java 30 Aug 2012 16:24:43 -0000 1.1 @@ -0,0 +1,704 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.time; + +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.TimeZone; + +/** + *

A suite of utilities surrounding the use of the + * {@link java.util.Calendar} and {@link java.util.Date} object.

+ * + * @author Serge Knystautas + * @author Stephen Colebourne + * @author Janek Bogucki + * @author Gary Gregory + * @since 2.0 + * @version $Id: DateUtils.java,v 1.1 2012/08/30 16:24:43 marcin Exp $ + */ +public class DateUtils { + + /** + * The UTC time zone (often referred to as GMT). + */ + public static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone("GMT"); + /** + * Number of milliseconds in a standard second. + */ + public static final int MILLIS_IN_SECOND = 1000; + /** + * Number of milliseconds in a standard minute. + */ + public static final int MILLIS_IN_MINUTE = 60 * 1000; + /** + * Number of milliseconds in a standard hour. + */ + public static final int MILLIS_IN_HOUR = 60 * 60 * 1000; + /** + * Number of milliseconds in a standard day. + */ + public static final int MILLIS_IN_DAY = 24 * 60 * 60 * 1000; + + /** + * This is half a month, so this represents whether a date is in the top + * or bottom half of the month. + */ + public final static int SEMI_MONTH = 1001; + + private static final int[][] fields = { + {Calendar.MILLISECOND}, + {Calendar.SECOND}, + {Calendar.MINUTE}, + {Calendar.HOUR_OF_DAY, Calendar.HOUR}, + {Calendar.DATE, Calendar.DAY_OF_MONTH, Calendar.AM_PM /* Calendar.DAY_OF_YEAR, Calendar.DAY_OF_WEEK, Calendar.DAY_OF_WEEK_IN_MONTH */}, + {Calendar.MONTH, DateUtils.SEMI_MONTH}, + {Calendar.YEAR}, + {Calendar.ERA}}; + + /** + * A week range, starting on Sunday. + */ + public final static int RANGE_WEEK_SUNDAY = 1; + + /** + * A week range, starting on Monday. + */ + public final static int RANGE_WEEK_MONDAY = 2; + + /** + * A week range, starting on the day focused. + */ + public final static int RANGE_WEEK_RELATIVE = 3; + + /** + * A week range, centered around the day focused. + */ + public final static int RANGE_WEEK_CENTER = 4; + + /** + * A month range, the week starting on Sunday. + */ + public final static int RANGE_MONTH_SUNDAY = 5; + + /** + * A month range, the week starting on Monday. + */ + public final static int RANGE_MONTH_MONDAY = 6; + + /** + *

DateUtils instances should NOT be constructed in + * standard programming. Instead, the class should be used as + * DateUtils.parse(str);.

+ * + *

This constructor is public to permit tools that require a JavaBean + * instance to operate.

+ */ + public DateUtils() { + } + + //----------------------------------------------------------------------- + /** + *

Round this date, leaving the field specified as the most + * significant field.

+ * + *

For example, if you had the datetime of 28 Mar 2002 + * 13:45:01.231, if this was passed with HOUR, it would return + * 28 Mar 2002 14:00:00.000. If this was passed with MONTH, it + * would return 1 April 2002 0:00:00.000.

+ * + * @param date the date to work with + * @param field the field from Calendar + * or SEMI_MONTH + * @return the rounded date + * @throws IllegalArgumentException if the date is null + */ + public static Date round(Date date, int field) { + if (date == null) { + throw new IllegalArgumentException("The date must not be null"); + } + GregorianCalendar gval = new GregorianCalendar(); + gval.setTime(date); + modify(gval, field, true); + return gval.getTime(); + } + + /** + *

Round this date, leaving the field specified as the most + * significant field.

+ * + *

For example, if you had the datetime of 28 Mar 2002 + * 13:45:01.231, if this was passed with HOUR, it would return + * 28 Mar 2002 14:00:00.000. If this was passed with MONTH, it + * would return 1 April 2002 0:00:00.000.

+ * + * @param date the date to work with + * @param field the field from Calendar + * or SEMI_MONTH + * @return the rounded date (a different object) + * @throws IllegalArgumentException if the date is null + */ + public static Calendar round(Calendar date, int field) { + if (date == null) { + throw new IllegalArgumentException("The date must not be null"); + } + Calendar rounded = (Calendar) date.clone(); + modify(rounded, field, true); + return rounded; + } + + /** + *

Round this date, leaving the field specified as the most + * significant field.

+ * + *

For example, if you had the datetime of 28 Mar 2002 + * 13:45:01.231, if this was passed with HOUR, it would return + * 28 Mar 2002 14:00:00.000. If this was passed with MONTH, it + * would return 1 April 2002 0:00:00.000.

+ * + * @param date the date to work with, either Date or Calendar + * @param field the field from Calendar + * or SEMI_MONTH + * @return the rounded date + * @throws IllegalArgumentException if the date is null + * @throws ClassCastException if the object type is not a Date + * or Calendar + */ + public static Date round(Object date, int field) { + if (date == null) { + throw new IllegalArgumentException("The date must not be null"); + } + if (date instanceof Date) { + return round((Date) date, field); + } else if (date instanceof Calendar) { + return round((Calendar) date, field).getTime(); + } else { + throw new ClassCastException("Could not round " + date); + } + } + + //----------------------------------------------------------------------- + /** + *

Truncate this date, leaving the field specified as the most + * significant field.

+ * + *

For example, if you had the datetime of 28 Mar 2002 + * 13:45:01.231, if you passed with HOUR, it would return 28 Mar + * 2002 13:00:00.000. If this was passed with MONTH, it would + * return 1 Mar 2002 0:00:00.000.

+ * + * @param date the date to work with + * @param field the field from Calendar + * or SEMI_MONTH + * @return the rounded date + * @throws IllegalArgumentException if the date is null + */ + public static Date truncate(Date date, int field) { + if (date == null) { + throw new IllegalArgumentException("The date must not be null"); + } + GregorianCalendar gval = new GregorianCalendar(); + gval.setTime(date); + modify(gval, field, false); + return gval.getTime(); + } + + /** + *

Truncate this date, leaving the field specified as the most + * significant field.

+ * + *

For example, if you had the datetime of 28 Mar 2002 + * 13:45:01.231, if you passed with HOUR, it would return 28 Mar + * 2002 13:00:00.000. If this was passed with MONTH, it would + * return 1 Mar 2002 0:00:00.000.

+ * + * @param date the date to work with + * @param field the field from Calendar + * or SEMI_MONTH + * @return the rounded date (a different object) + * @throws IllegalArgumentException if the date is null + */ + public static Calendar truncate(Calendar date, int field) { + if (date == null) { + throw new IllegalArgumentException("The date must not be null"); + } + Calendar truncated = (Calendar) date.clone(); + modify(truncated, field, false); + return truncated; + } + + /** + *

Truncate this date, leaving the field specified as the most + * significant field.

+ * + *

For example, if you had the datetime of 28 Mar 2002 + * 13:45:01.231, if you passed with HOUR, it would return 28 Mar + * 2002 13:00:00.000. If this was passed with MONTH, it would + * return 1 Mar 2002 0:00:00.000.

+ * + * @param date the date to work with, either Date + * or Calendar + * @param field the field from Calendar + * or SEMI_MONTH + * @return the rounded date + * @throws IllegalArgumentException if the date + * is null + * @throws ClassCastException if the object type is not a + * Date or Calendar + */ + public static Date truncate(Object date, int field) { + if (date == null) { + throw new IllegalArgumentException("The date must not be null"); + } + if (date instanceof Date) { + return truncate((Date) date, field); + } else if (date instanceof Calendar) { + return truncate((Calendar) date, field).getTime(); + } else { + throw new ClassCastException("Could not truncate " + date); + } + } + + //----------------------------------------------------------------------- + /** + *

Internal calculation method.

+ * + * @param val the calendar + * @param field the field constant + * @param round true to round, false to truncate + */ + private static void modify(Calendar val, int field, boolean round) { + boolean roundUp = false; + for (int i = 0; i < fields.length; i++) { + for (int j = 0; j < fields[i].length; j++) { + if (fields[i][j] == field) { + //This is our field... we stop looping + if (round && roundUp) { + if (field == DateUtils.SEMI_MONTH) { + //This is a special case that's hard to generalize + //If the date is 1, we round up to 16, otherwise + // we subtract 15 days and add 1 month + if (val.get(Calendar.DATE) == 1) { + val.add(Calendar.DATE, 15); + } else { + val.add(Calendar.DATE, -15); + val.add(Calendar.MONTH, 1); + } + } else { + //We need at add one to this field since the + // last number causes us to round up + val.add(fields[i][0], 1); + } + } + return; + } + } + //We have various fields that are not easy roundings + int offset = 0; + boolean offsetSet = false; + //These are special types of fields that require different rounding rules + switch (field) { + case DateUtils.SEMI_MONTH: + if (fields[i][0] == Calendar.DATE) { + //If we're going to drop the DATE field's value, + // we want to do this our own way. + //We need to subtrace 1 since the date has a minimum of 1 + offset = val.get(Calendar.DATE) - 1; + //If we're above 15 days adjustment, that means we're in the + // bottom half of the month and should stay accordingly. + if (offset >= 15) { + offset -= 15; + } + //Record whether we're in the top or bottom half of that range + roundUp = offset > 7; + offsetSet = true; + } + break; + case Calendar.AM_PM: + if (fields[i][0] == Calendar.HOUR) { + //If we're going to drop the HOUR field's value, + // we want to do this our own way. + offset = val.get(Calendar.HOUR); + if (offset >= 12) { + offset -= 12; + } + roundUp = offset > 6; + offsetSet = true; + } + break; + } + if (!offsetSet) { + int min = val.getActualMinimum(fields[i][0]); + int max = val.getActualMaximum(fields[i][0]); + //Calculate the offset from the minimum allowed value + offset = val.get(fields[i][0]) - min; + //Set roundUp if this is more than half way between the minimum and maximum + roundUp = offset > ((max - min) / 2); + } + //We need to remove this field + val.add(fields[i][0], -offset); + } + throw new IllegalArgumentException("The field " + field + " is not supported"); + + } + + // TODO: Decide whether this code is removed or goes into 2.1 + //----------------------------------------------------------------------- + /* + *

Parses a date string formatted in CVS format.

+ * + * @param dateStr the date to parse + * @return the parsed date + * @throws IllegalArgumentException if the date cannot be parsed + public static Calendar parseCVS(String dateStr) { + if (dateStr == null) { + throw new IllegalArgumentException("The date must not be null"); + } + //Get the symbol names + DateFormatSymbols symbols = new DateFormatSymbols(Locale.ENGLISH); + + //Prep the string to parse + String value = dateStr.toLowerCase().trim(); + + //Get the current date/time + Calendar now = Calendar.getInstance(); + if (value.endsWith(" ago")) { + //If this was a date that was "ago" the current time... + //Strip out the ' ago' part + value = value.substring(0, value.length() - 4); + + //Split the value and unit + int start = value.indexOf(" "); + if (start < 0) { + throw new IllegalArgumentException("Could not find space in between value and unit"); + } + String unit = value.substring(start + 1); + value = value.substring(0, start); + //We support "a week", so we need to parse the value as "a" + int val = 0; + if (value.equals("a") || value.equals("an")) { + val = 1; + } else { + val = Integer.parseInt(value); + } + + //Determine the unit + if (unit.equals("milliseconds") || unit.equals("millisecond")) { + now.add(Calendar.MILLISECOND, -val); + } else if (unit.equals("seconds") || unit.equals("second")) { + now.add(Calendar.SECOND, -val); + } else if (unit.equals("minutes") || unit.equals("minute")) { + now.add(Calendar.MINUTE, -val); + } else if (unit.equals("hours") || unit.equals("hour")) { + now.add(Calendar.HOUR, -val); + } else if (unit.equals("days") || unit.equals("day")) { + now.add(Calendar.DATE, -val); + } else if (unit.equals("weeks") || unit.equals("week")) { + now.add(Calendar.DATE, -val * 7); + } else if (unit.equals("fortnights") || unit.equals("fortnight")) { + now.add(Calendar.DATE, -val * 14); + } else if (unit.equals("months") || unit.equals("month")) { + now.add(Calendar.MONTH, -val); + } else if (unit.equals("years") || unit.equals("year")) { + now.add(Calendar.YEAR, -val); + } else { + throw new IllegalArgumentException("We do not understand that many units ago"); + } + return now; + } else if (value.startsWith("last ")) { + //If this was the last time a certain field was met + //Strip out the 'last ' part + value = value.substring(5); + //Get the current date/time + String[] strings = symbols.getWeekdays(); + for (int i = 0; i < strings.length; i++) { + if (value.equalsIgnoreCase(strings[i])) { + //How many days after Sunday + int daysAgo = now.get(Calendar.DAY_OF_WEEK) - i; + if (daysAgo <= 0) { + daysAgo += 7; + } + now.add(Calendar.DATE, -daysAgo); + return now; + } + } + strings = symbols.getMonths(); + for (int i = 0; i < strings.length; i++) { + if (value.equalsIgnoreCase(strings[i])) { + //How many days after January + int monthsAgo = now.get(Calendar.MONTH) - i; + if (monthsAgo <= 0) { + monthsAgo += 12; + } + now.add(Calendar.MONTH, -monthsAgo); + return now; + } + } + if (value.equals("week")) { + now.add(Calendar.DATE, -7); + return now; + } + throw new IllegalArgumentException("We do not understand that last units"); + } else if (value.equals("yesterday")) { + now.add(Calendar.DATE, -1); + return now; + } else if (value.equals("tomorrow")) { + now.add(Calendar.DATE, 1); + return now; + } + //Try to parse the date a number of different ways + for (int i = 0; i < dateFormats.length; i++) { + try { + Date datetime = dateFormats[i].parse(dateStr); + Calendar cal = Calendar.getInstance(); + cal.setTime(datetime); + return cal; + } catch (ParseException pe) { + //we ignore this and just keep trying + } + } + + throw new IllegalArgumentException("Unable to parse '" + dateStr + "'."); + } + */ + + //----------------------------------------------------------------------- + /** + *

This constructs an Iterator that will + * start and stop over a date range based on the focused + * date and the range style.

+ * + *

For instance, passing Thursday, July 4, 2002 and a + * RANGE_MONTH_SUNDAY will return an + * Iterator that starts with Sunday, June 30, + * 2002 and ends with Saturday, August 3, 2002. + * + * @param focus the date to work with + * @param rangeStyle the style constant to use. Must be one of the range + * styles listed for the {@link #iterator(Calendar, int)} method. + * + * @return the date iterator + * @throws IllegalArgumentException if the date is null or if + * the rangeStyle is not + */ + public static Iterator iterator(Date focus, int rangeStyle) { + if (focus == null) { + throw new IllegalArgumentException("The date must not be null"); + } + GregorianCalendar gval = new GregorianCalendar(); + gval.setTime(focus); + return iterator(gval, rangeStyle); + } + + /** + *

This constructs an Iterator that will + * start and stop over a date range based on the focused + * date and the range style.

+ * + *

For instance, passing Thursday, July 4, 2002 and a + * RANGE_MONTH_SUNDAY will return an + * Iterator that starts with Sunday, June 30, + * 2002 and ends with Saturday, August 3, 2002. + * + * @param focus the date to work with + * @param rangeStyle the style constant to use. Must be one of + * {@link DateUtils#RANGE_MONTH_SUNDAY}, + * {@link DateUtils#RANGE_MONTH_MONDAY}, + * {@link DateUtils#RANGE_WEEK_SUNDAY}, + * {@link DateUtils#RANGE_WEEK_MONDAY}, + * {@link DateUtils#RANGE_WEEK_RELATIVE}, + * {@link DateUtils#RANGE_WEEK_CENTER} + * @return the date iterator + * @throws IllegalArgumentException if the date is null + */ + public static Iterator iterator(Calendar focus, int rangeStyle) { + if (focus == null) { + throw new IllegalArgumentException("The date must not be null"); + } + Calendar start = null; + Calendar end = null; + int startCutoff = Calendar.SUNDAY; + int endCutoff = Calendar.SATURDAY; + switch (rangeStyle) { + case RANGE_MONTH_SUNDAY: + case RANGE_MONTH_MONDAY: + //Set start to the first of the month + start = truncate(focus, Calendar.MONTH); + //Set end to the last of the month + end = (Calendar) start.clone(); + end.add(Calendar.MONTH, 1); + end.add(Calendar.DATE, -1); + //Loop start back to the previous sunday or monday + if (rangeStyle == RANGE_MONTH_MONDAY) { + startCutoff = Calendar.MONDAY; + endCutoff = Calendar.SUNDAY; + } + break; + case RANGE_WEEK_SUNDAY: + case RANGE_WEEK_MONDAY: + case RANGE_WEEK_RELATIVE: + case RANGE_WEEK_CENTER: + //Set start and end to the current date + start = truncate(focus, Calendar.DATE); + end = truncate(focus, Calendar.DATE); + switch (rangeStyle) { + case RANGE_WEEK_SUNDAY: + //already set by default + break; + case RANGE_WEEK_MONDAY: + startCutoff = Calendar.MONDAY; + endCutoff = Calendar.SUNDAY; + break; + case RANGE_WEEK_RELATIVE: + startCutoff = focus.get(Calendar.DAY_OF_WEEK); + endCutoff = startCutoff - 1; + break; + case RANGE_WEEK_CENTER: + startCutoff = focus.get(Calendar.DAY_OF_WEEK) - 3; + endCutoff = focus.get(Calendar.DAY_OF_WEEK) + 3; + break; + } + break; + default: + throw new IllegalArgumentException("The range style " + rangeStyle + " is not valid."); + } + if (startCutoff < Calendar.SUNDAY) { + startCutoff += 7; + } + if (startCutoff > Calendar.SATURDAY) { + startCutoff -= 7; + } + if (endCutoff < Calendar.SUNDAY) { + endCutoff += 7; + } + if (endCutoff > Calendar.SATURDAY) { + endCutoff -= 7; + } + while (start.get(Calendar.DAY_OF_WEEK) != startCutoff) { + start.add(Calendar.DATE, -1); + } + while (end.get(Calendar.DAY_OF_WEEK) != endCutoff) { + end.add(Calendar.DATE, 1); + } + return new DateIterator(start, end); + } + + /** + *

This constructs an Iterator that will + * start and stop over a date range based on the focused + * date and the range style.

+ * + *

For instance, passing Thursday, July 4, 2002 and a + * RANGE_MONTH_SUNDAY will return an + * Iterator that starts with Sunday, June 30, + * 2002 and ends with Saturday, August 3, 2002.

+ * + * @param focus the date to work with, either + * Date or Calendar + * @param rangeStyle the style constant to use. Must be one of the range + * styles listed for the {@link #iterator(Calendar, int)} method. + * @return the date iterator + * @throws IllegalArgumentException if the date + * is null + * @throws ClassCastException if the object type is + * not a Date or Calendar + */ + public static Iterator iterator(Object focus, int rangeStyle) { + if (focus == null) { + throw new IllegalArgumentException("The date must not be null"); + } + if (focus instanceof Date) { + return iterator((Date) focus, rangeStyle); + } else if (focus instanceof Calendar) { + return iterator((Calendar) focus, rangeStyle); + } else { + throw new ClassCastException("Could not iterate based on " + focus); + } + } + + /** + *

Date iterator.

+ */ + static class DateIterator implements Iterator { + private final Calendar endFinal; + private final Calendar spot; + + DateIterator(Calendar startFinal, Calendar endFinal) { + super(); + this.endFinal = endFinal; + spot = startFinal; + spot.add(Calendar.DATE, -1); + } + + public boolean hasNext() { + return spot.before(endFinal); + } + + public Object next() { + if (spot.equals(endFinal)) { + throw new NoSuchElementException(); + } + spot.add(Calendar.DATE, 1); + return spot.clone(); + } + + public void remove() { + throw new UnsupportedOperationException(); + } + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/time/DurationFormatUtils.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/time/DurationFormatUtils.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/time/DurationFormatUtils.java 30 Aug 2012 16:24:43 -0000 1.1 @@ -0,0 +1,202 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.time; + +/** + *

Duration formatting utilites and constants.

+ * + * @author Apache Ant - DateUtils + * @author Stephane Bailliez + * @author Stefan Bodewig + * @author Stephen Colebourne + * @author Gary Gregory + * @since 2.0 + * @version $Id: DurationFormatUtils.java,v 1.1 2012/08/30 16:24:43 marcin Exp $ + */ +class DurationFormatUtils { + // TODO: Make class public once methods can fully select which fields to output + + /** + *

Pattern used with FastDateFormat and SimpleDateFormat for the ISO8601 + * date time extended format used in durations.

+ * + * @see org.apache.commons.lang.time.FastDateFormat + * @see java.text.SimpleDateFormat + */ + public static final String ISO_EXTENDED_FORMAT_PATTERN = "'P'yyyy'Y'M'M'd'DT'H'H'm'M's.S'S'"; + + /** + *

ISO8601 formatter for the date time extended format used in durations, + * with XML Schema durations particularly in mind.

+ * + *

This format represents the Gregorian year, month, day, hour, minute, and second components defined + * in � 5.5.3.2 of ISO 8601, respectively. These components are ordered in their significance by their order + * of appearance i.e. as year, month, day, hour, minute, and second.

+ * + *

The ISO8601 extended format PnYnMnDTnHnMnS, where nY + * represents the number of years, nM the number of months, nD the number of days, + * 'T' is the date/time separator, nH the number of hours, nM the number of minutes and + * nS the number of seconds. The number of seconds can include decimal digits to arbitrary precision.

+ * + * @see #ISO_EXTENDED_FORMAT_PATTERN + * @see http://www.w3.org/TR/xmlschema-2/#duration + */ + public static final FastDateFormat ISO_EXTENDED_FORMAT = + FastDateFormat.getInstance(ISO_EXTENDED_FORMAT_PATTERN); + + /** + *

Get the time gap as a string.

+ * + *

The format used is ISO8601-like: + * hours:minutes:seconds.milliseconds.

+ * + * @param millis the duration to format + * @return the time as a String + */ + public static String formatISO(long millis) { + int hours, minutes, seconds, milliseconds; + hours = (int) (millis / DateUtils.MILLIS_IN_HOUR); + millis = millis - (hours * DateUtils.MILLIS_IN_HOUR); + minutes = (int) (millis / DateUtils.MILLIS_IN_MINUTE); + millis = millis - (minutes * DateUtils.MILLIS_IN_MINUTE); + seconds = (int) (millis / DateUtils.MILLIS_IN_SECOND); + millis = millis - (seconds * DateUtils.MILLIS_IN_SECOND); + milliseconds = (int) millis; + + StringBuffer buf = new StringBuffer(32); + buf.append(hours); + buf.append(':'); + buf.append((char) (minutes / 10 + '0')); + buf.append((char) (minutes % 10 + '0')); + buf.append(':'); + buf.append((char) (seconds / 10 + '0')); + buf.append((char) (seconds % 10 + '0')); + buf.append('.'); + if (milliseconds < 10) { + buf.append('0').append('0'); + } else if (milliseconds < 100) { + buf.append('0'); + } + buf.append(milliseconds); + return buf.toString(); + } + + /** + *

Format an elapsed time into a plurialization correct string. + * It is limited only to report elapsed time in minutes and + * seconds and has the following behavior.

+ * + *
    + *
  • minutes are not displayed when 0 (ie: + * "45 seconds")
  • . + *
  • seconds are always displayed in plural form (ie + * "0 seconds" or "10 seconds") except + * for 1 (ie "1 second")
  • + *
+ * + * @param millis the elapsed time to report in milliseconds + * @return the formatted text in minutes/seconds + */ + public static String formatWords( + long millis, + boolean supressLeadingZeroElements, + boolean supressTrailingZeroElements) { + long[] values = new long[4]; + values[0] = millis / DateUtils.MILLIS_IN_DAY; + values[1] = (millis / DateUtils.MILLIS_IN_HOUR) % 24; + values[2] = (millis / DateUtils.MILLIS_IN_MINUTE) % 60; + values[3] = (millis / DateUtils.MILLIS_IN_SECOND) % 60; + String[] fieldsOne = { " day ", " hour ", " minute ", " second" }; + String[] fieldsPlural = { " days ", " hours ", " minutes ", " seconds" }; + + StringBuffer buf = new StringBuffer(64); + boolean valueOutput = false; + + for (int i = 0; i < 4; i++) { + long value = values[i]; + if (value == 0) { + // handle zero + if (valueOutput) { + if (supressTrailingZeroElements == false) { + buf.append('0').append(fieldsPlural[i]); + } + } else { + if (supressLeadingZeroElements == false) { + buf.append('0').append(fieldsPlural[i]); + } + } + } else if (value == 1) { + // one + valueOutput = true; + buf.append('1').append(fieldsOne[i]); + } else { + // other + valueOutput = true; + buf.append(value).append(fieldsPlural[i]); + } + } + + return buf.toString().trim(); + } + + /** + *

DurationFormatUtils instances should NOT be constructed in standard programming.

+ * + *

This constructor is public to permit tools that require a JavaBean instance + * to operate.

+ */ + public DurationFormatUtils() { + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/time/FastDateFormat.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/time/FastDateFormat.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/time/FastDateFormat.java 30 Aug 2012 16:24:43 -0000 1.1 @@ -0,0 +1,1373 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.time; + +import java.text.DateFormat; +import java.text.DateFormatSymbols; +import java.text.FieldPosition; +import java.text.Format; +import java.text.ParsePosition; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.TimeZone; + +/** + *

FastDateFormat is a fast and thread-safe version of + * {@link java.text.SimpleDateFormat}.

+ * + *

This class can be used as a direct replacement to + * SimpleDateFormat in most formatting situations. + * This class is especially useful in multi-threaded server environments. + * SimpleDateFormat is not thread-safe in any JDK version, + * nor will it be as Sun have closed the bug/RFE. + *

+ * + *

Only formatting is supported, but all patterns are compatible with + * SimpleDateFormat (except time zones - see below).

+ * + *

Java 1.4 introduced a new pattern letter, 'Z', to represent + * time zones in RFC822 format (eg. +0800 or -1100). + * This pattern letter can be used here (on all JDK versions).

+ * + *

In addition, the pattern 'ZZ' has been made to represent + * ISO8601 full format time zones (eg. +08:00 or -11:00). + * This introduces a minor incompatability with Java 1.4, but at a gain of + * useful functionality.

+ * + * @author TeaTrove project + * @author Brian S O'Neill + * @author Sean Schofield + * @author Gary Gregory + * @author Stephen Colebourne + * @since 2.0 + * @version $Id: FastDateFormat.java,v 1.1 2012/08/30 16:24:43 marcin Exp $ + */ +public class FastDateFormat extends Format { + // A lot of the speed in this class comes from caching, but some comes + // from the special int to StringBuffer conversion. + // + // The following produces a padded 2 digit number: + // buffer.append((char)(value / 10 + '0')); + // buffer.append((char)(value % 10 + '0')); + // + // Note that the fastest append to StringBuffer is a single char (used here). + // Note that Integer.toString() is not called, the conversion is simply + // taking the value and adding (mathematically) the ASCII value for '0'. + // So, don't change this code! It works and is very fast. + + /** + * FULL locale dependent date or time style. + */ + public static final int FULL = DateFormat.FULL; + /** + * LONG locale dependent date or time style. + */ + public static final int LONG = DateFormat.LONG; + /** + * MEDIUM locale dependent date or time style. + */ + public static final int MEDIUM = DateFormat.MEDIUM; + /** + * SHORT locale dependent date or time style. + */ + public static final int SHORT = DateFormat.SHORT; + + // package scoped as used by inner class + static final double LOG_10 = Math.log(10); + + private static String cDefaultPattern; + + private static Map cInstanceCache = new HashMap(7); + private static Map cDateInstanceCache = new HashMap(7); + private static Map cTimeInstanceCache = new HashMap(7); + private static Map cDateTimeInstanceCache = new HashMap(7); + private static Map cTimeZoneDisplayCache = new HashMap(7); + + /** + * The pattern. + */ + private final String mPattern; + /** + * The time zone. + */ + private final TimeZone mTimeZone; + /** + * Whether the time zone overrides any on Calendars. + */ + private final boolean mTimeZoneForced; + /** + * The locale. + */ + private final Locale mLocale; + /** + * Whether the locale overrides the default. + */ + private final boolean mLocaleForced; + /** + * The parsed rules. + */ + private Rule[] mRules; + /** + * The estimated maximum length. + */ + private int mMaxLengthEstimate; + + //----------------------------------------------------------------------- + /** + *

Gets a formatter instance using the default pattern in the + * default locale.

+ * + * @return a date/time formatter + */ + public static FastDateFormat getInstance() { + return getInstance(getDefaultPattern(), null, null); + } + + /** + *

Gets a formatter instance using the specified pattern in the + * default locale.

+ * + * @param pattern {@link java.text.SimpleDateFormat} compatible + * pattern + * @return a pattern based date/time formatter + * @throws IllegalArgumentException if pattern is invalid + */ + public static FastDateFormat getInstance(String pattern) { + return getInstance(pattern, null, null); + } + + /** + *

Gets a formatter instance using the specified pattern and + * time zone.

+ * + * @param pattern {@link java.text.SimpleDateFormat} compatible + * pattern + * @param timeZone optional time zone, overrides time zone of + * formatted date + * @return a pattern based date/time formatter + * @throws IllegalArgumentException if pattern is invalid + */ + public static FastDateFormat getInstance(String pattern, TimeZone timeZone) { + return getInstance(pattern, timeZone, null); + } + + /** + *

Gets a formatter instance using the specified pattern and + * locale.

+ * + * @param pattern {@link java.text.SimpleDateFormat} compatible + * pattern + * @param locale optional locale, overrides system locale + * @return a pattern based date/time formatter + * @throws IllegalArgumentException if pattern is invalid + */ + public static FastDateFormat getInstance(String pattern, Locale locale) { + return getInstance(pattern, null, locale); + } + + /** + *

Gets a formatter instance using the specified pattern, time zone + * and locale.

+ * + * @param pattern {@link java.text.SimpleDateFormat} compatible + * pattern + * @param timeZone optional time zone, overrides time zone of + * formatted date + * @param locale optional locale, overrides system locale + * @return a pattern based date/time formatter + * @throws IllegalArgumentException if pattern is invalid + * or null + */ + public static synchronized FastDateFormat getInstance(String pattern, TimeZone timeZone, Locale locale) { + FastDateFormat emptyFormat = new FastDateFormat(pattern, timeZone, locale); + FastDateFormat format = (FastDateFormat) cInstanceCache.get(emptyFormat); + if (format == null) { + format = emptyFormat; + format.init(); // convert shell format into usable one + cInstanceCache.put(format, format); // this is OK! + } + return format; + } + + /** + *

Gets a date formatter instance using the specified style, time + * zone and locale.

+ * + * @param style date style: FULL, LONG, MEDIUM, or SHORT + * @param timeZone optional time zone, overrides time zone of + * formatted date + * @param locale optional locale, overrides system locale + * @return a localized standard date formatter + * @throws IllegalArgumentException if the Locale has no date + * pattern defined + */ + public static synchronized FastDateFormat getDateInstance(int style, TimeZone timeZone, Locale locale) { + Object key = new Integer(style); + if (timeZone != null) { + key = new Pair(key, timeZone); + } + if (locale == null) { + key = new Pair(key, locale); + } + + FastDateFormat format = (FastDateFormat) cDateInstanceCache.get(key); + if (format == null) { + if (locale == null) { + locale = Locale.getDefault(); + } + + try { + SimpleDateFormat formatter = (SimpleDateFormat) DateFormat.getDateInstance(style, locale); + String pattern = formatter.toPattern(); + format = getInstance(pattern, timeZone, locale); + cDateInstanceCache.put(key, format); + + } catch (ClassCastException ex) { + throw new IllegalArgumentException("No date pattern for locale: " + locale); + } + } + return format; + } + + /** + *

Gets a time formatter instance using the specified style, time + * zone and locale.

+ * + * @param style time style: FULL, LONG, MEDIUM, or SHORT + * @param timeZone optional time zone, overrides time zone of + * formatted time + * @param locale optional locale, overrides system locale + * @return a localized standard time formatter + * @throws IllegalArgumentException if the Locale has no time + * pattern defined + */ + public static synchronized FastDateFormat getTimeInstance(int style, TimeZone timeZone, Locale locale) { + Object key = new Integer(style); + if (timeZone != null) { + key = new Pair(key, timeZone); + } + if (locale != null) { + key = new Pair(key, locale); + } + + FastDateFormat format = (FastDateFormat) cTimeInstanceCache.get(key); + if (format == null) { + if (locale == null) { + locale = Locale.getDefault(); + } + + try { + SimpleDateFormat formatter = (SimpleDateFormat) DateFormat.getTimeInstance(style, locale); + String pattern = formatter.toPattern(); + format = getInstance(pattern, timeZone, locale); + cTimeInstanceCache.put(key, format); + + } catch (ClassCastException ex) { + throw new IllegalArgumentException("No date pattern for locale: " + locale); + } + } + return format; + } + + /** + *

Gets a date/time formatter instance using the specified style, + * time zone and locale.

+ * + * @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT + * @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT + * @param timeZone optional time zone, overrides time zone of + * formatted date + * @param locale optional locale, overrides system locale + * @return a localized standard date/time formatter + * @throws IllegalArgumentException if the Locale has no date/time + * pattern defined + */ + public static synchronized FastDateFormat getDateTimeInstance( + int dateStyle, int timeStyle, TimeZone timeZone, Locale locale) { + + Object key = new Pair(new Integer(dateStyle), new Integer(timeStyle)); + if (timeZone != null) { + key = new Pair(key, timeZone); + } + if (locale != null) { + key = new Pair(key, locale); + } + + FastDateFormat format = (FastDateFormat) cDateTimeInstanceCache.get(key); + if (format == null) { + if (locale == null) { + locale = Locale.getDefault(); + } + + try { + SimpleDateFormat formatter = (SimpleDateFormat) DateFormat.getDateTimeInstance(dateStyle, timeStyle, locale); + String pattern = formatter.toPattern(); + format = getInstance(pattern, timeZone, locale); + cDateTimeInstanceCache.put(key, format); + + } catch (ClassCastException ex) { + throw new IllegalArgumentException("No date time pattern for locale: " + locale); + } + } + return format; + } + + //----------------------------------------------------------------------- + /** + *

Gets the time zone display name, using a cache for performance.

+ * + * @param tz the zone to query + * @param daylight true if daylight savings + * @param style the style to use TimeZone.LONG + * or TimeZone.SHORT + * @param locale the locale to use + * @return the textual name of the time zone + */ + static synchronized String getTimeZoneDisplay(TimeZone tz, boolean daylight, int style, Locale locale) { + Object key = new TimeZoneDisplayKey(tz, daylight, style, locale); + String value = (String) cTimeZoneDisplayCache.get(key); + if (value == null) { + // This is a very slow call, so cache the results. + value = tz.getDisplayName(daylight, style, locale); + cTimeZoneDisplayCache.put(key, value); + } + return value; + } + + /** + *

Gets the default pattern.

+ * + * @return the default pattern + */ + private static synchronized String getDefaultPattern() { + if (cDefaultPattern == null) { + cDefaultPattern = new SimpleDateFormat().toPattern(); + } + return cDefaultPattern; + } + + // Constructor + //----------------------------------------------------------------------- + /** + *

Constructs a new FastDateFormat.

+ * + * @param pattern {@link java.text.SimpleDateFormat} compatible + * pattern + * @param timeZone time zone to use, null means use + * default for Date and value within for + * Calendar + * @param locale locale, null means use system + * default + * @throws IllegalArgumentException if pattern is invalid or + * null + */ + protected FastDateFormat(String pattern, TimeZone timeZone, Locale locale) { + super(); + if (pattern == null) { + throw new IllegalArgumentException("The pattern must not be null"); + } + mPattern = pattern; + + mTimeZoneForced = (timeZone != null); + if (timeZone == null) { + timeZone = TimeZone.getDefault(); + } + mTimeZone = timeZone; + + mLocaleForced = (locale != null); + if (locale == null) { + locale = Locale.getDefault(); + } + mLocale = locale; + } + + /** + *

Initialise the instance for first use.

+ */ + protected void init() { + List rulesList = parsePattern(); + mRules = (Rule[]) rulesList.toArray(new Rule[rulesList.size()]); + + int len = 0; + for (int i=mRules.length; --i >= 0; ) { + len += mRules[i].estimateLength(); + } + + mMaxLengthEstimate = len; + } + + // Parse the pattern + //----------------------------------------------------------------------- + /** + *

Returns a list of Rules given a pattern.

+ * + * @return a List of Rule objects + * @throws IllegalArgumentException if pattern is invalid + */ + protected List parsePattern() { + DateFormatSymbols symbols = new DateFormatSymbols(mLocale); + List rules = new ArrayList(); + + String[] ERAs = symbols.getEras(); + String[] months = symbols.getMonths(); + String[] shortMonths = symbols.getShortMonths(); + String[] weekdays = symbols.getWeekdays(); + String[] shortWeekdays = symbols.getShortWeekdays(); + String[] AmPmStrings = symbols.getAmPmStrings(); + + int length = mPattern.length(); + int[] indexRef = new int[1]; + + for (int i = 0; i < length; i++) { + indexRef[0] = i; + String token = parseToken(mPattern, indexRef); + i = indexRef[0]; + + int tokenLen = token.length(); + if (tokenLen == 0) { + break; + } + + Rule rule; + char c = token.charAt(0); + + switch (c) { + case 'G': // era designator (text) + rule = new TextField(Calendar.ERA, ERAs); + break; + case 'y': // year (number) + if (tokenLen >= 4) { + rule = UnpaddedNumberField.INSTANCE_YEAR; + } else { + rule = TwoDigitYearField.INSTANCE; + } + break; + case 'M': // month in year (text and number) + if (tokenLen >= 4) { + rule = new TextField(Calendar.MONTH, months); + } else if (tokenLen == 3) { + rule = new TextField(Calendar.MONTH, shortMonths); + } else if (tokenLen == 2) { + rule = TwoDigitMonthField.INSTANCE; + } else { + rule = UnpaddedMonthField.INSTANCE; + } + break; + case 'd': // day in month (number) + rule = selectNumberRule(Calendar.DAY_OF_MONTH, tokenLen); + break; + case 'h': // hour in am/pm (number, 1..12) + rule = new TwelveHourField(selectNumberRule(Calendar.HOUR, tokenLen)); + break; + case 'H': // hour in day (number, 0..23) + rule = selectNumberRule(Calendar.HOUR_OF_DAY, tokenLen); + break; + case 'm': // minute in hour (number) + rule = selectNumberRule(Calendar.MINUTE, tokenLen); + break; + case 's': // second in minute (number) + rule = selectNumberRule(Calendar.SECOND, tokenLen); + break; + case 'S': // millisecond (number) + rule = selectNumberRule(Calendar.MILLISECOND, tokenLen); + break; + case 'E': // day in week (text) + rule = new TextField(Calendar.DAY_OF_WEEK, tokenLen < 4 ? shortWeekdays : weekdays); + break; + case 'D': // day in year (number) + rule = selectNumberRule(Calendar.DAY_OF_YEAR, tokenLen); + break; + case 'F': // day of week in month (number) + rule = selectNumberRule(Calendar.DAY_OF_WEEK_IN_MONTH, tokenLen); + break; + case 'w': // week in year (number) + rule = selectNumberRule(Calendar.WEEK_OF_YEAR, tokenLen); + break; + case 'W': // week in month (number) + rule = selectNumberRule(Calendar.WEEK_OF_MONTH, tokenLen); + break; + case 'a': // am/pm marker (text) + rule = new TextField(Calendar.AM_PM, AmPmStrings); + break; + case 'k': // hour in day (1..24) + rule = new TwentyFourHourField(selectNumberRule(Calendar.HOUR_OF_DAY, tokenLen)); + break; + case 'K': // hour in am/pm (0..11) + rule = selectNumberRule(Calendar.HOUR, tokenLen); + break; + case 'z': // time zone (text) + if (tokenLen >= 4) { + rule = new TimeZoneNameRule(mTimeZone, mTimeZoneForced, mLocale, TimeZone.LONG); + } else { + rule = new TimeZoneNameRule(mTimeZone, mTimeZoneForced, mLocale, TimeZone.SHORT); + } + break; + case 'Z': // time zone (value) + if (tokenLen == 1) { + rule = TimeZoneNumberRule.INSTANCE_NO_COLON; + } else { + rule = TimeZoneNumberRule.INSTANCE_COLON; + } + break; + case '\'': // literal text + String sub = token.substring(1); + if (sub.length() == 1) { + rule = new CharacterLiteral(sub.charAt(0)); + } else { + rule = new StringLiteral(sub); + } + break; + default: + throw new IllegalArgumentException("Illegal pattern component: " + token); + } + + rules.add(rule); + } + + return rules; + } + + /** + *

Performs the parsing of tokens.

+ * + * @param pattern the pattern + * @param indexRef index references + * @return parsed token + */ + protected String parseToken(String pattern, int[] indexRef) { + StringBuffer buf = new StringBuffer(); + + int i = indexRef[0]; + int length = pattern.length(); + + char c = pattern.charAt(i); + if (c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z') { + // Scan a run of the same character, which indicates a time + // pattern. + buf.append(c); + + while (i + 1 < length) { + char peek = pattern.charAt(i + 1); + if (peek == c) { + buf.append(c); + i++; + } else { + break; + } + } + } else { + // This will identify token as text. + buf.append('\''); + + boolean inLiteral = false; + + for (; i < length; i++) { + c = pattern.charAt(i); + + if (c == '\'') { + if (i + 1 < length && pattern.charAt(i + 1) == '\'') { + // '' is treated as escaped ' + i++; + buf.append(c); + } else { + inLiteral = !inLiteral; + } + } else if (!inLiteral && + (c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z')) { + i--; + break; + } else { + buf.append(c); + } + } + } + + indexRef[0] = i; + return buf.toString(); + } + + /** + *

Gets an appropriate rule for the padding required.

+ * + * @param field the field to get a rule for + * @param padding the padding required + * @return a new rule with the correct padding + */ + protected NumberRule selectNumberRule(int field, int padding) { + switch (padding) { + case 1: + return new UnpaddedNumberField(field); + case 2: + return new TwoDigitNumberField(field); + default: + return new PaddedNumberField(field, padding); + } + } + + // Format methods + //----------------------------------------------------------------------- + /** + *

Format either a Date or a + * Calendar object.

+ * + * @param obj the object to format + * @param toAppendTo the buffer to append to + * @param pos the position - ignored + * @return the buffer passed in + */ + public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) { + if (obj instanceof Date) { + return format((Date) obj, toAppendTo); + } else if (obj instanceof Calendar) { + return format((Calendar) obj, toAppendTo); + } else { + throw new IllegalArgumentException("Unknown class: " + + (obj == null ? "" : obj.getClass().getName())); + } + } + + /** + *

Formats a Date object.

+ * + * @param date the date to format + * @return the formatted string + */ + public String format(Date date) { + Calendar c = new GregorianCalendar(mTimeZone); + c.setTime(date); + return applyRules(c, new StringBuffer(mMaxLengthEstimate)).toString(); + } + + /** + *

Formats a Calendar object.

+ * + * @param calendar the calendar to format + * @return the formatted string + */ + public String format(Calendar calendar) { + return format(calendar, new StringBuffer(mMaxLengthEstimate)).toString(); + } + + /** + *

Formats a Date object into the + * supplied StringBuffer.

+ * + * @param date the date to format + * @param buf the buffer to format into + * @return the specified string buffer + */ + public StringBuffer format(Date date, StringBuffer buf) { + Calendar c = new GregorianCalendar(mTimeZone); + c.setTime(date); + return applyRules(c, buf); + } + + /** + *

Formats a Calendar object into the + * supplied StringBuffer.

+ * + * @param calendar the calendar to format + * @param buf the buffer to format into + * @return the specified string buffer + */ + public StringBuffer format(Calendar calendar, StringBuffer buf) { + if (mTimeZoneForced) { + calendar = (Calendar) calendar.clone(); + calendar.setTimeZone(mTimeZone); + } + return applyRules(calendar, buf); + } + + /** + *

Performs the formatting by applying the rules to the + * specified calendar.

+ * + * @param calendar the calendar to format + * @param buf the buffer to format into + * @return the specified string buffer + */ + protected StringBuffer applyRules(Calendar calendar, StringBuffer buf) { + Rule[] rules = mRules; + int len = mRules.length; + for (int i = 0; i < len; i++) { + rules[i].appendTo(buf, calendar); + } + return buf; + } + + // Parsing + //----------------------------------------------------------------------- + /** + *

Parsing not supported.

+ * + * @param source the string to parse + * @param pos the parsing position + * @return null as not supported + */ + public Object parseObject(String source, ParsePosition pos) { + pos.setIndex(0); + pos.setErrorIndex(0); + return null; + } + + // Accessors + //----------------------------------------------------------------------- + /** + *

Gets the pattern used by this formatter.

+ * + * @return the pattern, {@link java.text.SimpleDateFormat} compatible + */ + public String getPattern() { + return mPattern; + } + + /** + *

Gets the time zone used by this formatter.

+ * + *

This zone is always used for Date formatting. + * If a Calendar is passed in to be formatted, the + * time zone on that may be used depending on + * {@link #getTimeZoneOverridesCalendar()}.

+ * + * @return the time zone + */ + public TimeZone getTimeZone() { + return mTimeZone; + } + + /** + *

Returns true if the time zone of the + * calendar overrides the time zone of the formatter.

+ * + * @return true if time zone of formatter + * overridden for calendars + */ + public boolean getTimeZoneOverridesCalendar() { + return mTimeZoneForced; + } + + /** + *

Gets the locale used by this formatter.

+ * + * @return the locale + */ + public Locale getLocale() { + return mLocale; + } + + /** + *

Gets an estimate for the maximum string length that the + * formatter will produce.

+ * + *

The actual formatted length will almost always be less than or + * equal to this amount.

+ * + * @return the maximum formatted length + */ + public int getMaxLengthEstimate() { + return mMaxLengthEstimate; + } + + // Basics + //----------------------------------------------------------------------- + /** + *

Compare two objects for equality.

+ * + * @param obj the object to compare to + * @return true if equal + */ + public boolean equals(Object obj) { + if (obj instanceof FastDateFormat == false) { + return false; + } + FastDateFormat other = (FastDateFormat) obj; + if ( + (mPattern == other.mPattern || mPattern.equals(other.mPattern)) && + (mTimeZone == other.mTimeZone || mTimeZone.equals(other.mTimeZone)) && + (mLocale == other.mLocale || mLocale.equals(other.mLocale)) && + (mTimeZoneForced == other.mTimeZoneForced) && + (mLocaleForced == other.mLocaleForced) + ) { + return true; + } + return false; + } + + /** + *

A suitable hashcode.

+ * + * @return a hashcode compatable with equals + */ + public int hashCode() { + int total = 0; + total += mPattern.hashCode(); + total += mTimeZone.hashCode(); + total += (mTimeZoneForced ? 1 : 0); + total += mLocale.hashCode(); + total += (mLocaleForced ? 1 : 0); + return total; + } + + /** + *

Gets a debugging string version of this formatter.

+ * + * @return a debugging string + */ + public String toString() { + return "FastDateFormat[" + mPattern + "]"; + } + + // Rules + //----------------------------------------------------------------------- + /** + *

Inner class defining a rule.

+ */ + private interface Rule { + int estimateLength(); + void appendTo(StringBuffer buffer, Calendar calendar); + } + + /** + *

Inner class defining a numeric rule.

+ */ + private interface NumberRule extends Rule { + void appendTo(StringBuffer buffer, int value); + } + + /** + *

Inner class to output a constant single character.

+ */ + private static class CharacterLiteral implements Rule { + private final char mValue; + + CharacterLiteral(char value) { + mValue = value; + } + + public int estimateLength() { + return 1; + } + + public void appendTo(StringBuffer buffer, Calendar calendar) { + buffer.append(mValue); + } + } + + /** + *

Inner class to output a constant string.

+ */ + private static class StringLiteral implements Rule { + private final String mValue; + + StringLiteral(String value) { + mValue = value; + } + + public int estimateLength() { + return mValue.length(); + } + + public void appendTo(StringBuffer buffer, Calendar calendar) { + buffer.append(mValue); + } + } + + /** + *

Inner class to output one of a set of values.

+ */ + private static class TextField implements Rule { + private final int mField; + private final String[] mValues; + + TextField(int field, String[] values) { + mField = field; + mValues = values; + } + + public int estimateLength() { + int max = 0; + for (int i=mValues.length; --i >= 0; ) { + int len = mValues[i].length(); + if (len > max) { + max = len; + } + } + return max; + } + + public void appendTo(StringBuffer buffer, Calendar calendar) { + buffer.append(mValues[calendar.get(mField)]); + } + } + + /** + *

Inner class to output an unpadded number.

+ */ + private static class UnpaddedNumberField implements NumberRule { + static final UnpaddedNumberField INSTANCE_YEAR = new UnpaddedNumberField(Calendar.YEAR); + + private final int mField; + + UnpaddedNumberField(int field) { + mField = field; + } + + public int estimateLength() { + return 4; + } + + public void appendTo(StringBuffer buffer, Calendar calendar) { + appendTo(buffer, calendar.get(mField)); + } + + public final void appendTo(StringBuffer buffer, int value) { + if (value < 10) { + buffer.append((char)(value + '0')); + } else if (value < 100) { + buffer.append((char)(value / 10 + '0')); + buffer.append((char)(value % 10 + '0')); + } else { + buffer.append(Integer.toString(value)); + } + } + } + + /** + *

Inner class to output an unpadded month.

+ */ + private static class UnpaddedMonthField implements NumberRule { + static final UnpaddedMonthField INSTANCE = new UnpaddedMonthField(); + + UnpaddedMonthField() { + } + + public int estimateLength() { + return 2; + } + + public void appendTo(StringBuffer buffer, Calendar calendar) { + appendTo(buffer, calendar.get(Calendar.MONTH) + 1); + } + + public final void appendTo(StringBuffer buffer, int value) { + if (value < 10) { + buffer.append((char)(value + '0')); + } else { + buffer.append((char)(value / 10 + '0')); + buffer.append((char)(value % 10 + '0')); + } + } + } + + /** + *

Inner class to output a padded number.

+ */ + private static class PaddedNumberField implements NumberRule { + private final int mField; + private final int mSize; + + PaddedNumberField(int field, int size) { + if (size < 3) { + // Should use UnpaddedNumberField or TwoDigitNumberField. + throw new IllegalArgumentException(); + } + mField = field; + mSize = size; + } + + public int estimateLength() { + return 4; + } + + public void appendTo(StringBuffer buffer, Calendar calendar) { + appendTo(buffer, calendar.get(mField)); + } + + public final void appendTo(StringBuffer buffer, int value) { + if (value < 100) { + for (int i = mSize; --i >= 2; ) { + buffer.append('0'); + } + buffer.append((char)(value / 10 + '0')); + buffer.append((char)(value % 10 + '0')); + } else { + int digits; + if (value < 1000) { + digits = 3; + } else { + digits = (int)(Math.log(value) / LOG_10) + 1; + } + for (int i = mSize; --i >= digits; ) { + buffer.append('0'); + } + buffer.append(Integer.toString(value)); + } + } + } + + /** + *

Inner class to output a two digit number.

+ */ + private static class TwoDigitNumberField implements NumberRule { + private final int mField; + + TwoDigitNumberField(int field) { + mField = field; + } + + public int estimateLength() { + return 2; + } + + public void appendTo(StringBuffer buffer, Calendar calendar) { + appendTo(buffer, calendar.get(mField)); + } + + public final void appendTo(StringBuffer buffer, int value) { + if (value < 100) { + buffer.append((char)(value / 10 + '0')); + buffer.append((char)(value % 10 + '0')); + } else { + buffer.append(Integer.toString(value)); + } + } + } + + /** + *

Inner class to output a two digit year.

+ */ + private static class TwoDigitYearField implements NumberRule { + static final TwoDigitYearField INSTANCE = new TwoDigitYearField(); + + TwoDigitYearField() { + } + + public int estimateLength() { + return 2; + } + + public void appendTo(StringBuffer buffer, Calendar calendar) { + appendTo(buffer, calendar.get(Calendar.YEAR) % 100); + } + + public final void appendTo(StringBuffer buffer, int value) { + buffer.append((char)(value / 10 + '0')); + buffer.append((char)(value % 10 + '0')); + } + } + + /** + *

Inner class to output a two digit month.

+ */ + private static class TwoDigitMonthField implements NumberRule { + static final TwoDigitMonthField INSTANCE = new TwoDigitMonthField(); + + TwoDigitMonthField() { + } + + public int estimateLength() { + return 2; + } + + public void appendTo(StringBuffer buffer, Calendar calendar) { + appendTo(buffer, calendar.get(Calendar.MONTH) + 1); + } + + public final void appendTo(StringBuffer buffer, int value) { + buffer.append((char)(value / 10 + '0')); + buffer.append((char)(value % 10 + '0')); + } + } + + /** + *

Inner class to output the twelve hour field.

+ */ + private static class TwelveHourField implements NumberRule { + private final NumberRule mRule; + + TwelveHourField(NumberRule rule) { + mRule = rule; + } + + public int estimateLength() { + return mRule.estimateLength(); + } + + public void appendTo(StringBuffer buffer, Calendar calendar) { + int value = calendar.get(Calendar.HOUR); + if (value == 0) { + value = calendar.getLeastMaximum(Calendar.HOUR) + 1; + } + mRule.appendTo(buffer, value); + } + + public void appendTo(StringBuffer buffer, int value) { + mRule.appendTo(buffer, value); + } + } + + /** + *

Inner class to output the twenty four hour field.

+ */ + private static class TwentyFourHourField implements NumberRule { + private final NumberRule mRule; + + TwentyFourHourField(NumberRule rule) { + mRule = rule; + } + + public int estimateLength() { + return mRule.estimateLength(); + } + + public void appendTo(StringBuffer buffer, Calendar calendar) { + int value = calendar.get(Calendar.HOUR_OF_DAY); + if (value == 0) { + value = calendar.getMaximum(Calendar.HOUR_OF_DAY) + 1; + } + mRule.appendTo(buffer, value); + } + + public void appendTo(StringBuffer buffer, int value) { + mRule.appendTo(buffer, value); + } + } + + /** + *

Inner class to output a time zone name.

+ */ + private static class TimeZoneNameRule implements Rule { + private final TimeZone mTimeZone; + private final boolean mTimeZoneForced; + private final Locale mLocale; + private final int mStyle; + private final String mStandard; + private final String mDaylight; + + TimeZoneNameRule(TimeZone timeZone, boolean timeZoneForced, Locale locale, int style) { + mTimeZone = timeZone; + mTimeZoneForced = timeZoneForced; + mLocale = locale; + mStyle = style; + + if (timeZoneForced) { + mStandard = getTimeZoneDisplay(timeZone, false, style, locale); + mDaylight = getTimeZoneDisplay(timeZone, true, style, locale); + } else { + mStandard = null; + mDaylight = null; + } + } + + public int estimateLength() { + if (mTimeZoneForced) { + return Math.max(mStandard.length(), mDaylight.length()); + } else if (mStyle == TimeZone.SHORT) { + return 4; + } else { + return 40; + } + } + + public void appendTo(StringBuffer buffer, Calendar calendar) { + if (mTimeZoneForced) { + if (mTimeZone.useDaylightTime() && calendar.get(Calendar.DST_OFFSET) != 0) { + buffer.append(mDaylight); + } else { + buffer.append(mStandard); + } + } else { + TimeZone timeZone = calendar.getTimeZone(); + if (timeZone.useDaylightTime() && calendar.get(Calendar.DST_OFFSET) != 0) { + buffer.append(getTimeZoneDisplay(timeZone, true, mStyle, mLocale)); + } else { + buffer.append(getTimeZoneDisplay(timeZone, false, mStyle, mLocale)); + } + } + } + } + + /** + *

Inner class to output a time zone as a number +/-HHMM + * or +/-HH:MM.

+ */ + private static class TimeZoneNumberRule implements Rule { + static final TimeZoneNumberRule INSTANCE_COLON = new TimeZoneNumberRule(true); + static final TimeZoneNumberRule INSTANCE_NO_COLON = new TimeZoneNumberRule(false); + + final boolean mColon; + + TimeZoneNumberRule(boolean colon) { + mColon = colon; + } + + public int estimateLength() { + return 5; + } + + public void appendTo(StringBuffer buffer, Calendar calendar) { + int offset = calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET); + + if (offset < 0) { + buffer.append('-'); + offset = -offset; + } else { + buffer.append('+'); + } + + int hours = offset / (60 * 60 * 1000); + buffer.append((char)(hours / 10 + '0')); + buffer.append((char)(hours % 10 + '0')); + + if (mColon) { + buffer.append(':'); + } + + int minutes = offset / (60 * 1000) - 60 * hours; + buffer.append((char)(minutes / 10 + '0')); + buffer.append((char)(minutes % 10 + '0')); + } + } + + // ---------------------------------------------------------------------- + /** + *

Inner class that acts as a compound key for time zone names.

+ */ + private static class TimeZoneDisplayKey { + private final TimeZone mTimeZone; + private final int mStyle; + private final Locale mLocale; + + TimeZoneDisplayKey(TimeZone timeZone, + boolean daylight, int style, Locale locale) { + mTimeZone = timeZone; + if (daylight) { + style |= 0x80000000; + } + mStyle = style; + mLocale = locale; + } + + public int hashCode() { + return mStyle * 31 + mLocale.hashCode(); + } + + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof TimeZoneDisplayKey) { + TimeZoneDisplayKey other = (TimeZoneDisplayKey)obj; + return + mTimeZone.equals(other.mTimeZone) && + mStyle == other.mStyle && + mLocale.equals(other.mLocale); + } + return false; + } + } + + // ---------------------------------------------------------------------- + /** + *

Helper class for creating compound objects.

+ * + *

One use for this class is to create a hashtable key + * out of multiple objects.

+ */ + private static class Pair { + private final Object mObj1; + private final Object mObj2; + + public Pair(Object obj1, Object obj2) { + mObj1 = obj1; + mObj2 = obj2; + } + + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (!(obj instanceof Pair)) { + return false; + } + + Pair key = (Pair)obj; + + return + (mObj1 == null ? + key.mObj1 == null : mObj1.equals(key.mObj1)) && + (mObj2 == null ? + key.mObj2 == null : mObj2.equals(key.mObj2)); + } + + public int hashCode() { + return + (mObj1 == null ? 0 : mObj1.hashCode()) + + (mObj2 == null ? 0 : mObj2.hashCode()); + } + + public String toString() { + return "[" + mObj1 + ':' + mObj2 + ']'; + } + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/time/StopWatch.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/time/StopWatch.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/time/StopWatch.java 30 Aug 2012 16:24:43 -0000 1.1 @@ -0,0 +1,201 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 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 acknowledgement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgement may appear in the software itself, + * if and wherever such third-party acknowledgements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.time; + +/** + *

StopWatch provides a convenient API for timings.

+ * + *

The methods do not protect against inappropriate calls. Thus you + * can call stop before start, resume before suspend or unsplit before split. + * The results are indeterminate in these cases.

+ * + *

To start the watch, call {@link #start()}. At this point you can:

+ *
    + *
  • {@link #split()} the watch to get the time whilst the watch continues in the + * background. {@link #unsplit()} will remove the effect of the split. At this point, + * these three options are available again.
  • + *
  • {@link #suspend()} the watch to pause it. {@link #resume()} allows the watch + * to continue. Any time between the suspend and resume will not be counted in + * the total. At this point, these three options are available again.
  • + *
  • {@link #stop()} the watch to complete the timing session.
  • + *
+ * + *

It is intended that the output methods {@link #toString()} and {@link #getTime()} + * should only be called after stop, split or suspend, however a suitable result will + * be returned at other points.

+ * + * @author Henri Yandell + * @author Stephen Colebourne + * @since 2.0 + * @version $Id: StopWatch.java,v 1.1 2012/08/30 16:24:43 marcin Exp $ + */ +public class StopWatch { + + /** + * The start time. + */ + private long startTime = -1; + /** + * The stop time. + */ + private long stopTime = -1; + + /** + *

Constructor.

+ */ + public StopWatch() { + } + + /** + *

Start the stopwatch.

+ * + *

This method starts a new timing session, clearing any previous values.

+ */ + public void start() { + stopTime = -1; + startTime = System.currentTimeMillis(); + } + + /** + *

Stop the stopwatch.

+ * + *

This method ends a new timing session, allowing the time to be retrieved.

+ */ + public void stop() { + stopTime = System.currentTimeMillis(); + } + + /** + *

Reset the stopwatch.

+ * + *

This method clears the internal values to allow the object to be reused.

+ */ + public void reset() { + startTime = -1; + stopTime = -1; + } + + /** + *

Split the time.

+ * + *

This method sets the stop time of the watch to allow a time to be extracted. + * The start time is unaffected, enabling {@link #unsplit()} to contine the + * timing from the original start point.

+ */ + public void split() { + stopTime = System.currentTimeMillis(); + } + + /** + *

Remove a split.

+ * + *

This method clears the stop time. The start time is unaffected, enabling + * timing from the original start point to continue.

+ */ + public void unsplit() { + stopTime = -1; + } + + /** + *

Suspend the stopwatch for later resumption.

+ * + *

This method suspends the watch until it is resumed. The watch will not include + * time between the suspend and resume calls in the total time.

+ */ + public void suspend() { + stopTime = System.currentTimeMillis(); + } + + /** + *

Resume the stopwatch after a suspend.

+ * + *

This method resumes the watch after it was suspended. The watch will not include + * time between the suspend and resume calls in the total time.

+ */ + public void resume() { + startTime += (System.currentTimeMillis() - stopTime); + stopTime = -1; + } + + /** + *

Get the time on the stopwatch.

+ * + *

This is either the time between start and latest split, between start + * and stop, or the time between the start and the moment this method is called.

+ * + * @return the time in milliseconds + */ + public long getTime() { + if (stopTime == -1) { + if (startTime == -1) { + return 0; + } + return (System.currentTimeMillis() - this.startTime); + } + return (this.stopTime - this.startTime); + } + + /** + *

Gets a summary of the time that the stopwatch recorded as a string.

+ * + *

The format used is ISO8601-like, + * hours:minutes:seconds.milliseconds.

+ * + * @return the time as a String + */ + public String toString() { + return DurationFormatUtils.formatISO(getTime()); + } + +} Index: 3rdParty_sources/commons-lang/org/apache/commons/lang/time/package.html =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-lang/org/apache/commons/lang/time/package.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-lang/org/apache/commons/lang/time/package.html 30 Aug 2012 16:24:43 -0000 1.1 @@ -0,0 +1,15 @@ + + +

+Provides classes and methods to work with dates and durations. +

+This includes: +

    +
  • DateUtils - a set of static utility methods for working with dates +
  • FastDateFormat - a replacement for SimpleDateFormat that is fast and thread-safe +
  • DateFormatUtils - a formatting class for dates +
  • StopWatch - a duration timer +
+@since 2.0 + + Index: lams_build/3rdParty.userlibraries =================================================================== RCS file: /usr/local/cvsroot/lams_build/3rdParty.userlibraries,v diff -u -r1.56 -r1.57 --- lams_build/3rdParty.userlibraries 22 Aug 2012 17:28:46 -0000 1.56 +++ lams_build/3rdParty.userlibraries 30 Aug 2012 16:24:27 -0000 1.57 @@ -26,7 +26,7 @@ - +