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