001/*
002 * Copyright 2006 - 2013
003 *     Stefan Balev     <stefan.balev@graphstream-project.org>
004 *     Julien Baudry    <julien.baudry@graphstream-project.org>
005 *     Antoine Dutot    <antoine.dutot@graphstream-project.org>
006 *     Yoann Pigné      <yoann.pigne@graphstream-project.org>
007 *     Guilhelm Savin   <guilhelm.savin@graphstream-project.org>
008 * 
009 * This file is part of GraphStream <http://graphstream-project.org>.
010 * 
011 * GraphStream is a library whose purpose is to handle static or dynamic
012 * graph, create them from scratch, file or any source and display them.
013 * 
014 * This program is free software distributed under the terms of two licenses, the
015 * CeCILL-C license that fits European law, and the GNU Lesser General Public
016 * License. You can  use, modify and/ or redistribute the software under the terms
017 * of the CeCILL-C license as circulated by CEA, CNRS and INRIA at the following
018 * URL <http://www.cecill.info> or under the terms of the GNU LGPL as published by
019 * the Free Software Foundation, either version 3 of the License, or (at your
020 * option) any later version.
021 * 
022 * This program is distributed in the hope that it will be useful, but WITHOUT ANY
023 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
024 * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
025 * 
026 * You should have received a copy of the GNU Lesser General Public License
027 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
028 * 
029 * The fact that you are presently reading this means that you have had
030 * knowledge of the CeCILL-C and LGPL licenses and that you accept their terms.
031 */
032package org.graphstream.util;
033
034import java.io.BufferedReader;
035import java.io.BufferedWriter;
036import java.io.FileNotFoundException;
037import java.io.FileReader;
038import java.io.FileWriter;
039import java.io.IOException;
040import java.io.PrintStream;
041import java.lang.reflect.InvocationTargetException;
042import java.lang.reflect.Method;
043import java.util.Arrays;
044import java.util.Collection;
045import java.util.HashSet;
046import java.util.Hashtable;
047import java.util.Set;
048
049/**
050 * Representation of a set of parameters.
051 * 
052 * <p>
053 * The environment class mimics the environment variables available in any shell
054 * using a hash map of keys/values, the key being the variables names, excepted
055 * here they are called parameters.
056 * </p>
057 * 
058 * <p>
059 * In addition, this class provides facilities to:
060 * <ul>
061 * <li>Read a parameter file and set the parameters from this file;</li>
062 * <li>Write a parameter file from the parameter of this environment;</li>
063 * <li>Parse the command line and get parameters from it;</li>
064 * <li>Take a class as argument and set all its fields having the same name as
065 * parameters in this class;</li>
066 * </ul>
067 * </p>
068 * 
069 * <p>
070 * As in any shell, most of the time, the environment is global and accessible
071 * from any part of the system. Here a singleton instance of this class is
072 * created and accessible from anywhere in the JVM using the
073 * {@link #getGlobalEnvironment()} method (indeed the singleton instance is
074 * created at its first access). However, it is still possible to create a
075 * private instance of this class for use in a specific part of a program.
076 * </p>
077 * 
078 * <p>
079 * To read a file of parameters, simply call the
080 * {@link #readParameterFile(String)} method. In the same way, to write a set of
081 * parameters to a file, call the {@link #writeParameterFile(String)} method.
082 * The format of the parameter file is given in the description of these
083 * methods.
084 * </p>
085 * 
086 * <p>
087 * To read parameters from he command line, call the
088 * {@link #readCommandLine(String[])} or
089 * {@link #readCommandLine(String[], Collection)} methods. These methods expect
090 * a format for the command line that is described in there respective
091 * documentations.
092 * </p>
093 * 
094 * <p>
095 * It is also possible to setup automatically the fields of an arbitrary object,
096 * provided these fields have name that match parameters in this environment. To
097 * do this call the {@link #initializeFieldsOf(Object)} method passing the
098 * object to initialise as argument. The object to setup must provide methods of
099 * the form "setThing(Type)" where "Thing" or "thing" is the name of the field
100 * to set and "Type" is one of "int", "long", "float", "double", "String" and
101 * "boolean". For the boolean type, the accepted values meaning true are "true",
102 * "on", "1", and "yes", all other value are considered as false.
103 * </p>
104 * 
105 * TODO: how (or when) does the default configuration file is read? 
106 * TODO: how to handle parameters that cannot be setup in the {@link #initializeFieldsOf(Object)}?
107 * 
108 * @author Frédéric Guinand
109 * @author Yoann Pigné
110 * @author Antoine Dutot
111 * @version 1.0 (jdk 1.5)
112 */
113public class Environment implements Cloneable
114{
115        // ---------- Attributes -----------
116
117        /**
118         * Name of the configuration file. Default is "config"
119         */
120        protected String configFileName = "config";
121
122        /**
123         * Has the configuration file been read yet?.
124         */
125        protected boolean configFileRead = false;
126
127        /**
128         * Set of parameters. This is a hash table and not a hashmap since several
129         * thread may access this class at once.
130         */
131        protected Hashtable<String, String> parameters = new Hashtable<String, String>();
132
133        /**
134         * When locked the environment parameters value still can be changed but it
135         * is no more possible to add new parameters.
136         */
137        protected boolean locked;
138
139        // --------- Static attributes ---------
140
141        /**
142         * Global environment for the whole JVM. This global environment is
143         * available <b>and editable</b> from everywhere. It is create as soon as
144         * the {@link #getGlobalEnvironment()} static method is called if this field
145         * was not yet initialized by any other mean.
146         * @see #getGlobalEnvironment()
147         */
148        public static Environment GLOBAL_ENV;
149
150        // --------- Static methods -----------
151
152        /**
153         * Access to the global shared environment for the whole JVM. This method
154         * allows to access a shared environment, that can be read and written from
155         * anywhere.
156         * @return A singleton instance of the global environment.
157         */
158        public static Environment getGlobalEnvironment()
159        {
160                if( GLOBAL_ENV == null )
161                        GLOBAL_ENV = new Environment();
162
163                return GLOBAL_ENV;
164        }
165
166        // --------- Methods -------------
167
168        /**
169         * Is the environment locked?.
170         * @return True if the environment is locked.
171         * @see #lockEnvironment(boolean)
172         */
173        public boolean isLocked()
174        {
175                return locked;
176        }
177
178        /**
179         * Access to a parameter in the environment.
180         * @param parameter The parameter name.
181         * @return The parameter value (empty string if not set).
182         */
183        public String getParameter( String parameter )
184        {
185                String p = parameters.get( parameter );
186
187                return ( p == null ) ? "" : p;
188        }
189        
190        /**
191         * True if the given paramter exist.
192         * @param parameter The parameter name.
193         * @return True if the given paramter name points to a value.
194         */
195        public boolean hasParameter( String parameter )
196        {
197                return( parameters.get( parameter ) != null );
198        }
199        
200        /**
201         * Check a parameter expected to be of boolean type. This method returns
202         * "true" if the parameter exists and has a value that is "1", "true",
203         * "on" or "yes" (with any possible combination of upper or lower-case
204         * letters). For any other values of the parameter or if the parameter does
205         * not exist in the environment, "false" is returned.
206         * @param parameter The parameter name.
207         * @return True if the parameter value means "true", false for any other
208         *         value or if the parameter does not exist.
209         * @see #getBooleanParameteri(String)
210         */
211        public boolean getBooleanParameter( String parameter )
212        {
213                int val = getBooleanParameteri( parameter );
214                
215                return( val == 1 );
216        }
217        
218        /**
219         * Check a parameter expected to be of boolean type. This method returns the
220         * value 1 if the parameter has value "1", "true", "on", "yes" (the case
221         * does not matter). Else it returns 0. To account the case of non-existing
222         * parameters, this method returns -1 if the given parameter does not
223         * exist.
224         * @param parameter The parameter name.
225         * @return 1 if the parameter value means "true", 0 if it has any other
226         *         value, or -1 if it does not exist.
227         * @see #getBooleanParameter(String)
228         */
229        public int getBooleanParameteri( String parameter )
230        {
231                String p = parameters.get( parameter );
232                
233                if( p != null )
234                {
235                        p = p.toLowerCase();
236                        
237                        if( p.equals( "1" ) )    return 1;
238                        if( p.equals( "true" ) ) return 1;
239                        if( p.equals( "on" ) )   return 1;
240                        if( p.equals( "yes" ) )  return 1;
241                        
242                        return 0;
243                }
244                
245                return -1;
246        }
247        
248        /**
249         * Get the value of a parameter that is expected to be a number. If the
250         * parameter does not exist or is not a number, 0 is returned.
251         * @param parameter The parameter name.
252         * @return The numeric value of the parameter. 0 if the parameter does
253         *         not exist or is not a number.
254         */
255        public double getNumberParameter( String parameter )
256        {
257                String p = parameters.get( parameter );
258                
259                if( p != null )
260                {
261                        try
262                        {
263                                return Double.parseDouble( p );
264                        }
265                        catch( NumberFormatException e )
266                        {
267                                return 0;
268                        }
269                }
270                
271                return 0;
272        }
273
274        /**
275         * Returns the number of parameters found in the configuration file.
276         * @return The number of parameters found in the configuration file.
277         */
278        public int getParameterCount()
279        {
280                return parameters.size();
281        }
282
283        /**
284         * Set of all parameter names.
285         * @return A set of all the names identifying parameters in this
286         *         environment.
287         */
288        public Set<String> getParametersKeySet()
289        {
290                return parameters.keySet();
291        }
292
293        /**
294         * Generate a new Environment object with a deep copy of the elements this
295         * object.
296         * @return An Environment object identical to this one
297         */
298        @Override
299        public Environment clone()
300        {
301                Environment e = new Environment();
302                e.configFileName = configFileName;
303                e.configFileRead = configFileRead;
304                e.locked = locked;
305                for( String key: parameters.keySet() )
306                {
307                        e.parameters.put( key, parameters.get( key ) );
308                }
309                return e;
310        }
311
312        /**
313         * Set the value of a parameter. If the parameter already exists its old
314         * value is overwritten. This works only if the environment is not locked.
315         * @param parameter The parameter name.
316         * @param value The new parameter value.
317         * @see #isLocked()
318         * @see #lockEnvironment(boolean)
319         */
320        public void setParameter( String parameter, String value )
321        {
322                if( !locked )
323                {
324                        parameters.put( parameter, value );
325                }
326                else
327                {
328                        if( parameters.get( parameter ) != null )
329                                parameters.put( parameter, value );
330                }
331        }
332
333        /**
334         * Disallow the addition of new parameters. The already declared parameters
335         * are still modifiable, but no new parameter can be added.
336         * @param on If true the environment is locked.
337         */
338        public void lockEnvironment( boolean on )
339        {
340                locked = on;
341        }
342
343        /**
344         * Initialize all the fields of the given object whose name correspond to
345         * parameters of this environment. This works only if the object to
346         * initialize provides methods that begins by "set". For example if the
347         * object provides a method named "setThing(int value)", and if there is a
348         * parameter named "thing" in this environment and its value is convertible
349         * to an integer, then the method "setThing()" will be invoked on the object
350         * with the correct value.
351         * @see #initializeFieldsOf(Object, String[])
352         * @see #initializeFieldsOf(Object, Collection)
353         * @param object The object to initialize.
354         */
355        public void initializeFieldsOf( Object object )
356        {
357                Method[] methods = object.getClass().getMethods();
358
359                for( Method method: methods )
360                {
361                        if( method.getName().startsWith( "set" ) )
362                        {
363                                Class<?> types[] = method.getParameterTypes();
364
365                                if( types.length == 1 )
366                                {
367                                        String name = method.getName().substring( 3, 4 )
368                                                        .toLowerCase()
369                                                        + method.getName().substring( 4 );
370                                        String value = parameters.get( name );
371
372                                        if( value != null )
373                                        {
374                                                invokeSetMethod( object, method, types, name, value );
375                                        }
376                                }
377                        }
378                }
379        }
380
381        /**
382         * Initialize all the fields of the given object that both appear in the
383         * given field list and whose name correspond to parameters of this
384         * environment. See the {@link #initializeFieldsOf(Object)} method
385         * description.
386         * @see #initializeFieldsOf(Object)
387         * @see #initializeFieldsOf(Object, Collection)
388         * @param object The object to initialize.
389         * @param fieldList The name of the fields to initialize in the object.
390         */
391        public void initializeFieldsOf( Object object, String... fieldList )
392        {
393                Method[] methods = object.getClass().getMethods();
394                HashSet<String> names = new HashSet<String>();
395
396                for( String s: fieldList )
397                        names.add( s );
398
399                for( Method method: methods )
400                {
401                        if( method.getName().startsWith( "set" ) )
402                        {
403                                Class<?> types[] = method.getParameterTypes();
404
405                                if( types.length == 1 )
406                                {
407                                        String name = method.getName().substring( 3, 4 )
408                                                        .toLowerCase()
409                                                        + method.getName().substring( 4 );
410
411                                        if( names.contains( name ) )
412                                        {
413                                                String value = parameters.get( name );
414
415                                                if( value != null )
416                                                {
417                                                        invokeSetMethod( object, method, types, name, value );
418                                                }
419                                        }
420                                }
421                        }
422                }
423        }
424
425        /**
426         * Initialize all the fields of the given object that both appear in the
427         * given field list and whose name correspond to parameters of this
428         * environment. See the {@link #initializeFieldsOf(Object)} method
429         * description.
430         * @see #initializeFieldsOf(Object)
431         * @see #initializeFieldsOf(Object, String[])
432         * @param object The object to initialize.
433         * @param fieldList The name of the fields to initialize in the object.
434         */
435        protected void initializeFieldsOf( Object object,
436                        Collection<String> fieldList )
437        {
438                Method[] methods = object.getClass().getMethods();
439
440                for( Method method: methods )
441                {
442                        if( method.getName().startsWith( "set" ) )
443                        {
444                                Class<?> types[] = method.getParameterTypes();
445
446                                if( types.length == 1 )
447                                {
448                                        String name = method.getName().substring( 3 ).toLowerCase();
449
450                                        if( fieldList.contains( name ) )
451                                        {
452                                                String value = parameters.get( name );
453
454                                                if( value != null )
455                                                {
456                                                        invokeSetMethod( object, method, types, name, value );
457                                                }
458                                        }
459                                }
460                        }
461                }
462        }
463
464        protected void invokeSetMethod( Object object, Method method,
465                        Class<?> types[], String name, String value )
466        {
467                try
468                {
469                        // XXX a way to avoid this overlong and repetitive
470                        // list of setters ?
471
472                        if( types[0] == Long.TYPE )
473                        {
474                                try
475                                {
476                                        long val = Long.parseLong( value );
477                                        method.invoke( object, new Long( val ) );
478                                }
479                                catch( NumberFormatException e )
480                                {
481                                        Logger
482                                                        .getGlobalLogger()
483                                                        .log(
484                                                                        Logger.LogLevel.WARN,
485                                                                        this.getClass().getName(),
486                                                                        "cannot set '%s' to the value '%s', values is not a long%n",
487                                                                        method.toString(), value );
488                                }
489                        }
490                        else if( types[0] == Integer.TYPE )
491                        {
492                                try
493                                {
494                                        int val = (int) Double.parseDouble( value );
495                                        method.invoke( object, new Integer( val ) );
496                                }
497                                catch( NumberFormatException e )
498                                {
499                                        Logger
500                                                        .getGlobalLogger()
501                                                        .log(
502                                                                        Logger.LogLevel.WARN,
503                                                                        this.getClass().getName(),
504                                                                        "cannot set '%s' to the value '%s', values is not a int%n",
505                                                                        method.toString(), value );
506                                }
507                        }
508                        else if( types[0] == Double.TYPE )
509                        {
510                                try
511                                {
512                                        double val = Double.parseDouble( value );
513                                        method.invoke( object, new Double( val ) );
514                                }
515                                catch( NumberFormatException e )
516                                {
517                                        Logger
518                                                        .getGlobalLogger()
519                                                        .log(
520                                                                        Logger.LogLevel.WARN,
521                                                                        this.getClass().getName(),
522                                                                        "cannot set '%s' to the value '%s', values is not a double%n",
523                                                                        method.toString(), value );
524                                }
525                        }
526                        else if( types[0] == Float.TYPE )
527                        {
528                                try
529                                {
530                                        float val = Float.parseFloat( value );
531                                        method.invoke( object, new Float( val ) );
532                                }
533                                catch( NumberFormatException e )
534                                {
535                                        Logger
536                                                        .getGlobalLogger()
537                                                        .log(
538                                                                        Logger.LogLevel.WARN,
539                                                                        this.getClass().getName(),
540                                                                        "cannot set '%s' to the value '%s', values is not a float%n",
541                                                                        method.toString(), value );
542                                }
543                        }
544                        else if( types[0] == Boolean.TYPE )
545                        {
546                                try
547                                {
548                                        boolean val = false;
549                                        value = value.toLowerCase();
550
551                                        if( value.equals( "1" ) || value.equals( "true" )
552                                                        || value.equals( "yes" ) || value.equals( "on" ) )
553                                                val = true;
554
555                                        method.invoke( object, new Boolean( val ) );
556                                }
557                                catch( NumberFormatException e )
558                                {
559                                        Logger
560                                                        .getGlobalLogger()
561                                                        .log(
562                                                                        Logger.LogLevel.WARN,
563                                                                        this.getClass().getName(),
564                                                                        "cannot set '%s' to the value '%s', values is not a boolean%n",
565                                                                        method.toString(), value );
566                                }
567                        }
568                        else if( types[0] == String.class )
569                        {
570                                method.invoke( object, value );
571                        }
572                        else
573                        {
574                                Logger.getGlobalLogger().log( Logger.LogLevel.WARN,
575                                                this.getClass().getName(),
576                                                "cannot match parameter '%s' and the method '%s'%n",
577                                                value, method.toString() );
578                        }
579                }
580                catch( InvocationTargetException ite )
581                {
582                        Logger
583                                        .getGlobalLogger()
584                                        .log(
585                                                        Logger.LogLevel.WARN,
586                                                        this.getClass().getName(),
587                                                        "cannot invoke method '%s' : invocation targer error : %s%n",
588                                                        method.toString(), ite.getMessage() );
589                }
590                catch( IllegalAccessException iae )
591                {
592                        Logger.getGlobalLogger().log( Logger.LogLevel.WARN,
593                                        this.getClass().getName(),
594                                        "cannot invoke method '%s' : illegal access error : %s%n",
595                                        method.toString(), iae.getMessage() );
596                }
597        }
598
599        /**
600         * Print all parameters to the given stream.
601         * @param out The output stream to use.
602         */
603        public void printParameters( PrintStream out )
604        {
605                out.println( toString() );
606        }
607
608        /**
609         * Print all parameters the stdout.
610         */
611        public void printParameters()
612        {
613                printParameters( System.out );
614        }
615
616        @Override
617        public String toString()
618        {
619                return parameters.toString();
620        }
621
622        /**
623         * Read the parameters from the given command line array. See the more
624         * complete {@link #readCommandLine(String[], Collection)} method.
625         * @param args The command line.
626         */
627        public void readCommandLine( String[] args )
628        {
629                readCommandLine( args, null );
630        }
631
632        /**
633         * Read the parameters from the given command line array. The expected
634         * format of this array is the following:
635         * <ul>
636         * <li>a word beginning by a "-" is the parameter name (for example
637         * "-param");</li>
638         * <li>if this word is immediately followed by a "=" and another word, this
639         * word is considered as its string value (for example "-param=aValue");</li>
640         * <li>If the parameter name is not followed by "=", it is considered a
641         * boolean option and its value is set to the string "true" (to set this to
642         * false simply give the string "-param=false");</li>
643         * <li>If a word is found on the command line without any preceding "-" but
644         * is followed by a "=" and by another word, then it is considered as a
645         * key,value brace</li>
646         * <li>If a word is found on the command line without any preceding "-" and
647         * is not followed by any "=", the it is considered to be a filename for a
648         * configuration file. The method will try to open this file for reading. A
649         * configuration file is composed of lines. Each line is composed of a brace
650         * key/value separated by a "=". If a line starts with a "#", then it is
651         * considered as a comment. Finally if no format is recognized the line is
652         * inserted to the <code>trashcan</code>.</li>
653         * </ul>
654         * @param args The command line.
655         * @param trashcan Will be filled by the set of unparsed strings (can be
656         *        null if these strings can be ignored).
657         */
658        public void readCommandLine( String[] args, Collection<String> trashcan )
659        {
660                for( String arg: args )
661                {
662                        boolean startsWithMinus = arg.startsWith( "-" );
663                        int equalPos = arg.indexOf( '=' );
664                        String value = "true";
665                        if( equalPos >= 0 )
666                        {
667                                value = arg.substring( equalPos + 1 );
668                                if( startsWithMinus )
669                                {
670                                        arg = arg.substring( 1, equalPos );
671                                }
672                                else
673                                {
674                                        arg = arg.substring( 0, equalPos );
675                                }
676                                parameters.put( arg, value );
677                        }
678                        else
679                        {
680                                if( startsWithMinus )
681                                {
682                                        arg = arg.substring( 1 );
683                                        parameters.put( arg, value );
684                                }
685                                else
686                                {
687                                        readConfigFile( arg, trashcan );
688                                }
689                        }
690                }
691        }
692
693        /**
694         * Internal method that reads a configuration file.
695         */
696        protected void readConfigFile( String filename, Collection<String> trashcan )
697        {
698                BufferedReader br;
699                int count = 0;
700                try
701                {
702                        br = new BufferedReader( new FileReader( filename ) );
703                        String str;
704                        while( ( str = br.readLine() ) != null )
705                        {
706                                count++;
707                                if( str.length() > 0 && !str.substring( 0, 1 ).equals( "#" ) )
708                                {
709                                        String[] val = str.split( "=" );
710                                        if( val.length != 2 )
711                                        {
712                                                if( val.length == 1 )
713                                                {
714                                                        parameters.put( val[0].trim(), "true" );
715                                                }
716                                                else
717                                                {
718                                                        System.err
719                                                                        .printf(
720                                                                                        "Something is wrong with the configuration file \"%s\"near line %d :\n %s",
721                                                                                        filename, count, str );
722                                                        if( trashcan != null )
723                                                        {
724                                                                trashcan.add( str );
725                                                        }
726                                                }
727                                        }
728                                        else
729                                        {
730                                                String s0 = val[0].trim();
731                                                String s1 = val[1].trim();
732                                                parameters.put( s0, s1 );
733                                        }
734                                }
735                        }
736
737                }
738                catch( FileNotFoundException fnfe )
739                {
740                        System.err.printf(
741                                        "Tried to open \"%s\" as a config file: file not found.%n",
742                                        filename );
743                        if( trashcan != null )
744                        {
745                                trashcan.add( filename );
746                        }
747                }
748                catch( IOException ioe )
749                {
750                        ioe.printStackTrace();
751                        System.exit( 0 );
752                }
753        }
754
755        /**
756         * Save the curent parameters to a file.
757         * @param fileName Name of the file to save the config in.
758         * @throws IOException For any output error on the given file name.
759         */
760        public void writeParameterFile( String fileName ) throws IOException
761        {
762                BufferedWriter bw = new BufferedWriter( new FileWriter( fileName ) );
763                Set<String> ks = parameters.keySet();
764
765                for( String key: ks )
766                {
767                        bw.write( key + " = " + parameters.get( key ) );
768                        bw.newLine();
769                        // System.out.println( key + " = " + parameters.get( key ) );
770                }
771
772                bw.close();
773        }
774
775        /**
776         * Read the default configuration file. Once this file has been correctly
777         * parsed, the {@link #configFileRead} boolean is set to true.
778         * @see #configFileName
779         */
780        protected void readConfigurationFile()
781        {
782                try
783                {
784                        readParameterFile( configFileName );
785                        configFileRead = true;
786                }
787                catch( IOException ioe )
788                {
789                        System.err.printf( "%-5s : %s : %s\n", "Warning", "Environment",
790                                        "Something wrong while reading the configuration file" );
791                }
792        }
793
794        /**
795         * Read a parameter file. The format of this file is as follows:
796         * <ul>
797         * <li>Each line contains a parameter setting or a comment;</li>
798         * <li>Lines beginning by a "#" are considered comments (be careful, a "#"
799         * in the middle of a line <b>is not</b> a comment);</li>
800         * <li>parameters settings are of the form "name=value", spaces are
801         * allowed, but space before and after the parameter name of value will be
802         * stripped.</li>
803         * </ul>
804         * @param fileName Name of the parameter file to read.
805         * @throws IOException For any error with the given parameter file name.
806         */
807        public void readParameterFile( String fileName ) throws IOException
808        {
809                BufferedReader br;
810                int count = 0;
811
812                br = new BufferedReader( new FileReader( fileName ) );
813
814                String str;
815
816                while( ( str = br.readLine() ) != null )
817                {
818                        count++;
819
820                        if( str.length() > 0 && !str.startsWith( "#" ) )
821                        {
822                                String[] val = str.split( "=" );
823
824                                if( val.length != 2 )
825                                {
826                                        System.err.printf( "%-5s : %s : %s\n", "Warn",
827                                                        "Environment",
828                                                        "Something is wrong in your configuration file near line "
829                                                                        + count + " : \n" + Arrays.toString( val ) );
830                                }
831                                else
832                                {
833                                        String s0 = val[0].trim();
834                                        String s1 = val[1].trim();
835
836                                        setParameter( s0, s1 );
837                                }
838                        }
839                }
840                
841                br.close();
842        }
843}