/* * StringUtil, utility class for string operations. * Copyright (C) 2004 - 2011 Achim Westermann. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * If you modify or optimize the code in a useful way please let me know. * Achim.Westermann@gmx.de * */ package info.monitorenter.util; import java.lang.reflect.Array; import java.util.List; /** * Nice static helpers for working with Strings. * <p> * Maybe not always the fastest solution to call in here, but working. Also * usable for seeing examples and cutting code for manual inlining. * <p> * * @author Achim.Westermann@gmx.de * * @version $Revision: 1.10 $ */ public final class StringUtil { /** Singleton instance. */ private static StringUtil instance = null; /** * Appends the given amount of spaces to the String. * <p> * * Not intended for big append -operations because in a loop alway just one * space is added. * <p> * * @param s * the base String to append spaces to. * * @param count * the amount of spaces to append. * * @return a String consisting of s and count trailing whitespaces. */ public static final String appendSpaces(final String s, final int count) { StringBuffer tmp = new StringBuffer(s); for (int i = 0; i < count; i++) { tmp.append(" "); } return tmp.toString(); } /** * Little String output - helper that modifies the given LinkedList by getting * it's Objects and replace them by their toString() - representation. * <p> * * What is special? <br> * If an Object in the given List is an Array (of Objects or primitive data * types) reflection will be used to create a String - representation of them. * The changes are reflected in the Objects that are in the given List. So * keep a reference to it. If you are sure, that your List does not contain * Arrays do not use this method to avoid overhead. * <p> * * Avoid structural modifications (remove) of the list while using this * method. This method or better: the given List is only thread - safe if the * list is synchronized. * <p> * * A clever VM (hotspot) will be able to inline this function because of void * return. * <p> * * @param objects * the List of objects that will be changed to a list of the String * representation of the Objects with respect to special array * treatment. * */ public static final void listOfArraysToString(final List<Object> objects) { if (objects == null) { return; } int stop = objects.size(); for (int i = 0; i < stop; i++) { objects.add(i, StringUtil.arrayToString(objects.remove(i))); } } /** * If the given Object is no Array, it's toString - method is invoked. * Primitive type - Arrays and Object - Arrays are introspected using * java.lang.reflect.Array. Convention for creation fo String - * representation: <p> * * @see StringUtil#arrayToString(Object, String) * * @param isArr * The Array to represent as String. * * @return a String-representation of the Object. * * */ public static final String arrayToString(final Object isArr) { String result = StringUtil.arrayToString(isArr, ","); return result; } /** * If the given Object is no Array, it's toString - method is invoked. * Primitive type - Arrays and Object - Arrays are introspected using * java.lang.reflect.Array. Convention for creation for String - * representation: <br> * * <code> * // Primitive arrays: * "["+isArr[0]+"<separator>"+isArr[1]+.. ..+isArr[isArr.length-1]+"]" * * * //Object arrays : * "["+isArr[0].toString()+"<separator>"+.. ..+isArr[isArr.length-1].toString+"]" * // Two or three - dimensional Arrays are not supported * //(should be reflected in a special output method, e.g.as a field) * * // other Objects: * toString() * </code> * * @param separator put in-between each array element in the resulting string. * * @param isArr * The Array to represent as String. * * @return a String-representation of the Object. * * */ public static final String arrayToString(final Object isArr, final String separator) { String result; if (isArr == null) { result = "null"; } else { Object element; StringBuffer tmp = new StringBuffer(); try { int length = Array.getLength(isArr); tmp.append("["); for (int i = 0; i < length; i++) { element = Array.get(isArr, i); if (element == null) { tmp.append("null"); } else { tmp.append(element.toString()); } if (i < length - 1) { tmp.append(separator); } } tmp.append("]"); result = tmp.toString(); } catch (ArrayIndexOutOfBoundsException bound) { // programming mistake or bad Array.getLength(obj). tmp.append("]"); result = tmp.toString(); } catch (IllegalArgumentException noarr) { result = isArr.toString(); } } return result; } /** * Returns the system - dependent line separator. * <p> * * Only call this method once (not in a loop) and keep the result. * <p> * * @return the system - dependent line separator. */ public static String getNewLine() { return System.getProperty("line.separator"); } /** * Returns the singleton instance of this class. * <p> * * This method is useless for now as all methods are static. It may be used in * future if VM-global configuration will be put to the state of the instance. * <p> * # * * @return the singleton instance of this class. */ public static StringUtil instance() { if (StringUtil.instance == null) { StringUtil.instance = new StringUtil(); } return StringUtil.instance; } /** * Returns true if the argument is null or consists of whitespaces only. * <p> * * @param test * the <code>String</code> to test. * * @return true if the argument is null or consists of whitespaces only. */ public static boolean isEmpty(final String test) { boolean result; if (test == null) { result = true; } else { result = test.trim().length() == 0; } return result; } /** * Returns the maximum length of a {@link Object#toString()} result in * characters within the given List. * <p> * * No data is changed in the given List at all. But the String - * representation of all Objects, even Arrays is build to inspect. <br> * Convention for creation fo String - representation: <br> * * <pre> * Primitive Arrays : as performed by this classes @see #ArrayToString. * Object Arrays : as performed by this classes @see #ArrayToString * other Objects : toString() (as performed by this classes @see #ArrayToString). * </pre> * * @param objects * the <code>List<Object></code> to inspect for the maximum * length of a {@link Object#toString()} result. * * @return The length of the longest String - representation of an Object in * the List <b>or 0 if objects was null or of size 0. </b> */ public static final int longestStringRepresentation(final List<Object> objects) { int result; if (objects == null) { result = 0; } else { int maxsize = 0; int tint = 0; String tmp; int stop = objects.size(); for (int i = 0; i < stop; i++) { tmp = StringUtil.arrayToString(objects.get(i)); tint = tmp.length(); if (tint > maxsize) { maxsize = tint; } } // maximum size known. result = maxsize; } return result; } /** * Appends the necessary amount of spaces to the string until it has the givn * length. No Exception is thrown, if the length of the String is shorter than * the given length, but nothing will happen and a message will be printed to * the System.out. * * * @param s * the String to expand. * @param length * the desired length of the String to be returned. * @return A String that represents the content of the old String including * extra whitespaces. */ public static final String setSize(final String s, final int length) { String result = s; int oldlen = s.length(); if (oldlen > length) { System.err.println("greenpeace.util.setSize(String s,int length): length (" + length + ") is smaller than s.length(" + oldlen + ") : " + s); } else { int tofill = length - oldlen; result = StringUtil.appendSpaces(s, tofill); } return result; } /** * Modifies the given LinkedList by getting it's Objects and replace them by * their toString() - representation concatenated with the necessary amount of * white spaces that every String in the List will have the same amount of * characters. * <p> * * Only use this method in following case: <br> * <ul> * <li>You have got an AbstractList or subclass containing Objects you do not * know.</li> * <li>You want to transform all Elements in the List to Strings.</li> * <li>There might be Array's in the Object (whose toString method will return * only their hashcode).</li> * </ul> * <p> * * What happens? * <ul> * <li>All Objects, even primitive Arrays in your List will be turned to * String- representation.</li> * <li>The result will replace the old position of the Object in the given * List. The old Objects will get lost!</li> * <li>All Strings will be filled with whitespaces until each String has the * same length.</li> * </ul> * At least this method will be speeded up by a hotspot VM by inlining this * method. <br> * <i>An example: <br> * You just retrieved data from a db using jdbc and a generic class * (resultset.getObject()). You want to print the data to System.out or to * save it to a file, but do not know, if Arrays are contained. You want the * output to be formatted (each line). </i> * <p> * * @param objects * contains the Objects to replace by their toString() * representation. */ public static final void toLongestString(final List<Object> objects) { if (objects == null) { return; } int maxsize = 0; int tint = 0; String tmp; int stop = objects.size(); for (int i = 0; i < stop; i++) { StringUtil.arrayToString(objects.get(i)); tmp = (String) objects.get(i); tint = tmp.length(); if (tint > maxsize) { maxsize = tint; } objects.add(i, tmp); } // maximum size known. for (int i = 0; i < stop; i++) { objects.add(i, StringUtil.setSize((String) objects.remove(i), maxsize)); } } /** * Avoids creation from outside for singleton support. * <p> * */ private StringUtil() { // nop } }