/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 1999 Bull S.A.
 * Contact: jonas-team@objectweb.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */
package org.objectweb.jonas.security.lib;

import java.io.File;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.URL;

import org.apache.commons.digester.Digester;

import org.objectweb.jonas.common.JProp;
import org.objectweb.jonas.common.Log;
import org.objectweb.jonas.security.JResources;
import org.objectweb.jonas.security.SecurityServiceException;
import org.objectweb.jonas.security.rules.JDSRuleSet;
import org.objectweb.jonas.security.rules.JLDAPRuleSet;
import org.objectweb.jonas.security.rules.JMemoryRuleSet;

import org.objectweb.util.monolog.api.BasicLevel;
import org.objectweb.util.monolog.api.Logger;


/**
 *
 *
 * @author Guillaume Sauthier
 */
public class JResourceManager {

    /**
     * Logger which is used
     */
    private static Logger logger = Log.getLogger(Log.JONAS_SECURITY_PREFIX);

    /**
     * JONAS_ROOT/xml
     */
    private String xmlDir = null;

    /**
     * DTD of the realm configuration file
     */
    protected static final String CONFIG_FILE_DTD = "jonas-realm_1_0.dtd";

    /**
     * JONAS_ROOT
     */
    private static final String JONAS_ROOT = JProp.getInstallRoot();

    /**
     * Unique JresourceManager instance
     */
    private static JResourceManager instance = null;


    /**
     * Private Constructor for Singleton
     */
    private JResourceManager() {
        xmlDir = JONAS_ROOT + File.separator + "xml" +  File.separator;
    }

    /**
     * @return returns the unique JResourceManager instance
     */
    public static JResourceManager getInstance() {
        if (instance == null) {
            instance = new JResourceManager();
        }
        return instance;
    }

    /**
     * Create and configure the Digester that will be used for the xml
     * parsing of the JOnAS realm file.
     * @return Digester the digester containing the rules for the xml parsing
     * of the JOnAS realm file (jonas-realm.xml)
     */
    protected Digester createRealmDigester() {

        // Initialize the digester
        Digester digester = new Digester();
        File realmDtd = new File(xmlDir + CONFIG_FILE_DTD);
        URL realmDtdURL = null;
        boolean validating = true;
        try {
            realmDtdURL = realmDtd.toURL();
            digester.register("-//ObjectWeb//DTD JOnAS realm 1.0//EN", realmDtdURL.toExternalForm());
        } catch (MalformedURLException e) {
            // Can't locate URL for DTD, no validation
            logger.log(BasicLevel.INFO, "Can not locate URL for DTD validation, no validation will be done." + e.getMessage());
            validating = false;
        }

        digester.setValidating(validating);
        digester.setErrorHandler(new JErrorHandler());
        digester.addRuleSet(new JMemoryRuleSet("jonas-realm/jonas-memoryrealm/"));
        digester.addRuleSet(new JDSRuleSet("jonas-realm/jonas-dsrealm/"));
        digester.addRuleSet(new JLDAPRuleSet("jonas-realm/jonas-ldaprealm/"));

        return (digester);
    }

    /**
     * Add JResource(s) created from parsing of the reader contents inside the JResources given instance.
     *
     * @param res JResources element where JResource will be addded.
     * @param reader XML Content Reader
     * @param xml filename / xml : used in Error messages
     *
     * @throws SecurityServiceException When parsing fails
     */
    public void addResources(JResources res, Reader reader, String xml) throws SecurityServiceException {
        // Create the digester for the parsing of the jonas-realm.xml file.
        Digester realmDigester = createRealmDigester();

        try {
            realmDigester.push(res);
            realmDigester.parse(reader);
            reader.close();
        } catch (org.xml.sax.SAXException saxe) {
            logger.log(BasicLevel.ERROR, "Error when parsing the XML of the file " + xml);
            throw new SecurityServiceException(saxe.getMessage(), saxe);
        } catch (Exception e) {
            logger.log(BasicLevel.ERROR, "Error when reading config file from the xml file " + xml);
            throw new SecurityServiceException("Error when reading config file from the xml file " + xml + " : " + e.getMessage(), e);
        }

    }


}
