// Copyright (c) Keith D Gregory, all rights reserved
package com.kdgregory.example.xml.parsing;

import java.io.IOException;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;

import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;


public class DTDValidatedParsingWithErrorHandlerAndEntityResolver
{
    public static void main(String[] argv) throws Exception
    {
        // these resources are opened here to separate the mechanics of finding them from the process of using them
        // note that the parser is responsible for closing both streams
        InputStream xml = Thread.currentThread().getContextClassLoader().getResourceAsStream("albumsWithExternalDoctype.xml");
        final InputStream dtd = Thread.currentThread().getContextClassLoader().getResourceAsStream("albums.dtd");

        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        dbf.setValidating(true);

        DocumentBuilder db = dbf.newDocumentBuilder();
        db.setErrorHandler(new ErrorHandler()
        {
            @Override
            public void fatalError(SAXParseException exception) throws SAXException
            {
                System.err.println("fatalError: " + exception);
            }

            @Override
            public void error(SAXParseException exception) throws SAXException
            {
                System.err.println("error: " + exception);
            }

            @Override
            public void warning(SAXParseException exception) throws SAXException
            {
                System.err.println("warning: " + exception);
            }
        });
        db.setEntityResolver(new EntityResolver()
        {
            @Override
            public InputSource resolveEntity(String publicId, String systemId)
            throws SAXException, IOException
            {
                if (systemId.equals("urn:x-com.kdgregory.example.xml.parsing"))
                {
                    // normally you open the DTD file/resource here
                    return new InputSource(dtd);
                }
                else 
                {
                    throw new SAXException("unable to resolve entity; "
                                + "public = \"" + publicId + "\", "
                                + "system = \"" + systemId + "\"");
                }
            }
        });

        Document dom = db.parse(new InputSource(xml));

        System.out.println("root element name = " + dom.getDocumentElement().getNodeName());
    }
}
