/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the reusable ccl java library * (http://www.kclee.com/clemens/java/ccl/). * * The Initial Developer of the Original Code is * Chr. Clemens Lee. * Portions created by Chr. Clemens Lee are Copyright (C) 2002 * Chr. Clemens Lee. All Rights Reserved. * * Contributor(s): Chr. Clemens Lee <clemens@kclee.com> * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ package ccl.util; import java.io.*; import java.lang.reflect.Field; import java.net.InetAddress; import java.text.DecimalFormat; import java.text.NumberFormat; import java.text.SimpleDateFormat; import java.util.*; interface Comparable { public int compare(Object o1,Object o2); } /** * A general purpose class with a variety of support and convenience methods. * * <p> There are different groups of methods in this class: * <br> * <br><a href="#setDebug(boolean)">debug and assertion methods</a> * <br><a href="#print(char)">print methods</a> - convenience methods for System.out.print etc. that additionally make sure output is gets flushed immediately. * <br><a href="#atoi(java.lang.String)">basic converter methods</a> * <br><a href="#isEmpty(java.lang.String)">string methods</a> * <br><a href="#concat(java.util.Vector)">string/vector converter methods</a> * <br><a href="#toVector(java.util.Enumeration)">vector methods</a> * <br><a href="#quickSort(java.lang.Object[], int, int, ccl.util.Comparable)">sorting and inserting methods</a> * <br><a href="#system(java.lang.String)">system methods</a> * <br><a href="#getStandardDate(java.util.Date)">date methods</a> * <br><a href="#rnd()">random generator methods</a> * <br><a href="#getConstantObject()">miscellaneous methods</a> * <p> * * Some basic but none the less the most used methods by myself are:<br> * - {@link #println(java.lang.String) println}<br> * - {@link #printlnErr(java.lang.Exception) printlnErr}<br> * - {@link #isEmpty(java.lang.String) isEmpty}<br> * - {@link #stringToLines(java.lang.String) stringToLines}<br> * - {@link #atoi(java.lang.String) atoi}<br> * - {@link #itoa(int) itoa}<br> * - {@link #systemAndWait(java.util.Vector) systemAndWait}<br> * - {@link #sleep(int) sleep}<br> * - {@link #getDate() getDate} * <p> * * But there are also some gems which are less regularly used but still quite * usefull:<br> * - {@link #getStackTrace(java.lang.Throwable)}<br> * - {@link #getDump(java.lang.Object)}<br> * - {@link #formatMemoryInfo()}<br> * - {@link #denullify(java.lang.String)}<br> * - {@link #formatBlock(java.lang.String, int)} * <p> * * Potential future but not yet existing classes to move some code into * are:<br> * StringUtil, VectorUtil, SystemUtil, and maybe Debug. * * @version $Id: Util.java,v 1.1 2005/10/30 22:22:35 ksen Exp $ * @author <a href="http://www.kclee.com/clemens/"> * Chr. Clemens Lee</a> * <<a href="mailto:clemens@kclee.com"> * clemens@kclee.com * </a>> */ public class Util { // ----------------------------------------------------- // attributes // ----------------------------------------------------- private static Random _rnd = new Random(); private static Object _objSwap = null; private static boolean _bNochKeinSwap = true; private static int _swap = -1; private static boolean _bNochKeinIntSwap = true; private static final char[] AC_UMLAUT = { '�', '�', '�', '�', '�', '�', '�', '�' }; /** * Used to store the debug state. Can be changed during * runtime for more flexibility. This is more important * to me than speed. */ private static boolean _bDebug = false; /** * This could be also private and instead you would have * to use getConstantObject(), but yet you have the * choice. * * @see #getConstantObject() */ public static final Object O_CONSTANT = new Object(); // ----------------------------------------------------- // constructor // ----------------------------------------------------- /** * This is an utility class, there is (should be) no need * for an instance of this class. */ private Util() { super(); } // ----------------------------------------------------- // debug methods and assertion stuff // ----------------------------------------------------- /** * Sets the debug mode for the running application. When * true, all following debug statements are equal to println * statements, otherwise they are ignored. * * @see #debug(Object) */ public static void setDebug( boolean bDebug_ ) { _bDebug = bDebug_; } /** * Returns the current debug mode. * * @return the current debug mode. */ public static boolean isDebug() { return _bDebug; } /** * Sets the debug mode for the running application. When * true, all following debug statements are equal to * printlnErr statements, otherwise they are ignored. * * @see #debug(Object) */ public static void setDebug( String sDebug_ ) { setDebug( atob( sDebug_ ) ); } /** * If the debug mode was set with the setDebug function * to true, this debug statements is equal to a printlnErr * statement, otherwise it will be ignored. * * @see #setDebug(boolean) */ public static void debug( Object oMessage_ ) { if ( _bDebug ) { printlnErr( oMessage_.toString() ); } } /** * If the debug mode was set with the setDebug function * to true, this debug statements is equal to a printlnErr * statement, otherwise it will be ignored. * * @see #setDebug(boolean) */ public static void debug(int i) { debug( "int: " + i ); } /** * If the debug mode was set with the setDebug function * to true, this debug statements is equal to a printlnErr * statement, otherwise it will be ignored. * * @see #setDebug(boolean) * @see #printlnErr(java.lang.Object, java.lang.Object) */ public static void debug( Object oOriginator_, Object oMessage_ ) { if ( _bDebug ) { printlnErr( oOriginator_, oMessage_ ); } } /** * panicIf <=> not assert. Throws ApplicationException if true. * It's not necessary to catch this exception. * * @see ApplicationException */ public static void panicIf(boolean bPanic_) { if (bPanic_) { throw(new ApplicationException()); } } /** * panicIf <=> not assert. Throws ApplicationException if true. * It's not necessary to catch this exception. * * @param sMessage_ The error message for the Exception. * * @see ApplicationException */ public static void panicIf(boolean bPanic_, String sMessage_) { if (bPanic_) { throw(new ApplicationException(sMessage_)); } } /** * Most people are used to assertions. But I once came up * with panicIf(boolean) and that's what I still prefer * to use. * * @deprecated use 'assert' keyword from jdk 1.4 or above. */ // public static void assert( boolean bAssert_ ) // { // panicIf( !bAssert_ ); // } // // /** // * Assert pObject is not null. // * // * @deprecated use 'assert' keyword from jdk 1.4 or above. // */ // public static void assert( Object pObject_ ) // { // panicIf( pObject_ == null ); // } // ----------------------------------------------------- // print methods // ----------------------------------------------------- /** * Prints out a char to System.out. * Unlike using System.out directly this * method makes sure the content gets flushed out immediately. */ public static void print(char c_) { System.out.print(c_); System.out.flush(); } /** * Prints out a String to System.out. * Unlike using System.out directly this * method makes sure the content gets flushed out immediately. */ public static void print(String pString_) { System.out.print(pString_); System.out.flush(); } /** * Prints out the object to System.out. * Unlike using System.out directly this * method makes sure the content gets flushed out immediately. */ public static void print(Object pObject_) { if (pObject_ == null) { print("null"); } else { print(pObject_.toString()); } } /** * Prints out a String to System.out together with a * new line. * Unlike using System.out directly this * method makes sure the content gets flushed out immediately. * * @param pString_ a string without a trailing newline to send * to standard output. */ public static void println( String pString_ ) { System.out.println(pString_); System.out.flush(); } /** * Prints out the exception, its stack trace, * and the current thread to System.out! * Unlike using System.out directly this * method makes sure the content gets flushed out immediately. * * @see #printlnErr(java.lang.Exception) printlnErr */ public static void println(Exception e) { System.out.println("Exception: " + e.getMessage()); /*//e.fillInStackTrace(); //e.printStackTrace(System.out);*/ Thread.dumpStack(); println(Thread.currentThread().toString()); } /** * Prints out the object to System.out together with a * new line. * Unlike using System.out directly this * method makes sure the content gets flushed out immediately. */ public static void println(Object pObject_) { print(pObject_); print('\n'); } /** * Same as print('\n'). * * @see #print(char) print */ public static void println() { print('\n'); } /** * Prints out a char to System.err. */ public static void printErr(char c_) { System.err.print(c_); System.err.flush(); } /** * Prints out a String to System.err. */ public static void printErr(String pString_) { System.err.print(pString_); System.err.flush(); } /** * Prints out the object to System.err. */ public static void printErr( Object pObject_ ) { if (pObject_ == null) { printErr( "null" ); } else { printErr( pObject_.toString() ); } } /** * The same as println, except output goes to std err. */ public static void printlnErr() { printErr( '\n' ); } /** * The same as println, except output goes to std err. * Unlike using System.err directly this * method makes sure the content gets flushed out immediately. * * @param sMessage_ a string without a trailing newline to send * to standard error. */ public static void printlnErr( String sMessage_ ) { printErr( sMessage_ ); printlnErr(); } /** * Prints out the object to System.err. * Unlike using System.err directly this * method makes sure the content gets flushed out immediately. * * @param pObject_ an object that will be converted to a string which * will be sent to standard error with a newline appended. */ public static void printlnErr( Object pObject_ ) { if ( pObject_ == null ) { printlnErr( "null" ); } else { printlnErr( pObject_.toString() ); } } /** * Prints out an error report for an exception to * System.err. Prints out the exception message * followed by its stack trace. * Unlike using System.err directly this * method makes sure the content gets flushed out immediately. * * @param exception_ the exception to print to * standard error. */ public static void printlnErr( Exception exception_ ) { printlnErr( exception_.getMessage() ); printlnErr( getStackTrace( exception_ ) ); } /** * Prints out a String with a prefix of the oClass_ class * name to System.err. */ public static void printlnErr( Object oClass_, Object oMessage_ ) { Util.panicIf( oClass_ == null ); printErr( oClass_.getClass().getName() + "." ); printlnErr( oMessage_ ); } /** * For batch applications to indicate progess to the user. */ public static void showLiveSignal() { showLiveSignal( '.' ); } /** * For batch applications to indicate progess to the user. * * @param c_ The char that should be printed to * stdout. */ public static void showLiveSignal( char c_ ) { print( c_ ); } // ----------------------------------------------------- // basic converter methods // ----------------------------------------------------- /** * String to int converter. */ public static int atoi( String pString_ ) { if (isEmpty(pString_)) { return 0; } int result = 0; boolean bNegative = false; int index = 0; int max = pString_.length(); int limit = 0; int multmin = 0; int digit = 0; while( (index < max - 1) && pString_.charAt( index ) == ' ') { index++; } if ( pString_.charAt( index ) == '-') { bNegative = true; limit = Integer.MIN_VALUE; index++; } else { limit = -Integer.MAX_VALUE; } multmin = limit / 10; if ( index < max ) { digit = Character.digit( pString_.charAt( index++ ), 10 ); if ( digit < 0 ) { return 0; } else { result = -digit; } } while( index < max ) { // Accumulating negatively avoids surprises near MAX_VALUE digit = Character.digit( pString_.charAt( index++ ), 10 ); if ( digit < 0 ) { break; } if ( result < multmin ) { break; } result *= 10; if ( result < limit + digit ) { break; } result -= digit; } if ( !bNegative ) { result = -result; } return( result ); } /** * String to long converter. */ public static long atol( String pString_ ) { return Long.parseLong( pString_, 10 ); } /** * Converts an int to a String. */ public static String itoa( int i_ ) { return(String.valueOf(i_)); } /** * Converts an long to a String. */ public static String ltoa( long l_ ) { return( String.valueOf( l_ ) ); } /** * Converts a double to a String. */ public static String dtoa( double d_ ) { return( String.valueOf( d_ ) ); } /** * String to float converter. An empty string gets * converted to 0.0, while a string that is not * adequately formatted results in NaN (not a number). */ public static float atof( String pString_ ) { float fRetVal = 0.0f; if (isEmpty(pString_)) { return fRetVal; } try { fRetVal = Float.valueOf( pString_ ).floatValue(); } catch( NumberFormatException pNumberFormatException ) { fRetVal = Float.NaN; } return fRetVal; } /** * String to double converter. An empty string gets * converted to 0.0, while a string that is not * adequately formatted results in NaN (not a number). * '\'' chars are removed from the String before processing * takes place. */ public static double atod( String pString_ ) { double dRetVal = 0.0; String pString = Util.replace( pString_, "'", "" ); if (isEmpty(pString)) { return dRetVal; } try { dRetVal = Double.valueOf( pString ).doubleValue(); } catch( NumberFormatException pNumberFormatException ) { dRetVal = Double.NaN; } return dRetVal; } /** * A long to double converter. * * @param l_ the long value to convert to a double. * * @return the double equivalent to the given long. */ public static double ltod( long l_ ) { return (double) l_; } /** * Converts an int into a byte array. First byte has the highest * value. * * @see #bytesToInt(byte[]) */ public static byte[] intToBytes( int i_ ) { byte abInt[] = new byte[4]; abInt[3] = (byte) (i_ & 255); abInt[2] = (byte) ((i_ >> 8) & 255); abInt[1] = (byte) ((i_ >> 16) & 255); abInt[0] = (byte) (i_ >> 24); return abInt; } /** * Converts a byte array into an int. First byte has the highest * value. * * @see #intToBytes(int) */ public static int bytesToInt( byte[] abInt ) { Util.panicIf(abInt.length != 4); Util.debug("Util.bytesToInt(): abInt: " + abInt[0] + "," + abInt[1] + "," + abInt[2] + "," + abInt[3]); int byteValue3 = (256 + abInt[3]) & 255; int byteValue2 = ((256 + abInt[2]) & 255) * 256; int byteValue1 = ((256 + abInt[1]) & 255) * 256 * 256; int byteValue0 = ((256 + abInt[0]) & 255) * 256 * 256 * 256; int i = byteValue0 | byteValue1 | byteValue2 | byteValue3; return i; } /** * Converts a byte to a char. */ public static char byteToChar( byte b_ ) { int intValue = (256 + b_) & 255; return((char) intValue); } /** * Converts a byte to an int. * * @deprecated Use byteToInt(byte) instead. */ public static int btoi( byte b_ ) { return byteToInt( b_ ); } /** * Converts a byte to an int. */ public static int byteToInt( byte b_ ) { int intValue = (256 + b_) & 255; return( intValue ); } /** * Converts a byte to a String. */ public static String byteToString( byte b_ ) { return cToS( byteToChar( b_ ) ); } /** * A character to String converter. */ public static String cToS(char c_) { return(new Character(c_).toString()); } /** * Works with ints instead of chars. */ public static int toUpperCase( int character_ ) { String sTemp = "" + (char) character_; int retVal = sTemp.toUpperCase().charAt( 0 ); return retVal; } /** * Works with ints instead of chars. */ public static int toLowerCase( int character_ ) { String sTemp = "" + (char) character_; int retVal = sTemp.toLowerCase().charAt( 0 ); return retVal; } /** * Converts a String to a boolean. * It's true if the string consists of the word "true" * ignoring case, otherwise it returns false. * * @return ((pString_ != null) && pString_.toLowerCase().equals("true")); */ public static boolean atob( String pString_ ) { return(Boolean.valueOf(pString_).booleanValue()); } /** * Boolean to boolean converter. * * @return true if input is true, false otherwise or if input * is null. */ public static boolean isTrue( Boolean pBoolean_ ) { if (pBoolean_ == null) { return false; } return pBoolean_.booleanValue(); } // ----------------------------------------------------- // string methods // ----------------------------------------------------- /** * Tests, if a given String equals null or "". */ public static boolean isEmpty( String sTest_ ) { if (sTest_ == null || sTest_.equals("")) { return true; } return false; } /** * Count how often a string contains a special char. */ public static int getOccurances(String source, int zeichen) { int anzahl = -1; int index = 0; do { index = source.indexOf(zeichen, index) + 1; anzahl++; } while( index != 0 ); return( anzahl ); } /** * Count how often a string is contained in another string. */ public static int getOccurances( String source_ , String lookFor_ ) { int count = -1; int index = 0; do { index = source_.indexOf( lookFor_, index ) + 1; count++; } while( index != 0 ); return count; } /** * Create a string by concatenating one char several times. */ public static String multiplyChar(char c, int anzahl) { String s = ""; while (anzahl > 0) { s += c; anzahl--; } return(s); } /** * Create a string by concatenating one string several times. * The method name should maybe renamed to multiplyString or * something else. */ public static String multiplyChar(String sFill, int anzahl) { String sRet = ""; while (anzahl > 0) { sRet += sFill; anzahl--; } return(sRet); } /** * Returns a String which consists only of spaces and has the * lenght 'length_' or which is empty if length_ equals zero. */ public static String getSpaces(int length_) { Util.panicIf(length_ < 0); if (length_ == 0) { return ""; } String sSpaces = " "; if (length_ > sSpaces.length()) { return multiplyChar(' ', length_); } return(sSpaces.substring(0, length_)); } /** * Append spaces to the end of a string. The returned string will always * have exactly the requested length_. */ public static String appendSpaces( String pString_, int length_ ) { if ( pString_ == null ) { return getSpaces( length_ ); } String sRetVal = pString_ + getSpaces( length_ ); return sRetVal.substring( 0, length_ ); } /** * Fill a string with a given char for alignment purposes. */ public static String paddWith(int number_, int stellen_, char cPadd_) { return paddWith(itoa(number_), stellen_, cPadd_); } /** * Fill a string with a given char for alignment purposes. */ public static String paddWith(String pString_, int stellen_, char cPadd_) { String sRetVal = new String(pString_); if (sRetVal.length() >= stellen_) { return(sRetVal); } String sPadding = multiplyChar(cPadd_, stellen_ - sRetVal.length()); sRetVal = sPadding + sRetVal; return(sRetVal); } /** * Fill a string with space chars for alignment purposes. */ public static String paddWithSpace(int number, int stellen) { return paddWith(number, stellen, ' '); } /** * Fill a string with space chars for alignment purposes. */ public static String paddWithSpace(long number, int stellen) { return paddWith(ltoa( number ), stellen, ' '); } /** * Fill a string with space chars for alignment purposes. */ public static String paddWithSpace(double dNumber_, int stellen) { return paddWith((new Double(dNumber_)).toString(), stellen, ' '); } /** * Fill a string with space chars for alignment purposes. */ public static String paddWithSpace(String pString_, int stellen) { return paddWith(pString_, stellen, ' '); } /** * Add spaces at the right side of a string if necessary. */ public static String rightPaddWithSpace( String pString_, int stellen ) { StringBuffer sbReturn = new StringBuffer( 32 ); if ( pString_ != null ) { sbReturn.append( pString_ ); } for( int i = 0; i <= stellen / 8; i++ ) { sbReturn.append( " " ); } return sbReturn.toString().substring( 0, stellen ); } /** * Fill a string with zero chars for alignment purposes. */ public static String paddWithZero(int number, int stellen) { return paddWith(number, stellen, '0'); } /** * Fill a string with zero chars for alignment purposes. */ public static String paddWithZero(long number, int stellen) { return paddWith(ltoa( number ), stellen, '0'); } /** * Fill a string with zero chars for alignment purposes. */ public static String paddWithZero( String sNumber_, int stellen_ ) { return paddWith( sNumber_, stellen_, '0'); } /** * What the method name says. */ public static String removeMultipleSpaces(String pString_) { panicIf(pString_ == null); String sRetVal = new String(pString_); int doubleSpaceIndex = sRetVal.indexOf(" "); while(doubleSpaceIndex != -1) { sRetVal = sRetVal.substring(0, doubleSpaceIndex) + sRetVal.substring(doubleSpaceIndex + 1, sRetVal.length()); doubleSpaceIndex = sRetVal.indexOf(" ", doubleSpaceIndex); } return sRetVal; } /** * Removes space, carriage, linefeed, and tab chars at * the right side of a string. */ public static String rtrim(String s) { int index = s.length() - 1; while (index >= 0 && (s.charAt(index) == ' ' || s.charAt( index ) == '\n' || s.charAt( index ) == '\r' || s.charAt( index ) == '\t') ) { index--; } return(s.substring(0, index + 1)); } /** * Removes space, carriage, linefeed, and tab chars at * the right side of a string. */ public static String ltrim(String s) { int index = 0; //s.length()-1; while (index < s.length() && s.charAt(index) == ' ') { index++; } return(s.substring(index, s.length())); } /** * Seems to do the same as 'removeMultipleSpaces(String)'. * One should become deprecated. */ public static String unifySpaces(String s) { String sRetVal = new String(); String sRest = s.trim(); int index = 0;//s.length()-1; while (sRest != null && sRest.length() > 0) { index = sRest.indexOf(' '); if (index < 0) { sRetVal += sRest; sRest = null; } else { sRetVal += sRest.substring(0, index + 1); sRest = sRest.substring(index + 1, sRest.length()); sRest = ltrim(sRest); } } return(sRetVal); } /** * Compares two strings. Upper or lower case characters * are not considered differently. */ public static boolean equalsCaseless(String sA_, String sB_) { String sFirst = sA_.toUpperCase(); String sSecond = sB_.toUpperCase(); return sFirst.equals(sSecond); } /** * Returns the given string with the first char converted * to upper case. */ public static String firstCharToUpperCase(String pString_) { String sRetVal = new String(); if (pString_ == null || pString_.length() == 0) { return(sRetVal); } sRetVal = pString_.substring(0, 1).toUpperCase() + pString_.substring(1, pString_.length()); return(sRetVal); } /** * Returns the given string with the first char converted * to lower case. */ public static String firstCharToLowerCase(String pString_) { String sRetVal = new String(); if (pString_ == null || pString_.length() == 0) { return(sRetVal); } sRetVal = pString_.substring(0, 1).toLowerCase() + pString_.substring(1, pString_.length()); return(sRetVal); } /** * Tests if this string ends with the specified character. */ public static boolean endsWith(String sThis_, char cOther_) { if ( isEmpty( sThis_ ) ) { return false; } return(sThis_.charAt(sThis_.length() - 1) == cOther_); } /** * Tests if this string ends with the second string. */ public static boolean endsWith(String pString_, String sEnd_) { if (isEmpty(sEnd_)) { return true; } else if (isEmpty(pString_)) { return false; } int stringLen = pString_.length(); int endLen = sEnd_.length(); if (endLen > stringLen) { return false; } boolean bRetVal = sEnd_.equals(pString_.substring(stringLen - endLen, stringLen)); return bRetVal; } /** * Replaces all occurences of cOld_ in pString with cNew_. * * @see String#replace(char, char) */ public static String replace(String pString_, char cOld_, char cNew_) { return replace(pString_, cOld_, cNew_, 0); } /** * Replaces all occurences of cOld_ in pString with cNew_. */ public static String replace(String pString_, char cOld_, char cNew_, int startIndex_) { return replace(pString_, cToS(cOld_), cToS(cNew_), startIndex_); } /** * Replaces all occurences of sOld_ in pString with sNew_. * Unlike the String.replace(char, char) method this one accepts whole strings * for replacement and as a consequence also allows to delete sub strings. * * @param pString_ a string that shall get some sub strings replaced. * @param sOld_ a string for which all occurences in the first string shall be replaced. * @param sNew_ a string which will be used for replacement of the old sub strings. * * @return the first string provided but with the replaced sub strings. */ public static String replace(String pString_, String sOld_, String sNew_) { return replace(pString_, sOld_, sNew_, 0); } /** * Replaces all occurences of sOld_ in pString with sNew_. * * @param startIndex_ The startindex_ gives the position in * pString_ where the replace procedure * should start. */ public static String replace(String pString_, String sOld_, String sNew_, int startIndex_) { panicIf(sNew_ == null || sOld_ == null); // 23. 11. 1996 // solange bis old nicht mehr gefunden wird. if (pString_ == null) { return null; } StringBuffer sbRetVal = new StringBuffer ( pString_.length() ); int copyIndex = 0; int lengthOld = sOld_.length(); int index = startIndex_; while( true ) { //Util.debug( "ccl.util.Util.replace(..).index: " + index ); index = pString_.indexOf(sOld_, index); if ( index == -1 ) { break; } sbRetVal.append( pString_.substring ( copyIndex, index ) ); sbRetVal.append( sNew_ ); index += lengthOld; copyIndex = index; } sbRetVal.append( pString_.substring( copyIndex, pString_.length() ) ); return sbRetVal.toString(); } /** * Tests if a string contains only space, tab, and linefeed * characters. */ public static boolean isSpaceLine(String sLine_) { if (sLine_ == null || sLine_.length() == 0) { return true; } for(int index = 0; index < sLine_.length(); index++) { char c = sLine_.charAt(index); if (c != ' ' && c != '\t' && c != '\n') { return false; } } return true; } /** * Replaces tabs with spaces, a maximum of 8 each. */ public static String untabify( String pString ) { for( int index = 0; index < pString.length(); index++ ) { if ( pString.charAt( index ) == '\t' ) { pString = pString.substring( 0, index ) + getSpaces( 8 - (index % 8) ) + pString.substring( index + 1 ); } } return pString; } /** * Returns "" if the input string is null, otherwise returns the same string back. */ public static String denullify(String pString_) { if (pString_ == null) { return ""; } return pString_; } /** * Before returning pObject_.toString() it checks if * pObject_ is null. If so, "null" is returned. */ public static String toString( Object pObject_ ) { if ( pObject_ == null ) { return "null"; } return pObject_.toString(); } /** * @return -1 if sToLookIn_ does not contain sThis_. * Otherwise the position is returned. * * @deprecated Well, String.indexOf(String) should be * just fine!? */ public static int contains(String sToLookIn_, String sThis_) { if (sToLookIn_ == null) { return -1; } if (sThis_ == null) { return -1; } for(int index = 0; index < sToLookIn_.length(); index++) { if (sToLookIn_.regionMatches(index, sThis_, 0, sThis_.length())) { return index; } } return -1; } /** * If you believe it or not, in a very old jdk version * there was a bug in String.compareTo(String) and I did * need this as a workaround. This method should be of no * use anymore [1999-07-15]. * * @deprecated Use String.compare instead. */ public static int compare(String firstString, String anotherString) { int len1 = firstString.length(); int len2 = anotherString.length(); int n = Math.min(len1, len2); int i = 0; int j = 0; while (n-- != 0) { char c1 = firstString.charAt(i++); char c2 = anotherString.charAt(j++); if (c1 != c2) { return(c1 - c2); } } return(len1 - len2); } /** * @return -1 means the string is either "" or contains just the * char cNot_. */ public static int indexOfNot(String pString_, char cNot_, int startIndex_) { panicIf(pString_ == null || startIndex_ < 0); while (startIndex_ < pString_.length()) { if (pString_.charAt(startIndex_) != cNot_) { return startIndex_; } startIndex_++; } return -1; } /** * @return -1 means the string is either "" or contains just the * char cNot_. */ public static int indexOfNot( String pString_, char cNot_ ) { return indexOfNot( pString_, cNot_, 0 ); } /** * How many chars c_ contains the String pString_. */ public static int count(String pString_, char c_) { int retVal = 0; if (Util.isEmpty(pString_)) { return retVal; } int index = pString_.indexOf(c_); while(index != -1) { retVal++; index = pString_.indexOf(c_, ++index); } return retVal; } /** * Return true for digit characters. */ public static boolean isDigit( char c_ ) { return '0' <= c_ && c_ <= '9'; } /** * Return true if the given character can be found * in the string "aeoui���". */ public static boolean isVocal( char c_ ) { String sChar = Util.cToS( c_ ).toLowerCase(); String sVocals = "aouie���"; return (sVocals.indexOf( sChar ) != -1); } /** * Reformat a string which is not longer than a given * size. If the input string was longer, a piece in the * middle of that string will be cut out and replaced * with '[...]'. maxSize should be not too small, btw. */ public static String shrinkString( String pString , int maxSize ) { if ( Util.isEmpty( pString ) ) { return ""; } if ( pString.length() <= maxSize ) { return pString; } String sRetVal = pString.substring( 0, maxSize / 2 - 2 ) + "[...]"; sRetVal += pString.substring( pString.length() - maxSize + sRetVal.length() , pString.length() ); return sRetVal; } // ----------------------------------------------------- // string/vector converter methods // ----------------------------------------------------- /** * This function concatenates different Strings into one String. * * @param pVector_ Contains the Strings that will be concatenated. * * @return There is no 'glue' between the Strings. * * @see #stringToLines(java.lang.String) */ public static String concat(Vector pVector_) { return concat(pVector_, ""); } /** * This function concatenates different Strings into one String. * * @param pVector_ Contains the Strings that will be concatenated. * @param sWith_ The 'glue' for the other Strings. * * @return sWith_ is not appended at the end. * * @see #stringToLines(java.lang.String, char) */ public static String concat(Vector pVector_, String sWith_) { String sRetVal = new String(); if (pVector_ == null || pVector_.size() < 1) { return sRetVal; } if (sWith_ == null) { sWith_ = ""; } Enumeration e = pVector_.elements(); sRetVal += e.nextElement().toString(); for( ; e.hasMoreElements(); ) { sRetVal += sWith_ + e.nextElement().toString(); } return sRetVal; } /** * This function concatenates different Strings into one String. * * @param pVector_ Contains the Strings that will be concatenated. * @param cWith_ The 'glue' for the other Strings. * * @return cWith_ is not appended at the end. * * @see #stringToLines(java.lang.String, char) */ public static String concat(Vector pVector_, char cWith_) { return concat(pVector_, cToS(cWith_)); } /** * This function concatenates a String with a char. */ public static String concat(String pString_, char cWidth_) { return(pString_ + cToS(cWidth_)); } /** * This function takes a String and separates it into different * lines. The last line does not need to have a separator character. * * @param lines_ The number of lines that should be extracted. * Zero if maximum number of lines is requested. * @param cCutter_ The character that separates pString_ into * different lines * * @return The single lines do not contain the cCutter_ * character at the end. */ public static Vector stringToLines(int lines_, String pString_, char cCutter_) { int maxLines = Integer.MAX_VALUE; if (lines_ > 0) { maxLines = lines_; } Vector vRetVal = new Vector(); if (pString_ == null) { return vRetVal; } int startIndex = 0; for( ; maxLines > 0; maxLines-- ) { int endIndex = pString_.indexOf(cCutter_, startIndex); if (endIndex == -1) { if (startIndex < pString_.length()) { endIndex = pString_.length(); } else { break; } } String sLine = pString_.substring(startIndex, endIndex); vRetVal.addElement((Object) sLine); startIndex = endIndex + 1; } return vRetVal; } /** * This function takes a String and separates it into different * lines. The last line does not need to have a separator character. * * @param cCutter_ The character that separates pString_ into * different lines * * @return The single lines do not contain the cCutter_ character * at the end. * * @see #concat(java.util.Vector, java.lang.String) */ public static Vector stringToLines(String pString_, char cCutter_) { return stringToLines(0, pString_, cCutter_); } /** * This function takes a String and separates it into different * lines. The last line does not need to have a '\n'. The function * can't handle dos carriage returns. * * @return The single lines do not contain the '\n' character * at the end. */ public static Vector stringToLines(String pString_) { return stringToLines(pString_, '\n'); } /** * This function takes a String and separates it into different * lines. The last line does not need to have a '\n'. The function * can't handle dos carriage returns. * * @param lines_ The number of lines that should be extracted. * Zero if maximum number of lines is requested. * * @return The single lines do not contain the line feed character * at the end. * * @see #concat(java.util.Vector, java.lang.String) */ public static Vector stringToLines(int lines_, String pString_) { return stringToLines(lines_, pString_, '\n'); } /** * This function takes a String and separates it into different * lines. The last line does not need to have a separator string. * * @return Note that the sCutter_ string will be removed from each * line. * * @see #concat(java.util.Vector, java.lang.String) */ public static Vector stringToLines(String sLines_, String sCutter_) { Vector vRetVal = new Vector(); if (sLines_ == null) { return vRetVal; } int startIndex = 0; while(startIndex < sLines_.length() && startIndex != -1) { int endIndex = sLines_.indexOf(sCutter_, startIndex); if (endIndex == -1) { endIndex = sLines_.length(); } String sNextLine = sLines_.substring(startIndex, endIndex); vRetVal.addElement(sNextLine); startIndex = endIndex + sCutter_.length(); } return vRetVal; } /** * This function takes a String and separates it into different * lines. The last line does not need to have a separator string. * * @see #concat(java.util.Vector, java.lang.String) */ public static Vector stringToLines(String sLines_, String sTokenizerString_, boolean bUseTokenizer_) { if (bUseTokenizer_ == false) { return stringToLines(sLines_, sTokenizerString_); } Vector vRetVal = new Vector(); if (sLines_ == null) { return vRetVal; } StringTokenizer pStringTokenizer = new StringTokenizer(sLines_, sTokenizerString_, false); while(pStringTokenizer.hasMoreTokens()) { String sNextToken = pStringTokenizer.nextToken(); vRetVal.addElement(sNextToken); } return vRetVal; } /** * This method takes a string and reformats it so that each * line has no more than the given length and the text will * be aligned as a block. * * This method uses a line length of 72. */ public static String formatBlock( String pString ) { return formatBlock( pString, 72 ); } /** * Adds spaces inside the string so that the total length * will match exactly the requested length. * * @param bRight starting from the right side to add spaces. */ private static String _formatBlockLine( String sLine , int lineLength , boolean bRight ) { StringBuffer sbRetVal = new StringBuffer(); sbRetVal.append( sLine ); int spacesToAdd = lineLength - sLine.length(); while( true ) { Util.debug( "ccl.util.Util._formatBlockLine(..).enter while true" ); int nextSpace = 0; int direction = 1; if ( bRight ) { nextSpace = sbRetVal.length() - 1; direction = -direction; } Util.debug( "ccl.util.Util._formatBlockLine(..).direction: " + direction ); Util.debug( "ccl.util.Util._formatBlockLine(..).spacesToAdd: " + spacesToAdd ); boolean bRestart = false; while( bRestart == false && spacesToAdd > 0 ) { Util.debug( "ccl.util.Util._formatBlockLine(..).nextSpace: " + nextSpace ); // find next space while( sbRetVal.charAt( nextSpace ) != ' ' ) { nextSpace += direction; if ( nextSpace < 0 || sbRetVal.length() <= nextSpace ) { Util.debug( "ccl.util.Util._formatBlockLine(..).first break finish" ); bRestart = true; break; } } if ( bRestart ) { break; } Util.debug( "ccl.util.Util._formatBlockLine(..).insert space at: " + nextSpace ); sbRetVal.insert( nextSpace, ' ' ); spacesToAdd--; // find next non space while( sbRetVal.charAt( nextSpace ) == ' ' ) { nextSpace += direction; if ( nextSpace < 0 || sbRetVal.length() <= nextSpace ) { bRestart = true; break; } } Util.debug( "ccl.util.Util._formatBlockLine(..).spacesToAdd: " + spacesToAdd ); } if ( spacesToAdd <= 0 ) { break; } } return sbRetVal.toString(); } /** * This method updates the return value string buffer and * the line buffer assuming a new spaces has to be added. * Both string buffers will be changed. */ private static void _processSpaceBlock( StringBuffer sbRetVal , StringBuffer sbLine , int lineLength ) { if ( sbLine.length() == lineLength ) { sbRetVal.append( sbLine.toString() ).append( '\n' ); sbLine.setLength( 0 ); } else if ( sbLine.length() > lineLength ) { int lastSpace = sbLine.toString().lastIndexOf( ' ' ); if ( lastSpace == -1 ) { sbRetVal.append( sbLine.toString() ).append( '\n' ); sbLine.setLength( 0 ); } else { sbRetVal.append( _formatBlockLine( sbLine.substring( 0, lastSpace ), lineLength, true ) ).append( '\n' ); sbLine.delete( 0, lastSpace + 1 ).append( ' ' ); } } else { sbLine.append( ' ' ); } } /** * This method takes a string and reformats it so that each * line has no more than the given length and the text will * be aligned as a block. */ public static String formatBlock( String pString, int lineLength ) { String sWorkString = replace( pString, "\n", " " ); sWorkString = replace( sWorkString, "\r", " " ); sWorkString = replace( sWorkString, "\t", " " ); sWorkString = sWorkString.trim(); StringBuffer sbRetVal = new StringBuffer(); StringBuffer sbLine = new StringBuffer(); boolean bWhiteSpace = false; int index = 0; while( index <= sWorkString.length() ) { char nextChar = ' '; if ( index < sWorkString.length() ) { nextChar = sWorkString.charAt( index ); } Util.debug( "ccl.util.Util.formatLeft(..).nextChar: " + nextChar ); if ( nextChar == ' ' || nextChar == '\t' || nextChar == '\n' || nextChar == '\r' ) { if ( bWhiteSpace == false ) { _processSpaceBlock( sbRetVal, sbLine, lineLength ); bWhiteSpace = true; } } else { bWhiteSpace = false; sbLine.append( nextChar ); } index++; Util.debug( "ccl.util.Util.formatLeft(..).sbRetVal: " + sbRetVal ); Util.debug( "ccl.util.Util.formatLeft(..).sbLine: " + sbLine ); } if ( sbLine.length() > 0 ) { sbRetVal.append( Util.rtrim( sbLine.toString() ) ).append( '\n' ); } return sbRetVal.toString(); } /** * This method takes a string and reformats it so that each * line has no more than the given length and the text will * be aligned as a block. * * @param indentation add indentation spaces to left * of each line. */ public static String formatBlock( String pString , int lineLength , int indentation ) { String sRetVal = formatBlock( pString, lineLength - indentation ); Vector vLines = stringToLines( sRetVal ); Enumeration eLines = vLines.elements(); sRetVal = ""; while( eLines.hasMoreElements() ) { sRetVal += getSpaces( indentation ) + ((String) eLines.nextElement()) + "\n"; } return sRetVal; } /** * This method takes a string and reformats it so that each * line has no more than the given length and the text will * be aligned to the left side. * * This method uses a line length of 72. */ public static String formatLeft( String pString ) { return formatLeft( pString, 72 ); } /** * This method updates the return value string buffer and * the line buffer assuming a new spaces has to be added. * Both string buffers will be changed. */ private static void _processSpaceLeft( StringBuffer sbRetVal , StringBuffer sbLine , int lineLength ) { if ( sbLine.length() == lineLength ) { sbRetVal.append( sbLine.toString() ).append( '\n' ); sbLine.setLength( 0 ); } else if ( sbLine.length() > lineLength ) { int lastSpace = sbLine.toString().lastIndexOf( ' ' ); if ( lastSpace == -1 ) { sbRetVal.append( sbLine.toString() ).append( '\n' ); sbLine.setLength( 0 ); } else { sbRetVal.append( sbLine.substring( 0, lastSpace ) ).append( '\n' ); sbLine.delete( 0, lastSpace + 1 ).append( ' ' ); } } else { sbLine.append( ' ' ); } } /** * This method takes a string and reformats it so that each * line has no more than the given length and the text will * be aligned to the left side. */ public static String formatLeft( String pString, int lineLength ) { String sWorkString = pString.trim(); StringBuffer sbRetVal = new StringBuffer(); StringBuffer sbLine = new StringBuffer(); boolean bWhiteSpace = false; int index = 0; while( index <= sWorkString.length() ) { char nextChar = ' '; if ( index < sWorkString.length() ) { nextChar = sWorkString.charAt( index ); } Util.debug( "ccl.util.Util.formatLeft(..).nextChar: " + nextChar ); if ( nextChar == ' ' || nextChar == '\t' || nextChar == '\n' || nextChar == '\r' ) { if ( bWhiteSpace == false ) { _processSpaceLeft( sbRetVal, sbLine, lineLength ); bWhiteSpace = true; } } else { bWhiteSpace = false; sbLine.append( nextChar ); } index++; Util.debug( "ccl.util.Util.formatLeft(..).sbRetVal: " + sbRetVal ); Util.debug( "ccl.util.Util.formatLeft(..).sbLine: " + sbLine ); } if ( sbLine.length() > 0 ) { sbRetVal.append( Util.rtrim( sbLine.toString() ) ).append( '\n' ); } return sbRetVal.toString(); } /** * This method takes a string and reformats it so that each * line has no more than the given length and the text will * be aligned to the left side. * * @param indentation add indentation spaces to left * of each line. */ public static String formatLeft( String pString , int lineLength , int indentation ) { String sRetVal = formatLeft( pString, lineLength - indentation ); Vector vLines = stringToLines( sRetVal ); Enumeration eLines = vLines.elements(); sRetVal = ""; while( eLines.hasMoreElements() ) { sRetVal += getSpaces( indentation ) + ((String) eLines.nextElement()) + "\n"; } return sRetVal; } /** * This method takes a string and reformats it so that each * line has no more than the given length and the text will * be centered in the middle. */ public static String formatCenter( String pString, int lineLength ) { StringBuffer sbRetVal = new StringBuffer(); String sLeft = formatLeft( pString, lineLength ); // now walk through each line and center it Vector vLines = stringToLines( sLeft ); Enumeration eLines = vLines.elements(); while( eLines.hasMoreElements() ) { String sLine = (String) eLines.nextElement(); sLine = centerLine( sLine, lineLength ); sbRetVal.append( sLine ).append( '\n' ); } return sbRetVal.toString(); } /** * Returns a string withe the provided content in the center * and no line feed. Also, the right side of the string * will not be filled up with spaces, only the left side. * The input should not contain line feeds, btw. */ public static String centerLine( String pString, int lineLength ) { if ( Util.isEmpty( pString ) ) { return ""; } if ( pString.length() > lineLength ) { return pString; } int add = (lineLength - pString.length()) / 2; return getSpaces( add ) + pString; } /** * Finds out the first position (started with 0) at which two strings * start to differ. * * @param s1 a string to compare, is not allowed to be null. * @param s2 a string to compare, is not allowed to be null. * @return the first position starting with 0 at which both strings differ or * the length of the smaller one or the length of both string if they are * equal. */ public static int getDiffPosition( String s1, String s2 ) { if ( s1 == null ) { throw new IllegalArgumentException( "First string is null" ); } if ( s2 == null ) { throw new IllegalArgumentException( "Second string is null" ); } int position = -1; do { position++; // if one of the files (can also be both) end here return current position if ( position >= s1.length() || position >= s2.length() ) { break; } } while( s1.charAt( position ) == s2.charAt( position ) ); return position; } // ----------------------------------------------------- // vector methods // ----------------------------------------------------- /** * Tests, if a given Vector is null or has size 0. */ public static boolean isEmpty( Vector vTest_ ) { if (vTest_ == null || vTest_.size() == 0 ) { return true; } return false; } /** * Enumeration to Vector converter. * * @return null in empty vector out */ public static Vector toVector( Enumeration pEnumeration_ ) { Vector vRetVal = new Vector(); if ( pEnumeration_ == null ) { return vRetVal; } while( pEnumeration_.hasMoreElements() ) { vRetVal.addElement( pEnumeration_.nextElement() ); } return vRetVal; } /** * Convert an array of objects to a vector. */ public static Vector objectsToVector(Object apObjects[]) { Vector vRetVal = new Vector(); if (apObjects != null && apObjects.length > 0) { for(int nr = 0; nr < apObjects.length; nr++) { vRetVal.addElement(apObjects[nr]); } } return vRetVal; } /** * Convenience class for java.util.Vector.copyInto(..). * * @param pVector_ the vector to convert into an array. * @return Never returns null, returns at least an array * of length 0. */ public static Object[] vectorToObjects( Vector pVector_ ) { if ( pVector_ == null ) { return new Object[ 0 ]; } Object[] aoRetVal = new Object[ pVector_.size() ]; pVector_.copyInto( aoRetVal ); return aoRetVal; } /** * All object in this vector which equal the bad element * are not copied over to the resulting vector. */ public static Vector filter(Vector pVector_, final Object oBadElement_) { panicIf(oBadElement_ == null); //final String sFinalBadElement = new String(sBadElement_); Testable pFilter = new Testable() { /** * Returns true when given object is none of the * bad ones. */ public boolean test(Object pObject_) { return(!oBadElement_.equals(pObject_)); } }; return filter(pVector_, pFilter); } /** * All object in this vector which equal an object in * the bad vector are not copied over to the resulting * vector. */ public static Vector filter(Vector pVector_, Vector vBadElements_) { Vector vRetVal = pVector_; panicIf(vBadElements_ == null); for(Enumeration e = vBadElements_.elements(); e.hasMoreElements(); ) { Object oBadElement = e.nextElement(); vRetVal = filter(vRetVal, oBadElement); } return vRetVal; } /** * Create a new vector and copy all elements of * the pVector_ paramter over which are accepted by the * test filter. * <br> * Each element for which the test returns true, it gets * added to the returned vector. */ public static Vector filter(Vector pVector_, Testable pFilter_) { Vector vRetVal = new Vector(); for(Enumeration e = pVector_.elements(); e.hasMoreElements(); ) { Object pObject = e.nextElement(); if (pFilter_.test(pObject)) { vRetVal.addElement(pObject); } } return vRetVal; } /** * Convert each element of the vector by a transformation * object. */ public static Vector map(Vector pVector_, Transformable pTransformable_) { Vector vRetVal = new Vector(); for(Enumeration e = pVector_.elements(); e.hasMoreElements(); ) { Object pObject = e.nextElement(); vRetVal.addElement(pTransformable_.transform(pObject)); } return vRetVal; } /** * Test if a vector contains a given string. */ public static boolean contains(Vector pVector_, final String sFind_) { panicIf(sFind_ == null); Testable pFilter = new Testable() { /** * Returns true if given object equals the final string * which is to be found. */ public boolean test(Object pObject_) { return(sFind_.equals((String) pObject_)); } }; return contains(pVector_, pFilter); } /** * Test if a vector contains an element which succeeds * a given test filter. */ public static boolean contains(Vector pVector_, Testable pFilter_) { Vector vRetVal = new Vector(); for(Enumeration e = pVector_.elements(); e.hasMoreElements(); ) { Object pObject = e.nextElement(); if (pFilter_.test(pObject)) { return true; } } return false; } /** * Convert an enumeration to a vector. * Sometimes you have an enumeration at hand, which you * want to use more than once. */ public static Vector enumerationToVector(Enumeration pEnumeration_) { Vector vRetVal = new Vector(); while(pEnumeration_.hasMoreElements()) { Object pObject = pEnumeration_.nextElement(); vRetVal.addElement(pObject); } return vRetVal; } /** * Create a new vector which consists of both given vectors. */ public static Vector concat(Vector vFirst_, Vector vSecond_) { Vector vRetVal = (Vector) vFirst_.clone(); for(Enumeration e = vSecond_.elements(); e.hasMoreElements(); ) { vRetVal.addElement(e.nextElement()); } return vRetVal; } /** * Create a new vector through extracting all elements of * the second vector from the first vector. */ public static Vector subtract(Vector vSource_, Vector vToDelete_) { Vector vRetVal = (Vector) vSource_.clone(); for(Enumeration e = vToDelete_.elements(); e.hasMoreElements(); ) { vRetVal.removeElement(e.nextElement()); } return vRetVal; } /** * Insert at a special offset all elements of the second * vector into the first vector. The input vectors are * not changed but a new result vector gets created. */ public static Vector insert(Vector vDestination_, Vector vOther_, int destination) { panicIf(vDestination_ == null || vOther_ == null); if (destination > vDestination_.size()) { destination = vDestination_.size(); } Vector vRetVal = new Vector(); for(int i = 0; i < destination; i++) { vRetVal.addElement(vDestination_.elementAt(i)); } vRetVal = concat(vRetVal, vOther_); for(int i = destination; i < vDestination_.size(); i++) { vRetVal.addElement(vDestination_.elementAt(i)); } return vRetVal; } /** * Do the elements of two vectors at the same position * equal each other? */ public static boolean equals(Vector vFirst_, Vector vSecond_) { if (vFirst_ == vSecond_) { return true; } if (vFirst_ == null || vSecond_ == null) { return false; } if (vFirst_.size() != vSecond_.size()) { return false; } for(int index = 0; index < vFirst_.size(); index++) { Object oFirst = vFirst_.elementAt(index); Object oSecond = vSecond_.elementAt(index); if (oFirst == null && oSecond == null) { continue; } if (oFirst == null || oSecond == null) { return false; } if (!oFirst.equals(oSecond)) { return false; } } return true; } /** * Create a new vector and invert the order of the * elements. */ public static Vector invert(Vector vSource_) { if (vSource_ == null || vSource_.size() == 0) { return(new Vector()); } int vectorSize = vSource_.size(); Vector vDest = new Vector(vectorSize); for(int index = vectorSize - 1; index >= 0; index--) { Object oNext = vSource_.elementAt(index); vDest.addElement(oNext); } return vDest; } // ----------------------------------------------------- // sorting and inserting methods // ----------------------------------------------------- /** * An implementation of Quicksort using medians of 3 for partitions. * Used internally by sort. * It is public and static so it can be used to sort plain * arrays as well. * * Originally written by Doug Lea and released into the public domain. * Thanks for the assistance and support of Sun Microsystems Labs, Agorics * Inc, Loral, and everyone contributing, testing, and using this code. * * History: * Date Who What * 2Oct95 dl@cs.oswego.edu refactored from DASeq.java * 13Oct95 dl Changed protection statuses * * @param s the array to sort * @param lo the least index to sort from * @param hi the greatest index * @param cmp the comparator to use for comparing elements */ public static void quickSort(Object s[], int lo, int hi, Comparable cmp) { if (lo >= hi) { return; } // Use median-of-three(lo, mid, hi) to pick a partition. // Also swap them into relative order while we are at it. int mid = (lo + hi) / 2; if (cmp.compare(s[lo], s[mid]) > 0) { Object tmp = s[lo]; s[lo] = s[mid]; s[mid] = tmp; // swap } if (cmp.compare(s[mid], s[hi]) > 0) { Object tmp = s[mid]; s[mid] = s[hi]; s[hi] = tmp; // swap if (cmp.compare(s[lo], s[mid]) > 0) { Object tmp2 = s[lo]; s[lo] = s[mid]; s[mid] = tmp2; // swap } } int left = lo + 1; // start one past lo since already handled lo int right = hi - 1; // similarly if (left >= right) { return; // if three or fewer we are done } Object partition = s[mid]; for ( ; ; ) { while (cmp.compare(s[right], partition) > 0) { --right; } while (left < right && cmp.compare(s[left], partition) <= 0) { ++left; } if (left < right) { Object tmp = s[left]; s[left] = s[right]; s[right] = tmp; // swap --right; } else { break; } } quickSort(s, lo, left, cmp); quickSort(s, left + 1, hi, cmp); } /** * An implementation of Quicksort using medians of 3 for partitions. * Used internally by sort. * It is public and static so it can be used to sort plain * arrays as well. * * Originally written by Doug Lea and released into the public domain. * Thanks for the assistance and support of Sun Microsystems Labs, Agorics * Inc, Loral, and everyone contributing, testing, and using this code. * * History: * Date Who What * 2Oct95 dl@cs.oswego.edu refactored from DASeq.java * 13Oct95 dl Changed protection statuses * 30Apr97 Clemens.Lahme@gmd.de For use with Vector * * @param v the vector to sort * @param lo the least index to sort from * @param hi the greatest index * @param cmp the comparator to use for comparing elements * */ public static void quickSort(Vector v, int lo, int hi, Comparable cmp) { panicIf (v == null); if ( lo >= hi ) { return; } // Use median-of-three(lo, mid, hi) to pick a partition. // Also swap them into relative order while we are at it. int mid = (lo + hi) / 2; if (cmp.compare(v.elementAt(lo), v.elementAt(mid)) > 0) { // swap Object tmp = v.elementAt(lo); v.setElementAt(v.elementAt(mid), lo); v.setElementAt(tmp, mid); } if (cmp.compare(v.elementAt(mid), v.elementAt(hi)) > 0) { // swap Object tmp = v.elementAt(mid); v.setElementAt(v.elementAt(hi), mid); v.setElementAt(tmp, hi); if (cmp.compare(v.elementAt(lo), v.elementAt(mid)) > 0) { // swap Object tmp2 = v.elementAt(lo); v.setElementAt(v.elementAt(mid), lo); v.setElementAt(tmp2, mid); } } int left = lo + 1; // start one past lo since already handled lo int right = hi - 1; // similarly if (left >= right) { return; // if three or fewer we are done } Object partition = v.elementAt(mid); for ( ; ; ) { while (cmp.compare(v.elementAt(right), partition) > 0) { --right; } while (left < right && cmp.compare(v.elementAt(left), partition) <= 0) { ++left; } if (left < right) { // swap Object tmp = v.elementAt(left); v.setElementAt(v.elementAt(right), left); v.setElementAt(tmp, right); --right; } else { break; } } quickSort(v, lo, left, cmp); quickSort(v, left + 1, hi, cmp); } /** * Uses Quicksort using medians of 3 for partitions and the */ public static Vector sort(final Vector vInput_, Comparable pComparable_) { panicIf(vInput_ == null); Vector vRetVal = (Vector) vInput_.clone(); if (vInput_.size() > 0) { quickSort(vRetVal, 0, vRetVal.size() - 1, pComparable_); } return vRetVal; } /** * Like sort but works directly on the input vector. */ public static void sortFast( Vector vInput_, Comparable pComparable_ ) { panicIf(vInput_ == null); if (vInput_.size() > 0) { quickSort( vInput_, 0, vInput_.size() - 1, pComparable_ ); } } /** * Uses Quicksort using medians of 3 for partitions. */ public static Vector sort(final Vector pVector_) { Comparable pComparable = new Comparable() { /** * Converts object string representation to lower * case before comparing. Is that really what we want? * In some cases yes, for example having 'Zorro' sorted * before 'arthur' is not what everbody expects, * thought some might expect it. */ public int compare(Object oFirst_, Object oSecond_) { return( ((oFirst_.toString()).toLowerCase()). compareTo((oSecond_.toString()).toLowerCase()) ); } }; return sort(pVector_, pComparable); } /** * Uses Quicksort using medians of 3 for partitions. */ public static void sortFast(final Vector pVector_) { Comparable pComparable = new Comparable() { /** * Converts object string representation to lower * case before comparing. Is that really what we want? * In some cases yes, for example having 'Zorro' sorted * before 'arthur' is not what everbody expects, * thought some might expect it. */ public int compare(Object oFirst_, Object oSecond_) { return( ((oFirst_.toString()).toLowerCase()). compareTo((oSecond_.toString()).toLowerCase()) ); } }; sortFast(pVector_, pComparable); } /** * Quicksort for Enumeration. * * @return null in empty vector out */ public static Vector sort( Enumeration pEnumeration_ ) { return sort( toVector( pEnumeration_ ) ); } /** * Quicksort for Enumeration. * * @return null in empty vector out */ public static Vector sort( Enumeration pEnumeration_, Comparable pComparable_ ) { return sort( toVector( pEnumeration_ ), pComparable_ ); } /** * Case sensitive sort has 'Zorro' ordered * before 'arthur'. If that is not desirec, * use normal sort routines. * Uses Quicksort using medians of 3 for partitions */ public static Vector sortCaseSensitive(final Vector pVector_) { Comparable pComparable = new Comparable() { /** * Case sensitive sort has 'Zorro' ordered * before 'arthur'. If that is not desirec, * use normal sort routines. */ public int compare(Object oFirst_, Object oSecond_) { return( oFirst_.toString(). compareTo(oSecond_.toString()) ); } }; return sort(pVector_, pComparable); } /** * Inert a new object into a vector and keep the * vector sorted. */ public static int insert( Vector pVector_, int lowestOffset_, int highestOffset_, Object pObject_, Comparable pComparable_ ) { if ( highestOffset_ < lowestOffset_ ) { pVector_.insertElementAt( pObject_, lowestOffset_ ); return lowestOffset_; } // get median element int midleOffset = (lowestOffset_ + highestOffset_) / 2; if ( pComparable_.compare( pObject_, pVector_.elementAt( midleOffset ) ) < 0 ) { return insert( pVector_, lowestOffset_, midleOffset - 1, pObject_, pComparable_ ); } else { return insert( pVector_, midleOffset + 1, highestOffset_, pObject_, pComparable_ ); } } /** * Inert a new object into a vector and keep the * vector sorted. */ public static int insert( Vector pVector_, Object pObject_, Comparable pComparable_ ) { panicIf( pVector_ == null ); return insert( pVector_, 0, pVector_.size() - 1, pObject_, pComparable_ ); } // ----------------------------------------------------- // system methods // ----------------------------------------------------- /** * This method does return immediately. If you want the * output of the process use either systemAndWait() or * systemAndGetError(). * * @exception IOException Whatever can go wrong. * * @see #systemAndWait(java.util.Vector) * @see #systemAndGetError(java.util.Vector) */ public static Process system( String sCommand_ ) throws IOException { Process pProcess = Runtime.getRuntime().exec( sCommand_ ); /*DataInputStream dis = new DataInputStream( new BufferedInputStream(p.getInputStream())); String s = null; while ((s = dis.readLine()) != null) { System.out.println(s); }*/ return pProcess; } /** * Execute an external command. * * @exception IOException Whatever Runtime.exec(..) throws. */ public static Process system(String asCommand_[]) throws IOException { Process pProcess = Runtime.getRuntime().exec(asCommand_); return pProcess; } /** * Execute an external command. Provide arguments inside * a vector. * * @exception IOException Whatever Runtime.exec(..) throws. */ public static Process system(Vector vArgs_) throws IOException { panicIf(vArgs_ == null || vArgs_.size() == 0); String asArgs[] = new String[vArgs_.size()]; int arg = 0; for(Enumeration eArgs = vArgs_.elements(); eArgs.hasMoreElements(); ) { asArgs[arg] = (String) eArgs.nextElement(); arg++; } return system(asArgs); } /** * Does a system exec and returns the stdout. * * @exception IOException Whatever might go wrong. * @param vArgs_ the arguments to system.exec(). * Should not be null or empty. * @return The standard output. */ public static String systemAndWait( Vector vArgs_ ) throws IOException { panicIf( vArgs_ == null || vArgs_.size() == 0 ); String sRetVal = ""; String sLine = null; Process pProcess = system( vArgs_ ); BufferedReader reader = new BufferedReader ( new InputStreamReader ( pProcess.getInputStream() ) ); while( (sLine = reader.readLine()) != null ) { sRetVal += sLine + "\n"; } reader.close(); return sRetVal; } /** * Does a system exec and returns the stdout. * * @exception IOException Whatever might go wrong. * @param commandline the arguments to system.exec(). * Should not be null or empty. * @return The standard output. */ public static String systemAndWait( String commandline ) throws IOException { panicIf( Util.isEmpty( commandline ) ); String sRetVal = ""; String sLine = null; Process pProcess = system( commandline ); BufferedReader reader = new BufferedReader ( new InputStreamReader ( pProcess.getInputStream() ) ); while( (sLine = reader.readLine()) != null ) { sRetVal += sLine + "\n"; } reader.close(); return sRetVal; } /** * Does a system exec and returns the stderr output. * * @exception IOException Whatever might go wrong. * @param vArgs_ the arguments to system.exec(). * Should not be null or empty. * @return The standard output. */ public static String systemAndGetError( Vector vArgs_ ) throws IOException { panicIf( vArgs_ == null || vArgs_.size() == 0 ); String sRetVal = ""; String sLine = null; Process pProcess = system( vArgs_ ); BufferedReader reader = new BufferedReader ( new InputStreamReader ( pProcess.getErrorStream() ) ); while( (sLine = reader.readLine()) != null ) { sRetVal += sLine + "\n"; } reader.close(); return sRetVal; } /** * Does a system exec and returns the stderr output. * * @exception IOException Whatever might go wrong. * @param commandline the arguments to system.exec(). * Should not be null or empty. * @return The standard output. */ public static String systemAndGetError( String commandline ) throws IOException { panicIf( Util.isEmpty( commandline ) ); String sRetVal = ""; String sLine = null; Process pProcess = system( commandline ); BufferedReader reader = new BufferedReader ( new InputStreamReader ( pProcess.getErrorStream() ) ); while( (sLine = reader.readLine()) != null ) { sRetVal += sLine + "\n"; } reader.close(); return sRetVal; } /** * Returns true if the current operating system is * Microsoft Windows. */ public static boolean isOSWindows() { String sOSName = System.getProperty("os.name"); Util.debug("Util.isOSWindows().sOSName: " + sOSName); return sOSName.startsWith("Windows"); } /** * Returns true if the current operating system is * Linux. */ public static boolean isOSLinux() { String sOSName = System.getProperty("os.name"); return sOSName.startsWith("Linux"); } /** * Returns true if the current operating system is * Sun Microsystem's Solaris (or SunOS). */ public static boolean isOSSolaris() { String sOSName = System.getProperty("os.name"); return sOSName.startsWith("Solaris") || sOSName.startsWith( "SunOS" ); } /** * Returns true if the current operating system is * either Linux or Solaris. */ public static boolean isOSUnix() { return isOSLinux() || isOSSolaris(); } /** * System.gc() does not always garanty immediate execution. * This method does also a yield for a bigger chance that gc * really does happen. */ public static void gc() { System.gc(); Thread.currentThread().yield(); } /** * Get the name of the localhost. */ public static String getLocalHostName() { String sHostName = ""; try { InetAddress iaLocalHost = InetAddress.getLocalHost(); sHostName = iaLocalHost.getHostName(); } catch(Exception eLocalHost) { return null; } return sHostName; } /** * Returns true if sFullPackageName_ is a swing * package, either old com.sun.java.swing or new * javax.swing convention. Accessibilitiy is also * considered to be a swing package. */ public static boolean isSwingPackage( String sFullPackageName_ ) { if ( sFullPackageName_.startsWith( "javax." ) || sFullPackageName_.startsWith( "com.sun.java." ) ) { if (sFullPackageName_.equals("javax.swing") || sFullPackageName_.equals("javax.accessibility" ) || sFullPackageName_.startsWith("javax.swing.") || sFullPackageName_.equals("com.sun.java.swing") || sFullPackageName_.equals("com.sun.java.accessibility") || sFullPackageName_.startsWith("com.sun.java.swing.")) { return true; } } return false; } /** * Returns a string which contains the stack trace. */ public static String getStackTrace( Throwable pThrowable_ ) { StringWriter pStringWriter = new StringWriter(); PrintWriter pPrintWriter = new PrintWriter ( pStringWriter ); pThrowable_.printStackTrace( pPrintWriter ); return pStringWriter.toString(); } /** * This method returns a string with dump out of all its * attribute fields, private as well as public fields. * Eventually you have to set the security * policy in order to permit access to private stuff. * This method also fails compiling for jdk 1.1. */ public static String getDump( Object object_ ) { String dumpString = "null"; //if ( dumpString.equals( "null" ) ) { // throw new ApplicationException( "Method ccl.Util.getDump(Object) not implemented!" ); //} if ( object_ != null ) { Class dumpClass = object_.getClass(); dumpString = dumpClass.getName() + "@" + Integer.toHexString( object_.hashCode() ) + ":"; do { Field[] fieldArray = dumpClass.getDeclaredFields(); for( int fieldIndex = 0; fieldIndex < fieldArray.length; fieldIndex++ ) { try { Field nextField = fieldArray[ fieldIndex ]; // here comes the trick!!! nextField.setAccessible( true ); dumpString += "\n " + nextField + ": " + nextField.get( object_ ); } catch( IllegalAccessException illegalAccessException ) { printlnErr( illegalAccessException ); } } dumpClass = dumpClass.getSuperclass(); } while( dumpClass != null ); } return dumpString; } // ----------------------------------------------------- // random generator methods // ----------------------------------------------------- /** * @return 50% chance of either true or false. */ public static boolean rnd() { return(rnd(1) == 0); } /** * Random number in the range [0, end_] (both inclusive). */ public static int rnd(int end_) { return rnd(0, end_); } /** * Random number in the range [start_, end_] (both inclusive). */ public static int rnd(int start_, int end_) { panicIf(end_ <= start_); float fR = _rnd.nextFloat(); int r = (int) (fR * (end_ - start_ + 1) + start_); return( r ); } /** * Returns the a pseudorandom float number between * 0.0 and excluding the provided float value. */ public static float rnd(float f) { float fR = (float) _rnd.nextFloat(); return( f * fR ); } /** * Returns the a pseudorandom double number between * 0.0 and excluding the provided double value. */ public static double rnd(double df) { double dR = _rnd.nextDouble(); return( df * dR ); } // ----------------------------------------------------- // date methods // ----------------------------------------------------- /** * @return 1998-12-06 for example. */ public static String getStandardDate( Date pDate_ ) { SimpleDateFormat pSimpleDateFormat = new SimpleDateFormat( "yyyy-MM-dd" ); String sRetVal = pSimpleDateFormat.format( pDate_ ); return sRetVal; } /** * Returns the current date as an ISO date string. * * @return 1998-12-06 for example. */ public static String getDate() { return getDate( getCalendar() ); } /** * Returns the given date as an ISO date string. * * @return 1998-12-06 for example. */ public static String getDate( Calendar pCalendar_ ) { SimpleDateFormat pSimpleDateFormat = new SimpleDateFormat( "yyyy-MM-dd" ); pSimpleDateFormat.setCalendar( pCalendar_ ); String sRetVal = pSimpleDateFormat.format( pCalendar_.getTime() ); return sRetVal; } /** * Returns the time as a string of the given date object. * * @return hh:mm:ss */ public static String getTime( Date pDate_ ) { SimpleDateFormat pSimpleDateFormat = new SimpleDateFormat( "HH:mm:ss" ); String sRetVal = pSimpleDateFormat.format( pDate_ ); return sRetVal; } /** * @return hh:mm:ss */ public static String getTime( Calendar pCalendar_ ) { SimpleDateFormat pSimpleDateFormat = new SimpleDateFormat( "HH:mm:ss" ); pSimpleDateFormat.setCalendar( pCalendar_ ); String sRetVal = pSimpleDateFormat.format ( pCalendar_.getTime() ); return sRetVal; } /** * Returns the current time with milli seconds. * E.g.: 20:14:59.032 * * @return current time with milli seconds. */ static public String getTimeWithMillis() { return getTimeWithMillis( Util.getCalendar() ); } /** * Returns the current time with milli seconds. * E.g.: 20:14:59.032 * * @param calendar_ the current time. * @return current time with milli seconds. */ static public String getTimeWithMillis( Calendar calendar_ ) { String timeWithMillis = Util.getTime( calendar_ ) + "." + Util.paddWithZero( calendar_.get( Calendar.MILLISECOND ) , 3 ); return timeWithMillis; } /** * Returns a string consiting of the iso date, time, and * milli seconds, all concatenated without any space, * colon, or dash. E.g. "20000811235959003" representing * 2000-08-11 23:59:59.003 . * * return a string containin only digits repesenting * the date and time and milli seconds. */ static public String getDateTimeAndMillis() { Calendar now = Util.getCalendar(); String sRetVal = Util.getDate( now ); sRetVal = Util.replace ( sRetVal, "-", "" ); sRetVal += Util.getTimeWithMillis( now ); sRetVal = Util.replace ( sRetVal, ":", "" ); sRetVal = Util.replace ( sRetVal, ".", "" ); return sRetVal; } /** * Input format of the date is either CCYY-MM-DD or * CCYYMMDD. * * For example: 1999-11-26. Time is undefined and can * have every value. * * @return null on parse error. */ public static Date stringToDate( String sDate_ ) { if ( sDate_ == null ) { return null; } // offset used for '-' char int offset = 1; if ( sDate_.length() == 8 ) { offset = 0; } Date dtRetVal = new Date(); try { String sYear = sDate_.substring( 0, 4 ); String sMonth = sDate_.substring( 4 + offset, 6 + offset ); String sDay = sDate_.substring( 6 + 2 * offset, 8 + 2 * offset ); int year = Util.atoi( sYear ); int month = Util.atoi( sMonth ) - 1; int day = Util.atoi( sDay ); Calendar pCalendar = new GregorianCalendar(); pCalendar.setTime( dtRetVal ); pCalendar.set( Calendar.YEAR, year ); pCalendar.set( Calendar.MONTH, month ); pCalendar.set( Calendar.DAY_OF_MONTH, day ); dtRetVal.setTime( pCalendar.getTime().getTime() ); } catch( Exception pException ) { dtRetVal = null; } return dtRetVal; } /** * For example: 1999-11-26. Time is undefined and can * have every value. * * @return null on parse error. */ public static Calendar getDate( String sDate_ ) { Calendar clnRetVal = getCalendar(); try { String sYear = sDate_.substring( 0, 4 ); String sMonth = sDate_.substring( 5, 7 ); String sDay = sDate_.substring( 8, 10 ); int year = Util.atoi( sYear ); int month = Util.atoi( sMonth ) - 1; int day = Util.atoi( sDay ); clnRetVal.set( Calendar.YEAR, year ); clnRetVal.set( Calendar.MONTH, month ); clnRetVal.set( Calendar.DAY_OF_MONTH, day ); } catch( Exception pException ) { clnRetVal = null; } return clnRetVal; } /** * This is a replacement of the SimpleTimeZone.getTimeZone(String) * function that additionally creates a GregorianCalendar of the * given timezone. There is a new timezone 'CET' (Central * European Time. It has the official daylight saving time settings * (ranging from the last Sunday in March at 2:00 am to the last * Sunday in October at 2:00 am) and should be preferred over 'ECT'. * * @param sTimeZoneID_ If it is null or "" then "GMT" is used. */ public static Calendar getCalendar(String sTimeZoneID_) { if ( Util.isEmpty( sTimeZoneID_ ) ) { sTimeZoneID_ = "GMT"; } TimeZone pTimeZone = null; if (sTimeZoneID_.equals("UTC")) { pTimeZone = new SimpleTimeZone(0, "UTC"); } else { pTimeZone = SimpleTimeZone.getTimeZone(sTimeZoneID_); } Util.debug("Util.getCalendar(): pTimeZone: " + pTimeZone); // New Daylight Saving Time Convention in 35 European Countries if (sTimeZoneID_.equals("CET")) { pTimeZone = new SimpleTimeZone( 1 * 1000 * 60 * 60 , "CET" , Calendar.MARCH, -1 , Calendar.SUNDAY , 2 * 1000 * 60 * 60 , Calendar.OCTOBER , -1 , Calendar.SUNDAY , 2 * 1000 * 60 * 60 ); } Util.debug("Util.getCalendar(): pTimeZone: " + pTimeZone); Calendar pCalendar = new GregorianCalendar(pTimeZone); return pCalendar; } /** * @return Calendar with local timezone */ public static Calendar getCalendar() { return getCalendar( Calendar.getInstance().getTimeZone().getID() ); } /** * @param sTime_ e.g. 23:59:59 */ public static void setTime( Calendar pCalendar_, String sTime_ ) { panicIf( sTime_ == null ); panicIf( sTime_.length() != 8 ); String sDate = Util.getDate( pCalendar_ ); pCalendar_.setTime( new Date( 0 ) ); pCalendar_.set( atoi( sDate.substring( 0, 4 ) ), // year atoi( sDate.substring( 5, 7 ) ) - 1, // month atoi( sDate.substring( 8 ) ), // day atoi( sTime_.substring( 0, 2 ) ), atoi( sTime_.substring( 3, 5 ) ), atoi( sTime_.substring( 6, 8 ) ) ); Util.debug( "ccl.util.Util.setTime(..).time: " + pCalendar_.getTime().getTime() ); long lTime = pCalendar_.getTime().getTime(); Util.debug( "ccl.util.Util.setTime(..).time%1000: " + lTime % 1000L ); Util.debug( "ccl.util.Util.setTime(..).time: " + pCalendar_.getTime().getTime() ); } /** * @param sDate_ e.g. 2000-01-26 */ public static void setDate( Calendar pCalendar_, String sDate_ ) { panicIf( sDate_ == null ); panicIf( sDate_.length() != 10 ); String sTime = Util.getTime( pCalendar_ ); pCalendar_.setTime( new Date( 0 ) ); pCalendar_.set( atoi( sDate_.substring( 0, 4 ) ), // year atoi( sDate_.substring( 5, 7 ) ) - 1, // month atoi( sDate_.substring( 8 ) ), // day atoi( sTime.substring( 0, 2 ) ), atoi( sTime.substring( 3, 5 ) ), atoi( sTime.substring( 6, 8 ) ) ); } /** * Input format of the date is either CCYY-MM-DD or * CCYYMMDD. */ public static boolean isDateValid( String sDate_ ) { if ( sDate_ == null || (sDate_.length() != 8 && sDate_.length() != 10) ) { return false; } Date pDate = Util.stringToDate( sDate_ ); Date dtValidation = new Date( pDate.getTime() ); String sValidation = Util.getStandardDate( dtValidation ); sValidation = Util.replace( sValidation, "-", "" ); //String sValidation = Util.getStandardDate( pDate ); return sValidation.equals( Util.replace( sDate_, "-", "" ) ); } /** * Return the number of days between to dates. * The first day and last day are both also counted. */ public static int getNumberOfDays( String sFrom_, String sTo_ ) { Calendar calFrom = getDate( sFrom_ ); Calendar calTo = getDate( sTo_ ); long diff = calTo.getTime().getTime() - calFrom.getTime().getTime(); diff = diff / (1000L * 60L * 60L * 24L) + 1L; return (int) diff; } /** * Provides the iso date of the next day after the given * date. */ public static String getNextDay( String sDate_ ) { Calendar calendar = getDate( sDate_ ); calendar.add( Calendar.DATE, 1 ); return getDate( calendar ); } /** * Provide an iso date string and get back an iso date * string with the last day in the same month. */ public static String getLastDayOfMonth( String sDate_ ) { Calendar calendar = getDate( sDate_ ); calendar.set( Calendar.DATE , 1 ); calendar.add( Calendar.MONTH, 1 ); calendar.add( Calendar.DATE , -1 ); return getDate( calendar ); } /** * Provide an iso date string and get back an iso date * string which has the day set to one. */ public static String getFirstDayOfMonth( String sDate_ ) { Calendar calendar = getDate( sDate_ ); calendar.set( Calendar.DATE , 1 ); return getDate( calendar ); } /** * Returns the English name of the month of the given * iso-date. */ public static String getMonth( String sDate ) { int month = Util.atoi( sDate.substring( 5, 7 ) ); if ( month == 1 ) { return "Januar"; } else if ( month == 2 ) { return "February"; } else if ( month == 3 ) { return "March"; } else if ( month == 4 ) { return "April"; } else if ( month == 5 ) { return "May"; } else if ( month == 6 ) { return "June"; } else if ( month == 7 ) { return "July"; } else if ( month == 8 ) { return "August"; } else if ( month == 9 ) { return "September"; } else if ( month == 10 ) { return "October"; } else if ( month == 11 ) { return "November"; } else if ( month == 12 ) { return "December"; } return null; } /** * @deprecated use getDate() instead. */ public static String getTodaySortable() { String sDatum = null; Date date = new Date(); Calendar calendar = new GregorianCalendar(); calendar.setTime(date); sDatum = itoa(calendar.get(Calendar.YEAR)); if (calendar.get(Calendar.MONTH) < 9) { sDatum += "0"; } sDatum += itoa(calendar.get(Calendar.MONTH) + 1); if (calendar.get(Calendar.DATE) < 10) { sDatum += "0"; } sDatum += itoa(calendar.get(Calendar.DATE)); return sDatum; } /** * @deprecated * @see #getTodaySortable() */ public static String getHeuteSortable() { return getTodaySortable(); } /*public static long timeToSeconds(String sTime_) { return ((long)MultiDate.getSecondsFromTime(sTime_)); }*/ // ----------------------------------------------------- // miscelaneous methods // ----------------------------------------------------- /** * Sometimes you need a dummy object just to have any * value for a hashtable or so and it doesn't matter at * all if we always use the same object, so here is one * you can use without wasting extra memory. */ public static Object getConstantObject() { return O_CONSTANT; } /** * Current thread sleeps in seconds. */ public static void sleep( int seconds_ ) { try { Thread.currentThread().sleep( seconds_ * 1000 ); } catch( Exception pException) { } } /** * Checks that a character is of type alpha. This means either the given character * is in range a-z or it is a German umlaut (sorry, no other countries are * supported right now - please add what you need). * * @param c_ a character to test for alpha status. * * @return true if the input character is of type alpha * (A-Za-z or German umlaut). */ public static boolean isAlpha(char c_) { if (('A' <= c_ && c_ <= 'Z') || ('a' <= c_ && c_ <= 'z')) { return true; } for(int i = 0; i < AC_UMLAUT.length; i++) { if (c_ == AC_UMLAUT[i]) { return true; } } return false; } /** * @deprecated * @see java.lang.Math#max(long, long) java.lang.Math.max */ public static long max(long a_, long b_) { if (a_ > b_) { return a_; } return(b_); } /** * @deprecated * @see java.lang.Math#max(int, int) java.lang.Math.max */ public static int max(int a_, int b_) { if (a_ > b_) { return a_; } return(b_); } /** * @deprecated * @see java.lang.Math#min(int, int) java.lang.Math.min */ public static int min(int a_, int b_) { if (a_ < b_) { return a_; } return(b_); } /** * This method is the first part of a service to swap two objects in less than * 3 steps. * Normally if you swap two objects you need 3 statements.<br> * c = a; a = b; b = c;<br> * Using this method plus method swap() you can get away with only two statements * in your code.<p> * * For example:<br> * o1 = swap(o1, o2); * o2 = swap(); * * @return the second input parameter object. * * @see #swap() swap */ public static Object swap(Object objFirst, Object objSecond) { panicIf(_bNochKeinSwap == false); _bNochKeinSwap = false; _objSwap = objFirst; return(objSecond); } /** * This method is the second step of a service to swap two objects * in less than 3 steps. * Normally if you swap two objects you need 3 statements.<br> * c = a; a = b; b = c;<br> * Using this method plus method swap() you can get away with only two * statements in your code.<p> * * Note that this method will keep a reference to the first object until * the swap method pair will be used again with a new pair of parameters!!! * * @return the first input parameter object from a previous * swap(Object, Object) invocation. * * @see #swap(java.lang.Object, java.lang.Object) swap */ public static Object swap() { panicIf(_bNochKeinSwap == true); _bNochKeinSwap = true; return(_objSwap); //_objSwap = null; } /** * This method is the first part of a service to swap two int values in less * than 3 steps. * Normally if you swap two objects you need 3 statements.<br> * c = a; a = b; b = c;<br> * Using this method plus method swap() you can get away with only two statements * in your code. * * @return the second input parameter object. * * @see #swapInt() swapInt */ public static int swapInt(int first, int second) { panicIf(_bNochKeinIntSwap == false); _bNochKeinIntSwap = false; _swap = first; return(second); } /** * This method is the second step of a service to swap two int values * in less than 3 steps. * Normally if you swap two objects you need 3 statements.<br> * c = a; a = b; b = c;<br> * Using this method plus method swap() you can get away with only two * statements in your code. * * @return the first input parameter object from a previous * swap(Object, Object) invocation. * * @see #swapInt(int, int) swapInt */ public static int swapInt() { panicIf(_bNochKeinIntSwap == true); _bNochKeinIntSwap = true; return(_swap); } /** * pObject_.getClass().getName() returns the name including * its package. This method returns just the name without * its package. */ public static String getObjectName( Object pObject_ ) { String sRetVal = pObject_.getClass().getName(); sRetVal = sRetVal.substring( sRetVal.lastIndexOf( '.' ) + 1 ); return sRetVal; } /** * This method returns the memory currently in use. */ public static long getUsedMemory() { long total = Runtime.getRuntime().totalMemory(); long free = Runtime.getRuntime().freeMemory (); return total - free; } /** * This method returns the percentage of used memory. */ public static String getUsedMemoryPercentage() { long total = Runtime.getRuntime().totalMemory(); long used = getUsedMemory(); return getUsedMemoryPercentage( total, used ); } /** * This method returns the percentage of used memory. */ public static String getUsedMemoryPercentage( long used , long total ) { int percentage = (int) (used * 1000 / total); String sPercentage = Util.itoa( percentage / 10 ) + "." + Util.itoa( percentage % 10 ) + " %"; return sPercentage; } /** * Returns a message which has nicely formatted information about the * current memory usage. */ public static String formatMemoryInfo() { long total = Runtime.getRuntime().totalMemory(); long free = Runtime.getRuntime().freeMemory (); long used = total - free; NumberFormat pNumberFormat = DecimalFormat.getInstance( Locale.US ); String sTotal = pNumberFormat.format( total ); String sUsed = pNumberFormat.format( used ); sUsed = getSpaces( sTotal.length() - sUsed.length() ) + sUsed; return "Memory (in use/total): " + sUsed + " / " + sTotal + " (" + getUsedMemoryPercentage( used, total ) + ")"; } }