rio, lca, refactoring
[jalview.git] / forester / java / src / org / forester / util / ForesterUtil.java
1 // $Id:
2 // FORESTER -- software libraries and applications
3 // for evolutionary biology research and applications.
4 //
5 // Copyright (C) 2008-2009 Christian M. Zmasek
6 // Copyright (C) 2008-2009 Burnham Institute for Medical Research
7 // All rights reserved
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 //
23 // Contact: phylosoft @ gmail . com
24 // WWW: www.phylosoft.org/forester
25
26 package org.forester.util;
27
28 import java.awt.Color;
29 import java.io.BufferedReader;
30 import java.io.BufferedWriter;
31 import java.io.File;
32 import java.io.FileInputStream;
33 import java.io.FileNotFoundException;
34 import java.io.FileOutputStream;
35 import java.io.FileReader;
36 import java.io.FileWriter;
37 import java.io.IOException;
38 import java.io.InputStream;
39 import java.io.InputStreamReader;
40 import java.io.StringReader;
41 import java.io.Writer;
42 import java.math.BigDecimal;
43 import java.net.URL;
44 import java.text.DateFormat;
45 import java.text.DecimalFormat;
46 import java.text.DecimalFormatSymbols;
47 import java.text.NumberFormat;
48 import java.text.ParseException;
49 import java.text.SimpleDateFormat;
50 import java.util.ArrayList;
51 import java.util.Collection;
52 import java.util.Date;
53 import java.util.Iterator;
54 import java.util.List;
55 import java.util.Map;
56 import java.util.Map.Entry;
57 import java.util.Set;
58 import java.util.SortedMap;
59 import java.util.SortedSet;
60 import java.util.TreeMap;
61 import java.util.TreeSet;
62 import java.util.regex.Pattern;
63
64 public final class ForesterUtil {
65
66     public final static String       FILE_SEPARATOR                   = System.getProperty( "file.separator" );
67     public final static String       LINE_SEPARATOR                   = System.getProperty( "line.separator" );
68     public final static String       JAVA_VENDOR                      = System.getProperty( "java.vendor" );
69     public final static String       JAVA_VERSION                     = System.getProperty( "java.version" );
70     public final static String       OS_ARCH                          = System.getProperty( "os.arch" );
71     public final static String       OS_NAME                          = System.getProperty( "os.name" );
72     public final static String       OS_VERSION                       = System.getProperty( "os.version" );
73     public final static Pattern      PARANTHESESABLE_NH_CHARS_PATTERN = Pattern.compile( "[(),;\\s]" );
74     public final static double       ZERO_DIFF                        = 1.0E-9;
75     public static final BigDecimal   NULL_BD                          = new BigDecimal( 0 );
76     public static final NumberFormat FORMATTER_9;
77     public static final NumberFormat FORMATTER_6;
78     public static final NumberFormat FORMATTER_06;
79     public static final NumberFormat FORMATTER_3;
80     static {
81         final DecimalFormatSymbols dfs = new DecimalFormatSymbols();
82         dfs.setDecimalSeparator( '.' );
83         // dfs.setGroupingSeparator( ( char ) 0 );
84         FORMATTER_9 = new DecimalFormat( "#.#########", dfs );
85         FORMATTER_6 = new DecimalFormat( "#.######", dfs );
86         FORMATTER_06 = new DecimalFormat( "0.######", dfs );
87         FORMATTER_3 = new DecimalFormat( "#.###", dfs );
88     }
89
90     private ForesterUtil() {
91     }
92
93     final public static void appendSeparatorIfNotEmpty( final StringBuffer sb, final char separator ) {
94         if ( sb.length() > 0 ) {
95             sb.append( separator );
96         }
97     }
98
99     public static boolean isWindowns() {
100         return ForesterUtil.OS_NAME.toLowerCase().indexOf( "win" ) > -1;
101     }
102
103     final public static String getForesterLibraryInformation() {
104         return "forester " + ForesterConstants.FORESTER_VERSION + " (" + ForesterConstants.FORESTER_DATE + ")";
105     }
106
107     public static boolean seqIsLikelyToBeAa( final String s ) {
108         final String seq = s.toLowerCase();
109         if ( ( seq.indexOf( 'r' ) > -1 ) || ( seq.indexOf( 'd' ) > -1 ) || ( seq.indexOf( 'e' ) > -1 )
110                 || ( seq.indexOf( 'q' ) > -1 ) || ( seq.indexOf( 'h' ) > -1 ) || ( seq.indexOf( 'k' ) > -1 )
111                 || ( seq.indexOf( 'w' ) > -1 ) || ( seq.indexOf( 's' ) > -1 ) || ( seq.indexOf( 'm' ) > -1 )
112                 || ( seq.indexOf( 'p' ) > -1 ) || ( seq.indexOf( 'v' ) > -1 ) ) {
113             return true;
114         }
115         return false;
116     }
117
118     /**
119      * This calculates a color. If value is equal to min the returned color is
120      * minColor, if value is equal to max the returned color is maxColor,
121      * otherwise a color 'proportional' to value is returned.
122      * 
123      * @param value
124      *            the value 
125      * @param min
126      *            the smallest value 
127      * @param max
128      *            the largest value 
129      * @param minColor
130      *            the color for min
131      * @param maxColor
132      *            the color for max
133      * @return a Color
134      */
135     final public static Color calcColor( double value,
136                                          final double min,
137                                          final double max,
138                                          final Color minColor,
139                                          final Color maxColor ) {
140         if ( value < min ) {
141             value = min;
142         }
143         if ( value > max ) {
144             value = max;
145         }
146         final double x = ForesterUtil.calculateColorFactor( value, max, min );
147         final int red = ForesterUtil.calculateColorComponent( minColor.getRed(), maxColor.getRed(), x );
148         final int green = ForesterUtil.calculateColorComponent( minColor.getGreen(), maxColor.getGreen(), x );
149         final int blue = ForesterUtil.calculateColorComponent( minColor.getBlue(), maxColor.getBlue(), x );
150         return new Color( red, green, blue );
151     }
152
153     /**
154      * This calculates a color. If value is equal to min the returned color is
155      * minColor, if value is equal to max the returned color is maxColor, if
156      * value is equal to mean the returned color is meanColor, otherwise a color
157      * 'proportional' to value is returned -- either between min-mean or
158      * mean-max
159      * 
160      * @param value
161      *            the value
162      * @param min
163      *            the smallest value
164      * @param max
165      *            the largest value 
166      * @param mean
167      *            the mean/median value 
168      * @param minColor
169      *            the color for min
170      * @param maxColor
171      *            the color for max
172      * @param meanColor
173      *            the color for mean
174      * @return a Color
175      */
176     final public static Color calcColor( double value,
177                                          final double min,
178                                          final double max,
179                                          final double mean,
180                                          final Color minColor,
181                                          final Color maxColor,
182                                          final Color meanColor ) {
183         if ( value < min ) {
184             value = min;
185         }
186         if ( value > max ) {
187             value = max;
188         }
189         if ( value < mean ) {
190             final double x = ForesterUtil.calculateColorFactor( value, mean, min );
191             final int red = ForesterUtil.calculateColorComponent( minColor.getRed(), meanColor.getRed(), x );
192             final int green = ForesterUtil.calculateColorComponent( minColor.getGreen(), meanColor.getGreen(), x );
193             final int blue = ForesterUtil.calculateColorComponent( minColor.getBlue(), meanColor.getBlue(), x );
194             return new Color( red, green, blue );
195         }
196         else if ( value > mean ) {
197             final double x = ForesterUtil.calculateColorFactor( value, max, mean );
198             final int red = ForesterUtil.calculateColorComponent( meanColor.getRed(), maxColor.getRed(), x );
199             final int green = ForesterUtil.calculateColorComponent( meanColor.getGreen(), maxColor.getGreen(), x );
200             final int blue = ForesterUtil.calculateColorComponent( meanColor.getBlue(), maxColor.getBlue(), x );
201             return new Color( red, green, blue );
202         }
203         else {
204             return meanColor;
205         }
206     }
207
208     /**
209      * Helper method for calcColor methods.
210      * 
211      * @param smallercolor_component_x
212      *            color component the smaller color
213      * @param largercolor_component_x
214      *            color component the larger color
215      * @param x
216      *            factor
217      * @return an int representing a color component
218      */
219     final private static int calculateColorComponent( final double smallercolor_component_x,
220                                                       final double largercolor_component_x,
221                                                       final double x ) {
222         return ( int ) ( smallercolor_component_x + ( ( x * ( largercolor_component_x - smallercolor_component_x ) ) / 255.0 ) );
223     }
224
225     /**
226      * Helper method for calcColor methods.
227      * 
228      * 
229      * @param value
230      *            the value
231      * @param larger
232      *            the largest value
233      * @param smaller
234      *            the smallest value
235      * @return a normalized value between larger and smaller
236      */
237     final private static double calculateColorFactor( final double value, final double larger, final double smaller ) {
238         return ( 255.0 * ( value - smaller ) ) / ( larger - smaller );
239     }
240
241     final public static String collapseWhiteSpace( final String s ) {
242         return s.replaceAll( "[\\s]+", " " );
243     }
244
245     final public static void collection2file( final File file, final Collection<?> data, final String separator )
246             throws IOException {
247         final Writer writer = new BufferedWriter( new FileWriter( file ) );
248         collection2writer( writer, data, separator );
249         writer.close();
250     }
251
252     final public static void collection2writer( final Writer writer, final Collection<?> data, final String separator )
253             throws IOException {
254         boolean first = true;
255         for( final Object object : data ) {
256             if ( !first ) {
257                 writer.write( separator );
258             }
259             else {
260                 first = false;
261             }
262             writer.write( object.toString() );
263         }
264     }
265
266     final public static String colorToHex( final Color color ) {
267         final String rgb = Integer.toHexString( color.getRGB() );
268         return rgb.substring( 2, rgb.length() );
269     }
270
271     synchronized public static void copyFile( final File in, final File out ) throws IOException {
272         final FileInputStream in_s = new FileInputStream( in );
273         final FileOutputStream out_s = new FileOutputStream( out );
274         try {
275             final byte[] buf = new byte[ 1024 ];
276             int i = 0;
277             while ( ( i = in_s.read( buf ) ) != -1 ) {
278                 out_s.write( buf, 0, i );
279             }
280         }
281         catch ( final IOException e ) {
282             throw e;
283         }
284         finally {
285             if ( in_s != null ) {
286                 in_s.close();
287             }
288             if ( out_s != null ) {
289                 out_s.close();
290             }
291         }
292     }
293
294     final public static int countChars( final String str, final char c ) {
295         int count = 0;
296         for( int i = 0; i < str.length(); ++i ) {
297             if ( str.charAt( i ) == c ) {
298                 ++count;
299             }
300         }
301         return count;
302     }
303
304     final public static BufferedWriter createBufferedWriter( final File file ) throws IOException {
305         if ( file.exists() ) {
306             throw new IOException( "[" + file + "] already exists" );
307         }
308         return new BufferedWriter( new FileWriter( file ) );
309     }
310
311     final public static EasyWriter createEasyWriter( final File file ) throws IOException {
312         return new EasyWriter( createBufferedWriter( file ) );
313     }
314
315     final public static BufferedWriter createEasyWriter( final String name ) throws IOException {
316         return createEasyWriter( createFileForWriting( name ) );
317     }
318
319     final public static BufferedWriter createBufferedWriter( final String name ) throws IOException {
320         return new BufferedWriter( new FileWriter( createFileForWriting( name ) ) );
321     }
322
323     final public static File createFileForWriting( final String name ) throws IOException {
324         final File file = new File( name );
325         if ( file.exists() ) {
326             throw new IOException( "[" + name + "] already exists" );
327         }
328         return file;
329     }
330
331     public static void fatalError( final String prg_name, final String message ) {
332         System.err.println();
333         System.err.println( "[" + prg_name + "] > " + message );
334         System.err.println();
335         System.exit( -1 );
336     }
337
338     public static String[] file2array( final File file ) throws IOException {
339         final List<String> list = file2list( file );
340         final String[] ary = new String[ list.size() ];
341         int i = 0;
342         for( final String s : list ) {
343             ary[ i++ ] = s;
344         }
345         return ary;
346     }
347
348     final public static List<String> file2list( final File file ) throws IOException {
349         final List<String> list = new ArrayList<String>();
350         final BufferedReader in = new BufferedReader( new FileReader( file ) );
351         String str;
352         while ( ( str = in.readLine() ) != null ) {
353             str = str.trim();
354             if ( ( str.length() > 0 ) && !str.startsWith( "#" ) ) {
355                 for( final String s : splitString( str ) ) {
356                     list.add( s );
357                 }
358             }
359         }
360         in.close();
361         return list;
362     }
363
364     final public static SortedSet<String> file2set( final File file ) throws IOException {
365         final SortedSet<String> set = new TreeSet<String>();
366         final BufferedReader in = new BufferedReader( new FileReader( file ) );
367         String str;
368         while ( ( str = in.readLine() ) != null ) {
369             str = str.trim();
370             if ( ( str.length() > 0 ) && !str.startsWith( "#" ) ) {
371                 for( final String s : splitString( str ) ) {
372                     set.add( s );
373                 }
374             }
375         }
376         in.close();
377         return set;
378     }
379
380     final public static String getCurrentDateTime() {
381         final DateFormat format = new SimpleDateFormat( "yyyy/MM/dd HH:mm:ss" );
382         return format.format( new Date() );
383     }
384
385     final public static String getFileSeparator() {
386         return ForesterUtil.FILE_SEPARATOR;
387     }
388
389     final public static String getFirstLine( final Object source ) throws FileNotFoundException, IOException {
390         BufferedReader reader = null;
391         if ( source instanceof File ) {
392             final File f = ( File ) source;
393             if ( !f.exists() ) {
394                 throw new IOException( "[" + f.getAbsolutePath() + "] does not exist" );
395             }
396             else if ( !f.isFile() ) {
397                 throw new IOException( "[" + f.getAbsolutePath() + "] is not a file" );
398             }
399             else if ( !f.canRead() ) {
400                 throw new IOException( "[" + f.getAbsolutePath() + "] is not a readable" );
401             }
402             reader = new BufferedReader( new FileReader( f ) );
403         }
404         else if ( source instanceof InputStream ) {
405             reader = new BufferedReader( new InputStreamReader( ( InputStream ) source ) );
406         }
407         else if ( source instanceof String ) {
408             reader = new BufferedReader( new StringReader( ( String ) source ) );
409         }
410         else if ( source instanceof StringBuffer ) {
411             reader = new BufferedReader( new StringReader( source.toString() ) );
412         }
413         else if ( source instanceof URL ) {
414             reader = new BufferedReader( new InputStreamReader( ( ( URL ) source ).openStream() ) );
415         }
416         else {
417             throw new IllegalArgumentException( "dont know how to read [" + source.getClass() + "]" );
418         }
419         String line;
420         while ( ( line = reader.readLine() ) != null ) {
421             line = line.trim();
422             if ( !ForesterUtil.isEmpty( line ) ) {
423                 if ( reader != null ) {
424                     reader.close();
425                 }
426                 return line;
427             }
428         }
429         if ( reader != null ) {
430             reader.close();
431         }
432         return line;
433     }
434
435     final public static String getLineSeparator() {
436         return ForesterUtil.LINE_SEPARATOR;
437     }
438
439     final public static void increaseCountingMap( final Map<String, Integer> counting_map, final String item_name ) {
440         if ( !counting_map.containsKey( item_name ) ) {
441             counting_map.put( item_name, 1 );
442         }
443         else {
444             counting_map.put( item_name, counting_map.get( item_name ) + 1 );
445         }
446     }
447
448     final public static boolean isContainsParanthesesableNhCharacter( final String nh ) {
449         return PARANTHESESABLE_NH_CHARS_PATTERN.matcher( nh ).find();
450     }
451
452     final public static boolean isEmpty( final List<?> l ) {
453         if ( ( l == null ) || l.isEmpty() ) {
454             return true;
455         }
456         for( final Object o : l ) {
457             if ( o != null ) {
458                 return false;
459             }
460         }
461         return true;
462     }
463
464     final public static boolean isEmpty( final Set<?> s ) {
465         if ( ( s == null ) || s.isEmpty() ) {
466             return true;
467         }
468         for( final Object o : s ) {
469             if ( o != null ) {
470                 return false;
471             }
472         }
473         return true;
474     }
475
476     final public static boolean isEmpty( final String s ) {
477         return ( ( s == null ) || ( s.length() < 1 ) );
478     }
479
480     final public static boolean isEqual( final double a, final double b ) {
481         return ( ( Math.abs( a - b ) ) < ZERO_DIFF );
482     }
483
484     final public static boolean isEven( final int n ) {
485         return ( n % 2 ) == 0;
486     }
487
488     /**
489      * This determines whether String[] a and String[] b have at least one
490      * String in common (intersect). Returns false if at least one String[] is
491      * null or empty.
492      * 
493      * @param a
494      *            a String[] b a String[]
495      * @return true if both a and b or not empty or null and contain at least
496      *         one element in common false otherwise
497      */
498     final public static boolean isIntersecting( final String[] a, final String[] b ) {
499         if ( ( a == null ) || ( b == null ) ) {
500             return false;
501         }
502         if ( ( a.length < 1 ) || ( b.length < 1 ) ) {
503             return false;
504         }
505         for( final String ai : a ) {
506             for( final String element : b ) {
507                 if ( ( ai != null ) && ( element != null ) && ai.equals( element ) ) {
508                     return true;
509                 }
510             }
511         }
512         return false;
513     }
514
515     final public static double isLargerOrEqualToZero( final double d ) {
516         if ( d > 0.0 ) {
517             return d;
518         }
519         else {
520             return 0.0;
521         }
522     }
523
524     final public static boolean isNull( final BigDecimal s ) {
525         return ( ( s == null ) || ( s.compareTo( NULL_BD ) == 0 ) );
526     }
527
528     final public static String isReadableFile( final File f ) {
529         if ( !f.exists() ) {
530             return "file [" + f + "] does not exist";
531         }
532         if ( f.isDirectory() ) {
533             return "[" + f + "] is a directory";
534         }
535         if ( !f.isFile() ) {
536             return "[" + f + "] is not a file";
537         }
538         if ( !f.canRead() ) {
539             return "file [" + f + "] is not readable";
540         }
541         if ( f.length() < 1 ) {
542             return "file [" + f + "] is empty";
543         }
544         return null;
545     }
546
547     final public static String isReadableFile( final String s ) {
548         return isReadableFile( new File( s ) );
549     }
550
551     final public static String isWritableFile( final File f ) {
552         if ( f.isDirectory() ) {
553             return "[" + f + "] is a directory";
554         }
555         if ( f.exists() ) {
556             return "[" + f + "] already exists";
557         }
558         return null;
559     }
560
561     /**
562      * Helper for method "stringToColor".
563      * <p>
564      * (Last modified: 12/20/03)
565      */
566     final public static int limitRangeForColor( int i ) {
567         if ( i > 255 ) {
568             i = 255;
569         }
570         else if ( i < 0 ) {
571             i = 0;
572         }
573         return i;
574     }
575
576     final public static SortedMap<Object, Integer> listToSortedCountsMap( final List list ) {
577         final SortedMap<Object, Integer> map = new TreeMap<Object, Integer>();
578         for( final Object key : list ) {
579             if ( !map.containsKey( key ) ) {
580                 map.put( key, 1 );
581             }
582             else {
583                 map.put( key, map.get( key ) + 1 );
584             }
585         }
586         return map;
587     }
588
589     final public static void map2file( final File file,
590                                        final Map<?, ?> data,
591                                        final String entry_separator,
592                                        final String data_separator ) throws IOException {
593         final Writer writer = new BufferedWriter( new FileWriter( file ) );
594         map2writer( writer, data, entry_separator, data_separator );
595         writer.close();
596     }
597
598     final public static void map2writer( final Writer writer,
599                                          final Map<?, ?> data,
600                                          final String entry_separator,
601                                          final String data_separator ) throws IOException {
602         boolean first = true;
603         for( final Entry<?, ?> entry : data.entrySet() ) {
604             if ( !first ) {
605                 writer.write( data_separator );
606             }
607             else {
608                 first = false;
609             }
610             writer.write( entry.getKey().toString() );
611             writer.write( entry_separator );
612             writer.write( entry.getValue().toString() );
613         }
614     }
615
616     final public static StringBuffer mapToStringBuffer( final Map map, final String key_value_separator ) {
617         final StringBuffer sb = new StringBuffer();
618         for( final Iterator iter = map.keySet().iterator(); iter.hasNext(); ) {
619             final Object key = iter.next();
620             sb.append( key.toString() );
621             sb.append( key_value_separator );
622             sb.append( map.get( key ).toString() );
623             sb.append( ForesterUtil.getLineSeparator() );
624         }
625         return sb;
626     }
627
628     final public static String normalizeString( final String s,
629                                                 final int length,
630                                                 final boolean left_pad,
631                                                 final char pad_char ) {
632         if ( s.length() > length ) {
633             return s.substring( 0, length );
634         }
635         else {
636             final StringBuffer pad = new StringBuffer( length - s.length() );
637             for( int i = 0; i < ( length - s.length() ); ++i ) {
638                 pad.append( pad_char );
639             }
640             if ( left_pad ) {
641                 return pad + s;
642             }
643             else {
644                 return s + pad;
645             }
646         }
647     }
648
649     final public static BufferedReader obtainReader( final Object source ) throws IOException, FileNotFoundException {
650         BufferedReader reader = null;
651         if ( source instanceof File ) {
652             final File f = ( File ) source;
653             if ( !f.exists() ) {
654                 throw new IOException( "\"" + f.getAbsolutePath() + "\" does not exist" );
655             }
656             else if ( !f.isFile() ) {
657                 throw new IOException( "\"" + f.getAbsolutePath() + "\" is not a file" );
658             }
659             else if ( !f.canRead() ) {
660                 throw new IOException( "\"" + f.getAbsolutePath() + "\" is not a readable" );
661             }
662             reader = new BufferedReader( new FileReader( f ) );
663         }
664         else if ( source instanceof InputStream ) {
665             reader = new BufferedReader( new InputStreamReader( ( InputStream ) source ) );
666         }
667         else if ( source instanceof String ) {
668             reader = new BufferedReader( new StringReader( ( String ) source ) );
669         }
670         else if ( source instanceof StringBuffer ) {
671             reader = new BufferedReader( new StringReader( source.toString() ) );
672         }
673         else {
674             throw new IllegalArgumentException( "attempt to parse object of type [" + source.getClass()
675                     + "] (can only parse objects of type File, InputStream, String, or StringBuffer)" );
676         }
677         return reader;
678     }
679
680     final public static StringBuffer pad( final double number, final int size, final char pad, final boolean left_pad ) {
681         return pad( new StringBuffer( number + "" ), size, pad, left_pad );
682     }
683
684     final public static StringBuffer pad( final String string, final int size, final char pad, final boolean left_pad ) {
685         return pad( new StringBuffer( string ), size, pad, left_pad );
686     }
687
688     final public static StringBuffer pad( final StringBuffer string,
689                                           final int size,
690                                           final char pad,
691                                           final boolean left_pad ) {
692         final StringBuffer padding = new StringBuffer();
693         final int s = size - string.length();
694         if ( s < 1 ) {
695             return new StringBuffer( string.substring( 0, size ) );
696         }
697         for( int i = 0; i < s; ++i ) {
698             padding.append( pad );
699         }
700         if ( left_pad ) {
701             return padding.append( string );
702         }
703         else {
704             return string.append( padding );
705         }
706     }
707
708     final public static double parseDouble( final String str ) throws ParseException {
709         if ( ForesterUtil.isEmpty( str ) ) {
710             return 0.0;
711         }
712         return Double.parseDouble( str );
713     }
714
715     final public static int parseInt( final String str ) throws ParseException {
716         if ( ForesterUtil.isEmpty( str ) ) {
717             return 0;
718         }
719         return Integer.parseInt( str );
720     }
721
722     final public static void printArray( final Object[] a ) {
723         for( int i = 0; i < a.length; ++i ) {
724             System.out.println( "[" + i + "]=" + a[ i ] );
725         }
726     }
727
728     final public static void printCountingMap( final Map<String, Integer> counting_map ) {
729         for( final String key : counting_map.keySet() ) {
730             System.out.println( key + ": " + counting_map.get( key ) );
731         }
732     }
733
734     final public static void printErrorMessage( final String prg_name, final String message ) {
735         System.out.println( "[" + prg_name + "] > error: " + message );
736     }
737
738     final public static void printProgramInformation( final String prg_name, final String prg_version, final String date ) {
739         final int l = prg_name.length() + prg_version.length() + date.length() + 4;
740         System.out.println();
741         System.out.println( prg_name + " " + prg_version + " (" + date + ")" );
742         for( int i = 0; i < l; ++i ) {
743             System.out.print( "_" );
744         }
745         System.out.println();
746     }
747
748     final public static void printProgramInformation( final String prg_name,
749                                                       final String desc,
750                                                       final String prg_version,
751                                                       final String date,
752                                                       final String email,
753                                                       final String www,
754                                                       final String based_on ) {
755         String my_prg_name = new String( prg_name );
756         if ( !ForesterUtil.isEmpty( desc ) ) {
757             my_prg_name += ( " - " + desc );
758         }
759         final int l = my_prg_name.length() + prg_version.length() + date.length() + 4;
760         System.out.println();
761         System.out.println( my_prg_name + " " + prg_version + " (" + date + ")" );
762         for( int i = 0; i < l; ++i ) {
763             System.out.print( "_" );
764         }
765         System.out.println();
766         System.out.println();
767         System.out.println( "WWW     : " + www );
768         System.out.println( "Contact : " + email );
769         if ( !ForesterUtil.isEmpty( based_on ) ) {
770             System.out.println( "Based on: " + based_on );
771         }
772         if ( !ForesterUtil.isEmpty( ForesterUtil.JAVA_VERSION ) && !ForesterUtil.isEmpty( ForesterUtil.JAVA_VENDOR ) ) {
773             System.out.println();
774             System.out.println( "[running on Java " + ForesterUtil.JAVA_VERSION + " " + ForesterUtil.JAVA_VENDOR + "]" );
775         }
776         System.out.println();
777     }
778
779     final public static void printProgramInformation( final String prg_name,
780                                                       final String prg_version,
781                                                       final String date,
782                                                       final String email,
783                                                       final String www ) {
784         printProgramInformation( prg_name, null, prg_version, date, email, www, null );
785     }
786
787     final public static void printWarningMessage( final String prg_name, final String message ) {
788         System.out.println( "[" + prg_name + "] > warning: " + message );
789     }
790
791     final public static void programMessage( final String prg_name, final String message ) {
792         System.out.println( "[" + prg_name + "] > " + message );
793     }
794
795     final public static String removeSuffix( final String file_name ) {
796         final int i = file_name.lastIndexOf( '.' );
797         if ( i > 1 ) {
798             return file_name.substring( 0, i );
799         }
800         return file_name;
801     }
802
803     /**
804      * Removes all white space from String s.
805      * 
806      * @return String s with white space removed
807      */
808     final public static String removeWhiteSpace( String s ) {
809         int i;
810         for( i = 0; i <= ( s.length() - 1 ); i++ ) {
811             if ( ( s.charAt( i ) == ' ' ) || ( s.charAt( i ) == '\t' ) || ( s.charAt( i ) == '\n' )
812                     || ( s.charAt( i ) == '\r' ) ) {
813                 s = s.substring( 0, i ) + s.substring( i + 1 );
814                 i--;
815             }
816         }
817         return s;
818     }
819
820     final public static String replaceIllegalNhCharacters( final String nh ) {
821         if ( nh == null ) {
822             return "";
823         }
824         return nh.trim().replaceAll( "[\\[\\]:]+", "_" );
825     }
826
827     final public static String replaceIllegalNhxCharacters( final String nhx ) {
828         if ( nhx == null ) {
829             return "";
830         }
831         return nhx.trim().replaceAll( "[\\[\\](),:;\\s]+", "_" );
832     }
833
834     final public static double round( final double value, final int decimal_place ) {
835         BigDecimal bd = new BigDecimal( value );
836         bd = bd.setScale( decimal_place, BigDecimal.ROUND_HALF_UP );
837         return bd.doubleValue();
838     }
839
840     /**
841      * Rounds d to an int.
842      */
843     final public static int roundToInt( final double d ) {
844         return ( int ) ( d + 0.5 );
845     }
846
847     final public static int roundToInt( final float f ) {
848         return ( int ) ( f + 0.5f );
849     }
850
851     final public static short roundToShort( final double d ) {
852         return ( short ) ( d + 0.5 );
853     }
854
855     final public static String sanitizeString( final String s ) {
856         if ( s == null ) {
857             return "";
858         }
859         else {
860             return s.trim();
861         }
862     }
863
864     final private static String[] splitString( final String str ) {
865         final String regex = "[\\s;,]+";
866         return str.split( regex );
867     }
868
869     final public static String stringArrayToString( final String[] a ) {
870         return stringArrayToString( a, ", " );
871     }
872
873     final public static String stringArrayToString( final String[] a, final String separator ) {
874         final StringBuilder sb = new StringBuilder();
875         if ( ( a != null ) && ( a.length > 0 ) ) {
876             for( int i = 0; i < ( a.length - 1 ); ++i ) {
877                 sb.append( a[ i ] + separator );
878             }
879             sb.append( a[ a.length - 1 ] );
880         }
881         return sb.toString();
882     }
883
884     final public static String[] stringListToArray( final List<String> list ) {
885         if ( list != null ) {
886             final String[] str = new String[ list.size() ];
887             int i = 0;
888             for( final String l : list ) {
889                 str[ i++ ] = l;
890             }
891             return str;
892         }
893         return null;
894     }
895
896     final public static String stringListToString( final List<String> l, final String separator ) {
897         final StringBuilder sb = new StringBuilder();
898         if ( ( l != null ) && ( l.size() > 0 ) ) {
899             for( int i = 0; i < ( l.size() - 1 ); ++i ) {
900                 sb.append( l.get( i ) + separator );
901             }
902             sb.append( l.get( l.size() - 1 ) );
903         }
904         return sb.toString();
905     }
906
907     final public static String[] stringSetToArray( final Set<String> strings ) {
908         final String[] str_array = new String[ strings.size() ];
909         int i = 0;
910         for( final String e : strings ) {
911             str_array[ i++ ] = e;
912         }
913         return str_array;
914     }
915
916     final public static void unexpectedFatalError( final String prg_name, final Exception e ) {
917         System.err.println();
918         System.err.println( "[" + prg_name
919                 + "] > unexpected error (Should not have occured! Please contact program author(s).)" );
920         e.printStackTrace( System.err );
921         System.err.println();
922         System.exit( -1 );
923     }
924
925     final public static void unexpectedFatalError( final String prg_name, final String message ) {
926         System.err.println();
927         System.err.println( "[" + prg_name
928                 + "] > unexpected error. Should not have occured! Please contact program author(s)." );
929         System.err.println( message );
930         System.err.println();
931         System.exit( -1 );
932     }
933
934     final public static void unexpectedFatalError( final String prg_name, final String message, final Exception e ) {
935         System.err.println();
936         System.err.println( "[" + prg_name
937                 + "] > unexpected error. Should not have occured! Please contact program author(s)." );
938         System.err.println( message );
939         e.printStackTrace( System.err );
940         System.err.println();
941         System.exit( -1 );
942     }
943
944     public final static String wordWrap( final String str, final int width ) {
945         final StringBuilder sb = new StringBuilder( str );
946         int start = 0;
947         int ls = -1;
948         int i = 0;
949         while ( i < sb.length() ) {
950             if ( sb.charAt( i ) == ' ' ) {
951                 ls = i;
952             }
953             if ( sb.charAt( i ) == '\n' ) {
954                 ls = -1;
955                 start = i + 1;
956             }
957             if ( i > ( ( start + width ) - 1 ) ) {
958                 if ( ls != -1 ) {
959                     sb.setCharAt( ls, '\n' );
960                     start = ls + 1;
961                     ls = -1;
962                 }
963                 else {
964                     sb.insert( i, '\n' );
965                     start = i + 1;
966                 }
967             }
968             i++;
969         }
970         return sb.toString();
971     }
972 }