/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 1999 Bull S.A.
 * Contact: jonas-team@ow2.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
 *
 * Initial developer: Florent BENOIT
 * --------------------------------------------------------------------------
 * $Id: JEntityResolver.java 15428 2008-10-07 11:20:29Z sauthieg $
 * --------------------------------------------------------------------------
 */

package org.ow2.jonas.deployment.common.lib;


import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.ow2.jonas.deployment.api.DTDs;
import org.ow2.jonas.deployment.api.Schemas;
import org.ow2.jonas.deployment.common.digester.JDigester;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;


/**
 * This class defines the entity resolver used to resolve DTDs/Schemas during
 * the xml parsing
 * @author Florent Benoit
 */
public class JEntityResolver implements EntityResolver {

    /**
     * Map which contains DTDs and Schemas available in local
     */
    private HashMap entries = new HashMap();

    /**
     * Constructor without JDigester instance (used in WsGen only)
     */
    public JEntityResolver() {
        super();
    }

    /**
     * Add a local schema to the known entries
     * @param path path to a local schema
     */
    private void addSchema(String path) {
        String id = path.substring(path.lastIndexOf('/') + 1);
        entries.put(id, path);
    }



    /**
     * The Parser will call this method before opening any external entity except
     * the top-level document entity.
     * @param publicId The public identifier of the external entity being referenced,
     *                 or null if none was supplied.
     * @param systemId The system identifier of the external entity being referenced.
     * @return An InputSource object describing the new input source, or null to request that
     *         the parser open a regular URI connection to the system identifier.
     * @throws SAXException Any SAX exception, possibly wrapping another exception.
     * @throws IOException A Java-specific IO exception, possibly the result of creating
     *                     a new InputStream or Reader for the InputSource.
     */
    public InputSource resolveEntity(String publicId, String systemId)
        throws IOException, SAXException {

        // DTD : check if we got this entry
        String localPath = null;
        if (publicId != null) {
            localPath = (String) entries.get(publicId);
        } else if (systemId != null) {
            // Can be a schema
            if (systemId.toLowerCase().endsWith(".xsd")) {
                // Retrieve basename
                String baseName = systemId.substring(systemId.lastIndexOf('/') + 1);

                // Registred ?
                localPath = (String) entries.get(baseName);
            }
        }

        if (localPath == null) {
            // This DTD/Schema was not added to this DTD/Schame local repository
            return null;
        }

        // Return the local path source
        return (new InputSource(localPath));
    }


    /**
     * Add the mapping between a public Id and the local path of the DTD
     * @param dtds Object containing the mapping PublicId --> Local URL
     */
    public void addDtds(DTDs dtds) {
        if (dtds != null) {
            Map dtdsMapping = dtds.getMapping();
            if (dtdsMapping != null) {
                for (Iterator it = dtdsMapping.entrySet().iterator(); it.hasNext();) {
                    Map.Entry entry = (Map.Entry) it.next();
                    String publicId = (String) entry.getKey();
                    String localURL = (String) entry.getValue();
                    entries.put(publicId, localURL);
                }
            }
        }
    }


    /**
     * Add the given Schemas to the schemas available for this resolver
     * @param schemas Definition of the schemas to add to this resolver
     */
    public void addSchemas(Schemas schemas) {
        // no schemas
        if (schemas == null) {
            return;
        }

        List localSchemas = schemas.getlocalSchemas();

        // there are schemas
        if (localSchemas != null) {
            for (Iterator it = localSchemas.iterator(); it.hasNext();) {
               String schema = (String) it.next();
               addSchema(schema);
            }
        }
    }



}

