/*
 * Created on Sep 17, 2004
 *
 * To change the template for this generated file go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
package org.biomoby.registry.rdfagent.util;

/**
 * @author onv
 *
 * To change the template for this generated type comment go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
import java.io.*;
import java.util.*;

/** a class to handle configs for different things.
 *  reads file on the format <pre>
 *  [sectionName1]
 *  key=value
 *  key2=value2
 *  [sectionName2]
 *  key=value
 *  key2=value2 
 *  key_with_equals\=still_key=value3
 *  </pre>
 *  everything after the first '#' is considered a comment.
 *  blank lines are ignored. If you want keys with '=' in them 
 *  escape it to '\=' and you should be fine.
 */
@SuppressWarnings("unchecked")
public class Config {
	
	private Hashtable configs;

  /** Create a Config for the specified file
	 * @param filename the File we read the config from
	 */
	public Config(String filename) throws IOException {
	BufferedReader br = new BufferedReader (new FileReader (filename));
	readConfig (br);
	}

	/** read in a Config from a reader.
		* @param br the reader that has the Config.
		*/
	private void readConfig(BufferedReader br) throws IOException {
        String line;
        configs = new Hashtable();
        Properties current = new Properties();   // the main thing.
        configs.put("", current);
        while ((line = br.readLine()) != null) {
            int index = line.indexOf('#');
            if (index >= 0)
                line = line.substring(0, index);
            if (line.equals(""))
                continue;
            if (line.startsWith("[")) {
                int endindex = line.indexOf(']');
                if (endindex >= 0) {
                    String newSection = line.substring(1, endindex);
                    // collapse configs named equal.
                    if (configs.get(newSection) != null)
                        current = (Properties) configs.get(newSection);
                    else
                        current = new Properties();
                    configs.put(newSection, current);
                }
            } else {
                boolean escaped = false;
                int start = 0;
                int eqindex;
                do {
                    escaped = false;
                    eqindex = line.indexOf('=', start);
                    if (eqindex > 0) {
                        if (line.charAt(eqindex - 1) == '\\') {
                            escaped = true;
                            start = eqindex;
                            line = line.substring(0, eqindex - 1) + line.substring(eqindex);
                        }
                    }
                } while (escaped);
                String key = "" , value = "";
                if (eqindex >= 0) {
                    key = line.substring(0, eqindex);
                    value = line.substring(eqindex + 1);
                } else
                    key = line;
                current.put(key, value);
            }
        }
        br.close();
    }



   /** get the available sections
	 * @return an Enumeration of the available sections (including the empty section).
	 */
	public Enumeration getSections () {
	return configs.keys ();
	}

	/** get the properties for a given section
		* @param sectionName the section we want properties for.
		* @return a Properties if section exist or null.
		*/
	 public Properties getProperties (String sectionName) {
     return (Properties)configs.get (sectionName);
	 }


/** get a property for given key in specified section
	 * @param section the section we should look in.
	 * @param key the key we want a value for.
	 * @param defaultstring the string to use if no value is found.
	 * @return a string if section + key is set, null otherwise
	 */
	public String getProperty (String section, String key, String defaultstring) {
	Properties p = getProperties (section);
	if (p != null) 
		return p.getProperty (key, defaultstring);
	return defaultstring;
	}
}
