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