package org.esupportail.portal.channels.CAnnuaire;
/** 
 * <p>Titre : CAnnuaire Config</p>
 * <p>Description : </p>
 * <p>Copyright : Copyright (c) 2003</p>
 * <p>Société : </p>
 * @author sgaudin
 * @version 1.0
 */

import java.io.IOException;
import java.net.URL;
import java.util.Hashtable;
import java.util.Vector;

import org.apache.commons.digester.Digester;
import org.jasig.portal.services.LogService;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;


public class config {

	/*tableau des serveurs LDAP trouvés en config*/
	private Hashtable tabServer;
	private Vector ordreServer;
	private Hashtable tabTable;
	//private String defaultServeurKey = null;

	private static config singleton = null;

	/**
	 * @param ConfigFileName
	 */
	private config(String ConfigFileName) {
		tabServer = new Hashtable();
		tabTable = new Hashtable();
		ordreServer = new Vector();

		Digester digester = new Digester();
		digester.setValidating(true);
		digester.push(this);

		/*MONTAGE DES TABLES*/
		digester.addObjectCreate("directories/tables/table", Table.class);
		digester.addSetProperties("directories/tables/table");
		digester.addCallMethod("directories/tables/table/item", "addItem", 3);
		digester.addCallParam("directories/tables/table/item", 0, "code");
		digester.addCallParam("directories/tables/table/item", 1, "value");
		digester.addCallParam("directories/tables/table/item", 2, "fieldOrder");
		digester.addSetNext("directories/tables/table", "addTable");

		/*MONTAGE DES SERVEUR*/
		// pour chaque directories/directory on cree un objet directory sur lequel on va travailler tant que
		// la méthode addSetNext n'est pas appelle sur directories/directory
		digester.addObjectCreate("directories/directory", Server.class);
		//ajout des propriétés du directory
		digester.addSetProperties("directories/directory");
		digester.addSetProperties("directories/directory/server");

		// pour chaque directories/directory/request on cree un objet Query
		digester.addObjectCreate("directories/directory/request", Query.class);
		//ajout des propriétés du request
		digester.addSetProperties("directories/directory/request");
		digester.addCallMethod("directories/directory/request", "setScope", 1);
		digester.addCallParam("directories/directory/request", 0, "scope");

		// pour chaque directories/directory/request/elemOfRequest on cree un objet ElmOfQuery
		digester.addObjectCreate(
			"directories/directory/request/elemOfRequest",
			ElmOfQuery.class);
		//ajout des propriétés de l'elmofquery
		digester.addSetProperties(
			"directories/directory/request/elemOfRequest");

		// une fois l'objet request créee on appel Query.addElement qui ajoute un élement de requete
		digester.addSetNext(
			"directories/directory/request/elemOfRequest",
			"addElement");

		// une fois l'objet request créee on appel Server.setQuery qui met à jour son objet Query
		digester.addSetNext("directories/directory/request", "setQuery");

		// pour chaque directories/directory/card on cree un objet Display
		digester.addObjectCreate("directories/directory/card", Display.class);
		//ajout des propriétés du display
		digester.addSetProperties("directories/directory/card");

		// pour chaque directories/directory/request on cree un objet Line
		digester.addObjectCreate("directories/directory/card/line", Line.class);
		//ajout des propriétés de la line
		digester.addSetProperties("directories/directory/card/line");

		digester.addCallMethod(
			"directories/directory/card/line",
			"setLinktable",
			1);
		digester.addCallParam("directories/directory/card/line", 0, "table");

		// une fois l'objet request créee on appel Display.addLine qui ajoute une ligne d'afcichage au display
		digester.addSetNext("directories/directory/card/line", "addLine");

		// une fois l'objet request créee on appel Server.setDisplay qui met à jour objet Display
		digester.addSetNext("directories/directory/card", "setDisplay");

		// une fois l'objet directory cree on appel this.addDirectory qui stocke l'annuaire dans un tableau
		digester.addSetNext("directories/directory", "addServer");
		URL url = config.class.getResource(ConfigFileName);

		if (url != null) {

			InputSource inSource = new InputSource(url.toExternalForm());

			try {
				//parcours du fichier de config
				digester.parse(inSource);
			} catch (IOException e) {
				LogService.log(
					LogService.ERROR,
					"config::config() : ERREUR : Impossible d'ouvrir le fichier de config :"
						+ ConfigFileName
						+ "\n"
						+ e.toString());
			} catch (SAXException e) {
				LogService.log(
					LogService.ERROR,
					"config::config() : ERREUR : SAXException :\n"
						+ e.toString());
			} catch (Exception e) {
				LogService.log(
					LogService.ERROR,
					"config::config() : ERREUR : de lecture du fichier de config\n"
						+ e.toString());
			}
		} else { 
			LogService.log(
				LogService.ERROR,
				"config::config() : ERREUR : "
					+ ConfigFileName
					+ " n'existe pas.\n");
		}

	}

	public void addServer(Server s) {
		tabServer.put(s.getName(), s);
		ordreServer.add(s.getName()); 
	}

	public void addTable(Table t) {
		t.loadItems();
		tabTable.put(t.getName(), t);
	}

	public String getDefaultServeurKey() {
		return (String)ordreServer.get(0);
	}

	public Vector getAllServers() {
		return (ordreServer);
	}

	public Server getServer(String key) {
		if (key != null)
			return ((Server) tabServer.get(key));
		else
			return (null);
	}

	public Hashtable getAllTables() {
		return (tabTable);
	}

	public Table getTable(String key) {
		if (key==null)return null;
		else return ((Table) tabTable.get(key));
	}

	public static config getInstance(String configFilePath) {
		if (singleton == null) {

			singleton = new config(configFilePath);

		}
		return singleton;

	}
}
