/* XCat.java --
   Copyright (C) 2001 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath 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
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.xml.util;

import gnu.java.lang.CPStringBuilder;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.StringTokenizer;
import java.util.Stack;
import java.util.Vector;

import org.xml.sax.Attributes;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;

import org.xml.sax.ext.DefaultHandler2;
import org.xml.sax.ext.EntityResolver2;

import org.xml.sax.helpers.XMLReaderFactory;

/**
 * Packages <a href=
    "http://www.oasis-open.org/committees/entity/spec-2001-08-06.html"
    >OASIS XML Catalogs</a>,
 * primarily for entity resolution by parsers.
 * That specification defines an XML syntax for mappings between
 * identifiers declared in DTDs (particularly PUBLIC identifiers) and
 * locations.  SAX has always supported such mappings, but conventions for
 * an XML file syntax to maintain them have previously been lacking.
 *
 * <p> This has three main operational modes.  The primary intended mode is
 * to create a resolver, then preloading it with one or more site-standard
 * catalogs before using it with one or more SAX parsers: <pre>
 *      XCat    catalog = new XCat ();
 *      catalog.setErrorHandler (diagnosticErrorHandler);
 *      catalog.loadCatalog ("file:/local/catalogs/catalog.cat");
 *      catalog.loadCatalog ("http://shared/catalog.cat");
 *      ...
 *      catalog.disableLoading ();
 *      parser1.setEntityResolver (catalog);
 *      parser2.setEntityResolver (catalog);
 *      ...</pre>
 *
 * <p>A second mode is to arrange that your application uses instances of
 * this class as its entity resolver, and automatically loads catalogs
 * referenced by <em>&lt;?oasis-xml-catalog...?&gt;</em> processing
 * instructions found before the DTD in documents it parses.
 * It would then discard the resolver after each parse.
 *
 * <p> A third mode applies catalogs in contexts other than entity
 * resolution for parsers.
 * The {@link #resolveURI resolveURI()} method supports resolving URIs
 * stored in XML application data, rather than inside DTDs.
 * Catalogs would be loaded as shown above, and the catalog could
 * be used concurrently for parser entity resolution and for
 * application URI resolution.
 * </p>
 *
 * <center><hr width='70%'></center>
 *
 * <p>Errors in catalogs implicitly loaded (during resolution) are ignored
 * beyond being reported through any <em>ErrorHandler</em> assigned using
 * {@link #setErrorHandler setErrorHandler()}.  SAX exceptions
 * thrown from such a handler won't abort resolution, although throwing a
 * <em>RuntimeException</em> or <em>Error</em> will normally abort both
 * resolution and parsing.  Useful diagnostic information is available to
 * any <em>ErrorHandler</em> used to report problems, or from any exception
 * thrown from an explicit {@link #loadCatalog loadCatalog()} invocation.
 * Applications can use that information as troubleshooting aids.
 *
 * <p>While this class requires <em>SAX2 Extensions 1.1</em> classes in
 * its class path, basic functionality does not require using a SAX2
 * parser that supports the extended entity resolution functionality.
 * See the original SAX1
 * {@link #resolveEntity(java.lang.String,java.lang.String) resolveEntity()}
 * method for a list of restrictions which apply when it is used with
 * older SAX parsers.
 *
 * @see EntityResolver2
 *
 * @author David Brownell
 */
public class XCat implements EntityResolver2
{
    private Catalog             catalogs [];
    private boolean             usingPublic = true;
    private boolean             loadingPermitted = true;
    private boolean             unified = true;
    private String              parserClass;
    private ErrorHandler        errorHandler;

    // private EntityResolver   next;   // chain to next if we fail...

    //
    // NOTE:  This is a straightforward implementation, and if
    // there are lots of "nextCatalog" or "delegate*" entries
    // in use, two tweaks would be worth considering:
    //
    //  - Centralize some sort of cache (key by URI) for individual
    //    resolvers.  That'd avoid multiple copies of a given catalog.
    //
    //  - Have resolution track what catalogs (+modes) have been
    //    searched.  This would support loop detection.
    //


    /**
     * Initializes without preloading a catalog.
     * This API is convenient when you may want to arrange that catalogs
     * are automatically loaded when explicitly referenced in documents,
     * using the <em>oasis-xml-catalog</em> processing instruction.
     * In such cases you won't usually be able to preload catalogs.
     */
    public XCat () { }

    /**
     * Initializes, and preloads a catalog using the default SAX parser.
     * This API is convenient when you operate with one or more standard
     * catalogs.
     *
     * <p> This just delegates to {@link #loadCatalog loadCatalog()};
     * see it for exception information.
     *
     * @param uri absolute URI for the catalog file.
     */
    public XCat (String uri)
    throws SAXException, IOException
        { loadCatalog (uri); }


    /**
     * Loads an OASIS XML Catalog.
     * It is appended to the list of currently active catalogs, or
     * reloaded if a catalog with the same URI was already loaded.
     * Callers have control over what parser is used, how catalog parsing
     * errors are reported, and whether URIs will be resolved consistently.
     *
     * <p> The OASIS specification says that errors detected when loading
     * catalogs "must recover by ignoring the catalog entry file that
     * failed, and proceeding."  In this API, that action can be the
     * responsibility of applications, when they explicitly load any
     * catalog using this method.
     *
     * <p>Note that catalogs referenced by this one will not be loaded
     * at this time.  Catalogs referenced through <em>nextCatalog</em>
     * or <em>delegate*</em> elements are normally loaded only if needed.
     *
     * @see #setErrorHandler
     * @see #setParserClass
     * @see #setUnified
     *
     * @param uri absolute URI for the catalog file.
     *
     * @exception IOException As thrown by the parser, typically to
     *  indicate problems reading data from that URI.
     * @exception SAXException As thrown by the parser, typically to
     *  indicate problems parsing data from that URI.  It may also
     *  be thrown if the parser doesn't support necessary handlers.
     * @exception IllegalStateException When attempting to load a
     *  catalog after loading has been {@link #disableLoading disabled},
     *  such as after any entity or URI lookup has been performed.
     */
    public synchronized void loadCatalog (String uri)
    throws SAXException, IOException
    {
        Catalog         catalog;
        int             index = -1;

        if (!loadingPermitted)
            throw new IllegalStateException ();

        uri = normalizeURI (uri);
        if (catalogs != null) {
            // maybe just reload
            for (index = 0; index < catalogs.length; index++)
                if (uri.equals (catalogs [index].catalogURI))
                    break;
        }
        catalog = loadCatalog (parserClass, errorHandler, uri, unified);

        // add to list of catalogs
        if (catalogs == null) {
            index = 0;
            catalogs = new Catalog [1];
        } else if (index == catalogs.length) {
            Catalog             tmp [];

            tmp = new Catalog [index + 1];
            System.arraycopy (catalogs, 0, tmp, 0, index);
            catalogs = tmp;
        }
        catalogs [index] = catalog;
    }


    /**
     * "New Style" external entity resolution for parsers.
     * Calls to this method prevent explicit loading of additional catalogs
     * using {@link #loadCatalog loadCatalog()}.
     *
     * <p>This supports the full core catalog functionality for locating
     * (and relocating) parsed entities that have been declared in a
     * document's DTD.
     *
     * @param name Entity name, such as "dudley", "%nell", or "[dtd]".
     * @param publicId Either a normalized public ID, or null.
     * @param baseURI Absolute base URI associated with systemId.
     * @param systemId URI found in entity declaration (may be
     *  relative to baseURI).
     *
     * @return Input source for accessing the external entity, or null
     *  if no mapping was found.  The input source may have opened
     *  the stream, and will have a fully resolved URI.
     *
     * @see #getExternalSubset
     */
    public InputSource resolveEntity (
        String name,            // UNUSED ... systemId is always non-null
        String publicId,
        String baseURI,         // UNUSED ... it just lets sysId be relative
        String systemId
    ) throws SAXException, IOException
    {
        if (loadingPermitted)
            disableLoading ();

        try {
            // steps as found in OASIS XML catalog spec 7.1.2
            // steps 1, 8 involve looping over the list of catalogs
            for (int i = 0; i < catalogs.length; i++) {
                InputSource     retval;
                retval = catalogs [i].resolve (usingPublic, publicId, systemId);
                if (retval != null)
                    return retval;
            }
        } catch (DoneDelegation x) {
            // done!
        }
        // step 9 involves returning "no match"
        return null;
    }


    /**
     * "New Style" parser callback to add an external subset.
     * For documents that don't include an external subset, this may
     * return one according to <em>doctype</em> catalog entries.
     * (This functionality is not a core part of the OASIS XML Catalog
     * specification, though it's presented in an appendix.)
     * If no such entry is defined, this returns null to indicate that
     * this document will not be modified to include such a subset.
     * Calls to this method prevent explicit loading of additional catalogs
     * using {@link #loadCatalog loadCatalog()}.
     *
     * <p><em>Warning:</em> That catalog functionality can be dangerous.
     * It can provide definitions of general entities, and thereby mask
     * certain well formedess errors.
     *
     * @param name Name of the document element, either as declared in
     *  a DOCTYPE declaration or as observed in the text.
     * @param baseURI Document's base URI (absolute).
     *
     * @return Input source for accessing the external subset, or null
     *  if no mapping was found.  The input source may have opened
     *  the stream, and will have a fully resolved URI.
     */
    public InputSource getExternalSubset (String name, String baseURI)
    throws SAXException, IOException
    {
        if (loadingPermitted)
            disableLoading ();
        try {
            for (int i = 0; i < catalogs.length; i++) {
                InputSource retval = catalogs [i].getExternalSubset (name);
                if (retval != null)
                    return retval;
            }
        } catch (DoneDelegation x) {
            // done!
        }
        return null;
    }


    /**
     * "Old Style" external entity resolution for parsers.
     * This API provides only core functionality.
     * Calls to this method prevent explicit loading of additional catalogs
     * using {@link #loadCatalog loadCatalog()}.
     *
     * <p>The functional limitations of this interface include:</p><ul>
     *
     *  <li>Since system IDs will be absolutized before the resolver
     *  sees them, matching against relative URIs won't work.
     *  This may affect <em>system</em>, <em>rewriteSystem</em>,
     *  and <em>delegateSystem</em> catalog entries.
     *
     *  <li>Because of that absolutization, documents declaring entities
     *  with system IDs using URI schemes that the JVM does not recognize
     *  may be unparsable.  URI schemes such as <em>file:/</em>,
     *  <em>http://</em>, <em>https://</em>, and <em>ftp://</em>
     *  will usually work reliably.
     *
     *  <li>Because missing external subsets can't be provided, the
     *  <em>doctype</em> catalog entries will be ignored.
     *  (The {@link #getExternalSubset getExternalSubset()} method is
     *  a "New Style" resolution option.)
     *
     *  </ul>
     *
     * <p>Applications can tell whether this limited functionality will be
     * used: if the feature flag associated with the {@link EntityResolver2}
     * interface is not <em>true</em>, the limitations apply.  Applications
     * can't usually know whether a given document and catalog will trigger
     * those limitations.  The issue can only be bypassed by operational
     * procedures such as not using catalogs or documents which involve
     * those features.
     *
     * @param publicId Either a normalized public ID, or null
     * @param systemId Always an absolute URI.
     *
     * @return Input source for accessing the external entity, or null
     *  if no mapping was found.  The input source may have opened
     *  the stream, and will have a fully resolved URI.
     */
    final public InputSource resolveEntity (String publicId, String systemId)
    throws SAXException, IOException
    {
        return resolveEntity (null, publicId, null, systemId);
    }


    /**
     * Resolves a URI reference that's not defined to the DTD.
     * This is intended for use with URIs found in document text, such as
     * <em>xml-stylesheet</em> processing instructions and in attribute
     * values, where they are not recognized as URIs by XML parsers.
     * Calls to this method prevent explicit loading of additional catalogs
     * using {@link #loadCatalog loadCatalog()}.
     *
     * <p>This functionality is supported by the OASIS XML Catalog
     * specification, but will never be invoked by an XML parser.
     * It corresponds closely to functionality for mapping system
     * identifiers for entities declared in DTDs; closely enough that
     * this implementation's default behavior is that they be
     * identical, to minimize potential confusion.
     *
     * <p>This method could be useful when implementing the
     * {@link javax.xml.transform.URIResolver} interface, wrapping the
     * input source in a {@link javax.xml.transform.sax.SAXSource}.
     *
     * @see #isUnified
     * @see #setUnified
     *
     * @param baseURI The relevant base URI as specified by the XML Base
     *  specification.  This recognizes <em>xml:base</em> attributes
     *  as overriding the actual (physical) base URI.
     * @param uri Either an absolute URI, or one relative to baseURI
     *
     * @return Input source for accessing the mapped URI, or null
     *  if no mapping was found.  The input source may have opened
     *  the stream, and will have a fully resolved URI.
     */
    public InputSource resolveURI (String baseURI, String uri)
    throws SAXException, IOException
    {
        if (loadingPermitted)
            disableLoading ();

        // NOTE:  baseURI isn't used here, but caller MUST have it,
        // and heuristics _might_ use it in the future ... plus,
        // it's symmetric with resolveEntity ().

        // steps 1, 6 involve looping
        try {
            for (int i = 0; i < catalogs.length; i++) {
                InputSource     tmp = catalogs [i].resolveURI (uri);
                if (tmp != null)
                    return tmp;
            }
        } catch (DoneDelegation x) {
            // done
        }
        // step 7 reports no match
        return null;
    }


    /**
     * Records that catalog loading is no longer permitted.
     * Loading is automatically disabled when lookups are performed,
     * and should be manually disabled when <em>startDTD()</em> (or
     * any other DTD declaration callback) is invoked, or at the latest
     * when the document root element is seen.
     */
    public synchronized void disableLoading ()
    {
        // NOTE:  this method and loadCatalog() are synchronized
        // so that it's impossible to load (top level) catalogs
        // after lookups start.  Likewise, deferred loading is also
        // synchronized (for "next" and delegated catalogs) to
        // ensure that parsers can share resolvers.
        loadingPermitted = false;
    }


    /**
     * Returns the error handler used to report catalog errors.
     * Null is returned if the parser's default error handling
     * will be used.
     *
     * @see #setErrorHandler
     */
    public ErrorHandler getErrorHandler ()
        { return errorHandler; }

    /**
     * Assigns the error handler used to report catalog errors.
     * These errors may come either from the SAX2 parser or
     * from the catalog parsing code driven by the parser.
     *
     * <p> If you're sharing the resolver between parsers, don't
     * change this once lookups have begun.
     *
     * @see #getErrorHandler
     *
     * @param parser The error handler, or null saying to use the default
     *  (no diagnostics, and only fatal errors terminate loading).
     */
    public void setErrorHandler (ErrorHandler handler)
        { errorHandler = handler; }


    /**
     * Returns the name of the SAX2 parser class used to parse catalogs.
     * Null is returned if the system default is used.
     * @see #setParserClass
     */
    public String getParserClass ()
        { return parserClass; }

    /**
     * Names the SAX2 parser class used to parse catalogs.
     *
     * <p> If you're sharing the resolver between parsers, don't change
     * this once lookups have begun.
     *
     * <p> Note that in order to properly support the <em>xml:base</em>
     * attribute and relative URI resolution, the SAX parser used to parse
     * the catalog must provide a {@link Locator} and support the optional
     * declaration and lexical handlers.
     *
     * @see #getParserClass
     *
     * @param parser The parser class name, or null saying to use the
     *  system default SAX2 parser.
     */
    public void setParserClass (String parser)
        { parserClass = parser; }


    /**
     * Returns true (the default) if all methods resolve
     * a given URI in the same way.
     * Returns false if calls resolving URIs as entities (such as
     * {@link #resolveEntity resolveEntity()}) use different catalog entries
     * than those resolving them as URIs ({@link #resolveURI resolveURI()}),
     * which will generally produce different results.
     *
     * <p>The OASIS XML Catalog specification defines two related schemes
     * to map URIs "as URIs" or "as system IDs".
     * URIs use <em>uri</em>, <em>rewriteURI</em>, and <em>delegateURI</em>
     * elements.  System IDs do the same things with <em>systemId</em>,
     * <em>rewriteSystemId</em>, and <em>delegateSystemId</em>.
     * It's confusing and error prone to maintain two parallel copies of
     * such data.  Accordingly, this class makes that behavior optional.
     * The <em>unified</em> interpretation of URI mappings is preferred,
     * since it prevents surprises where one URI gets mapped to different
     * contents depending on whether the reference happens to have come
     * from a DTD (or not).
     *
     * @see #setUnified
     */
    public boolean isUnified ()
        { return unified; }

    /**
     * Assigns the value of the flag returned by {@link #isUnified}.
     * Set it to false to be strictly conformant with the OASIS XML Catalog
     * specification.  Set it to true to make all mappings for a given URI
     * give the same result, regardless of the reason for the mapping.
     *
     * <p>Don't change this once you've loaded the first catalog.
     *
     * @param value new flag setting
     */
    public void setUnified (boolean value)
        { unified = value; }


    /**
     * Returns true (the default) if a catalog's public identifier
     * mappings will be used.
     * When false is returned, such mappings are ignored except when
     * system IDs are discarded, such as for
     * entities using the <em>urn:publicid:</em> URI scheme in their
     * system identifiers.  (See RFC 3151 for information about that
     * URI scheme.  Using it in system identifiers may not work well
     * with many SAX parsers unless the <em>resolve-dtd-uris</em>
     * feature flag is set to false.)
     * @see #setUsingPublic
     */
    public boolean isUsingPublic ()
        { return usingPublic; }

    /**
     * Specifies which catalog search mode is used.
     * By default, public identifier mappings are able to override system
     * identifiers when both are available.
     * Applications may choose to ignore public
     * identifier mappings in such cases, so that system identifiers
     * declared in DTDs will only be overridden by an explicit catalog
     * match for that system ID.
     *
     * <p> If you're sharing the resolver between parsers, don't
     * change this once lookups have begun.
     * @see #isUsingPublic
     *
     * @param value true to always use public identifier mappings,
     *  false to only use them for system ids using the <em>urn:publicid:</em>
     *  URI scheme.
     */
    public void setUsingPublic (boolean value)
        { usingPublic = value; }



    // hmm, what's this do? :)
    private static Catalog loadCatalog (
        String          parserClass,
        ErrorHandler    eh,
        String          uri,
        boolean         unified
    ) throws SAXException, IOException
    {
        XMLReader       parser;
        Loader          loader;
        boolean         doesIntern = false;

        if (parserClass == null)
            parser = XMLReaderFactory.createXMLReader ();
        else
            parser = XMLReaderFactory.createXMLReader (parserClass);
        if (eh != null)
            parser.setErrorHandler (eh);
        // resolve-dtd-entities is at default value (unrecognized == true)

        try {
            doesIntern = parser.getFeature (
                "http://xml.org/sax/features/string-interning");
        } catch (SAXNotRecognizedException e) { }

        loader = new Loader (doesIntern, eh, unified);
        loader.cat.parserClass = parserClass;
        loader.cat.catalogURI = uri;

        parser.setContentHandler (loader);
        parser.setProperty (
            "http://xml.org/sax/properties/declaration-handler",
            loader);
        parser.setProperty (
            "http://xml.org/sax/properties/lexical-handler",
            loader);
        parser.parse (uri);

        return loader.cat;
    }

    // perform one or both the normalizations for public ids
    private static String normalizePublicId (boolean full, String publicId)
    {
        if (publicId.startsWith ("urn:publicid:")) {
            CPStringBuilder     buf = new CPStringBuilder ();
            char                chars [] = publicId.toCharArray ();
boolean hasbug = false;

            for (int i = 13; i < chars.length; i++) {
                switch (chars [i]) {
                case '+':       buf.append (' '); continue;
                case ':':       buf.append ("//"); continue;
                case ';':       buf.append ("::"); continue;
                case '%':
// FIXME unhex that char!  meanwhile, warn and fallthrough ...
                    hasbug = true;
                default:        buf.append (chars [i]); continue;
                }
            }
            publicId = buf.toString ();
if (hasbug)
System.err.println ("nyet unhexing public id: " + publicId);
            full = true;
        }

        // SAX parsers do everything except that URN mapping, but
        // we can't trust other sources to normalize correctly
        if (full) {
            StringTokenizer     tokens;
            String              token;

            tokens = new StringTokenizer (publicId, " \r\n");
            publicId = null;
            while (tokens.hasMoreTokens ()) {
                if (publicId == null)
                    publicId = tokens.nextToken ();
                else
                    publicId += " " + tokens.nextToken ();
            }
        }
        return publicId;
    }

    private static boolean isUriExcluded (int c)
        { return c <= 0x20 || c >= 0x7f || "\"<>^`{|}".indexOf (c) != -1; }

    private static int hexNibble (int c)
    {
        if (c < 10)
            return c + '0';
        return ('a' - 10) + c;
    }

    // handles URIs with "excluded" characters
    private static String normalizeURI (String systemId)
    {
        int                     length = systemId.length ();

        for (int i = 0; i < length; i++) {
            char        c = systemId.charAt (i);

            // escape non-ASCII plus "excluded" characters
            if (isUriExcluded (c)) {
                byte                    buf [];
                ByteArrayOutputStream   out;
                int                             b;

                // a JVM that doesn't know UTF8 and 8859_1 is unusable!
                try {
                    buf = systemId.getBytes ("UTF8");
                    out = new ByteArrayOutputStream (buf.length + 10);

                    for (i = 0; i < buf.length; i++) {
                        b = buf [i] & 0x0ff;
                        if (isUriExcluded (b)) {
                            out.write ((int) '%');
                            out.write (hexNibble (b >> 4));
                            out.write (hexNibble (b & 0x0f));
                        } else
                            out.write (b);
                    }
                    return out.toString ("8859_1");
                } catch (IOException e) {
                    throw new RuntimeException (
                        "can't normalize URI: " + e.getMessage ());
                }
            }
        }
        return systemId;
    }

    // thrown to mark authoritative end of a search
    private static class DoneDelegation extends SAXException
    {
        DoneDelegation () { }
    }


    /**
     * Represents a OASIS XML Catalog, and encapsulates much of
     * the catalog functionality.
     */
    private static class Catalog
    {
        // loading infrastructure
        String          catalogURI;
        ErrorHandler    eh;
        boolean         unified;
        String          parserClass;

        // catalog data
        boolean         hasPreference;
        boolean         usingPublic;

        Hashtable       publicIds;
        Hashtable       publicDelegations;

        Hashtable       systemIds;
        Hashtable       systemRewrites;
        Hashtable       systemDelegations;

        Hashtable       uris;
        Hashtable       uriRewrites;
        Hashtable       uriDelegations;

        Hashtable       doctypes;

        Vector          next;

        // nonpublic!
        Catalog () { }


        // steps as found in OASIS XML catalog spec 7.1.2
        private InputSource locatePublicId (String publicId)
        throws SAXException, IOException
        {
            // 5. return (first) 'public' entry
            if (publicIds != null) {
                String  retval = (String) publicIds.get (publicId);
                if (retval != null) {
                    // IF the URI is accessible ...
                    return new InputSource (retval);
                }
            }

            // 6. return delegatePublic catalog match [complex]
            if (publicDelegations != null)
                return checkDelegations (publicDelegations, publicId,
                                publicId, null);

            return null;
        }

        // steps as found in OASIS XML catalog spec 7.1.2 or 7.2.2
        private InputSource mapURI (
            String      uri,
            Hashtable   ids,
            Hashtable   rewrites,
            Hashtable   delegations
        ) throws SAXException, IOException
        {
            // 7.1.2: 2. return (first) 'system' entry
            // 7.2.2: 2. return (first) 'uri' entry
            if (ids != null) {
                String  retval = (String) ids.get (uri);
                if (retval != null) {
                    // IF the URI is accessible ...
                    return new InputSource (retval);
                }
            }

            // 7.1.2: 3. return 'rewriteSystem' entries
            // 7.2.2: 3. return 'rewriteURI' entries
            if (rewrites != null) {
                String  prefix = null;
                String  replace = null;
                int     prefixLen = -1;

                for (Enumeration e = rewrites.keys ();
                        e.hasMoreElements ();
                        /* NOP */) {
                    String      temp = (String) e.nextElement ();
                    int         len = -1;

                    if (!uri.startsWith (temp))
                        continue;
                    if (prefix != null
                            && (len = temp.length ()) < prefixLen)
                        continue;
                    prefix = temp;
                    prefixLen = len;
                    replace = (String) rewrites.get (temp);
                }
                if (prefix != null) {
                    CPStringBuilder     buf = new CPStringBuilder (replace);
                    buf.append (uri.substring (prefixLen));
                    // IF the URI is accessible ...
                    return new InputSource (buf.toString ());
                }
            }

            // 7.1.2: 4. return 'delegateSystem' catalog match [complex]
            // 7.2.2: 4. return 'delegateURI' catalog match [complex]
            if (delegations != null)
                return checkDelegations (delegations, uri, null, uri);

            return null;
        }


        /**
         * Returns a URI for an external entity.
         */
        public InputSource resolve (
            boolean     usingPublic,
            String      publicId,
            String      systemId
        ) throws SAXException, IOException
        {
            boolean     preferSystem;
            InputSource retval;

            if (hasPreference)
                preferSystem = !this.usingPublic;
            else
                preferSystem = !usingPublic;

            if (publicId != null)
                publicId = normalizePublicId (false, publicId);

            // behavior here matches section 7.1.1 of the oasis spec
            if (systemId != null) {
                if (systemId.startsWith ("urn:publicid:")) {
                    String      temp = normalizePublicId (true, systemId);
                    if (publicId == null) {
                        publicId = temp;
                        systemId = null;
                    } else if (!publicId.equals (temp)) {
                        // error; ok to recover by:
                        systemId = null;
                    }
                } else
                    systemId = normalizeURI (systemId);
            }

            if (systemId == null && publicId == null)
                return null;

            if (systemId != null) {
                retval = mapURI (systemId, systemIds, systemRewrites,
                                        systemDelegations);
                if (retval != null) {
                    retval.setPublicId (publicId);
                    return retval;
                }
            }

            if (publicId != null
                    && !(systemId != null && preferSystem)) {
                retval = locatePublicId (publicId);
                if (retval != null) {
                    retval.setPublicId (publicId);
                    return retval;
                }
            }

            // 7. apply nextCatalog entries
            if (next != null) {
                int     length = next.size ();
                for (int i = 0; i < length; i++) {
                    Catalog     n = getNext (i);
                    retval = n.resolve (usingPublic, publicId, systemId);
                    if (retval != null)
                        return retval;
                }
            }

            return null;
        }

        /**
         * Maps one URI into another, for resources that are not defined
         * using XML external entity or notation syntax.
         */
        public InputSource resolveURI (String uri)
        throws SAXException, IOException
        {
            if (uri.startsWith ("urn:publicid:"))
                return resolve (true, normalizePublicId (true, uri), null);

            InputSource retval;

            uri = normalizeURI (uri);

            // 7.2.2 steps 2-4
            retval = mapURI (uri, uris, uriRewrites, uriDelegations);
            if (retval != null)
                return retval;

            // 7.2.2 step 5. apply nextCatalog entries
            if (next != null) {
                int     length = next.size ();
                for (int i = 0; i < length; i++) {
                    Catalog     n = getNext (i);
                    retval = n.resolveURI (uri);
                    if (retval != null)
                        return retval;
                }
            }

            return null;
        }


        /**
         * Finds the external subset associated with a given root element.
         */
        public InputSource getExternalSubset (String name)
        throws SAXException, IOException
        {
            if (doctypes != null) {
                String  value = (String) doctypes.get (name);
                if (value != null) {
                    // IF the URI is accessible ...
                    return new InputSource (value);
                }
            }
            if (next != null) {
                int     length = next.size ();
                for (int i = 0; i < length; i++) {
                    Catalog     n = getNext (i);
                    if (n == null)
                        continue;
                    InputSource retval = n.getExternalSubset (name);
                    if (retval != null)
                        return retval;
                }
            }
            return null;
        }

        private synchronized Catalog getNext (int i)
        throws SAXException, IOException
        {
            Object      obj;

            if (next == null || i < 0 || i >= next.size ())
                return null;
            obj = next.elementAt (i);
            if (obj instanceof Catalog)
                return (Catalog) obj;

            // ok, we deferred reading that catalog till now.
            // load and cache it.
            Catalog     cat = null;

            try {
                cat = loadCatalog (parserClass, eh, (String) obj, unified);
                next.setElementAt (cat, i);
            } catch (SAXException e) {
                // must fail quietly, says the OASIS spec
            } catch (IOException e) {
                // same applies here
            }
            return cat;
        }

        private InputSource checkDelegations (
            Hashtable   delegations,
            String      id,
            String      publicId,       // only one of public/system
            String      systemId        // will be non-null...
        ) throws SAXException, IOException
        {
            Vector      matches = null;
            int         length = 0;

            // first, see if any prefixes match.
            for (Enumeration e = delegations.keys ();
                    e.hasMoreElements ();
                    /* NOP */) {
                String  prefix = (String) e.nextElement ();

                if (!id.startsWith (prefix))
                    continue;
                if (matches == null)
                    matches = new Vector ();

                // maintain in longer->shorter sorted order
                // NOTE:  assumes not many matches will fire!
                int     index;

                for (index = 0; index < length; index++) {
                    String      temp = (String) matches.elementAt (index);
                    if (prefix.length () > temp.length ()) {
                        matches.insertElementAt (prefix, index);
                        break;
                    }
                }
                if (index == length)
                    matches.addElement (prefix);
                length++;
            }
            if (matches == null)
                return null;

            // now we know the list of catalogs to replace our "top level"
            // list ... we use it here, rather than somehow going back and
            // restarting, since this helps avoid reading most catalogs.
            // this assumes stackspace won't be a problem.
            for (int i = 0; i < length; i++) {
                Catalog         catalog = null;
                InputSource     result;

                // get this catalog.  we may not have read it yet.
                synchronized (delegations) {
                    Object      prefix = matches.elementAt (i);
                    Object      cat = delegations.get (prefix);

                    if (cat instanceof Catalog)
                        catalog = (Catalog) cat;
                    else {
                        try {
                            // load and cache that catalog
                            catalog = loadCatalog (parserClass, eh,
                                    (String) cat, unified);
                            delegations.put (prefix, catalog);
                        } catch (SAXException e) {
                            // must ignore, says the OASIS spec
                        } catch (IOException e) {
                            // same applies here
                        }
                    }
                }

                // ignore failed loads, and proceed
                if (catalog == null)
                    continue;

                // we have a catalog ... resolve!
                // usingPublic value can't matter, there's no choice
                result = catalog.resolve (true, publicId, systemId);
                if (result != null)
                    return result;
            }

            // if there were no successes, the entire
            // lookup failed (all the way to top level)
            throw new DoneDelegation ();
        }
    }


    /** This is the namespace URI used for OASIS XML Catalogs.  */
    private static final String catalogNamespace =
        "urn:oasis:names:tc:entity:xmlns:xml:catalog";


    /**
     * Loads/unmarshals one catalog.
     */
    private static class Loader extends DefaultHandler2
    {
        private boolean         preInterned;
        private ErrorHandler    handler;
        private boolean         unified;
        private int             ignoreDepth;
        private Locator         locator;
        private boolean         started;
        private Hashtable       externals;
        private Stack           bases;

        Catalog                 cat = new Catalog ();


        /**
         * Constructor.
         * @param flag true iff the parser already interns strings.
         * @param eh Errors and warnings are delegated to this.
         * @param unified true keeps one table for URI mappings;
         *      false matches OASIS spec, storing mappings
         *      for URIs and SYSTEM ids in parallel tables.
         */
        Loader (boolean flag, ErrorHandler eh, boolean unified)
        {
            preInterned = flag;
            handler = eh;
            this.unified = unified;
            cat.unified = unified;
            cat.eh = eh;
        }


        // strips out fragments
        private String nofrag (String uri)
        throws SAXException
        {
            if (uri.indexOf ('#') != -1) {
                warn ("URI with fragment: " + uri);
                uri = uri.substring (0, uri.indexOf ('#'));
            }
            return uri;
        }

        // absolutizes relative URIs
        private String absolutize (String uri)
        throws SAXException
        {
            // avoid creating URLs if they're already absolutized,
            // or if the URI is already using a known scheme
            if (uri.startsWith ("file:/")
                    || uri.startsWith ("http:/")
                    || uri.startsWith ("https:/")
                    || uri.startsWith ("ftp:/")
                    || uri.startsWith ("urn:")
                    )
                return uri;

            // otherwise, let's hope the JDK handles this URI scheme.
            try {
                URL     base = (URL) bases.peek ();
                return new URL (base, uri).toString ();
            } catch (Exception e) {
                fatal ("can't absolutize URI: " + uri);
                return null;
            }
        }

        // recoverable error
        private void error (String message)
        throws SAXException
        {
            if (handler == null)
                return;
            handler.error (new SAXParseException (message, locator));
        }

        // nonrecoverable error
        private void fatal (String message)
        throws SAXException
        {
            SAXParseException   spe;

            spe = new SAXParseException (message, locator);
            if (handler != null)
                handler.fatalError (spe);
            throw spe;
        }

        // low severity problem
        private void warn (String message)
        throws SAXException
        {
            if (handler == null)
                return;
            handler.warning (new SAXParseException (message, locator));
        }

        // callbacks:

        public void setDocumentLocator (Locator l)
            { locator = l; }

        public void startDocument ()
        throws SAXException
        {
            if (locator == null)
                error ("no locator!");
            bases = new Stack ();
            String      uri = locator.getSystemId ();
            try {
                bases.push (new URL (uri));
            } catch (IOException e) {
                fatal ("bad document base URI: " + uri);
            }
        }

        public void endDocument ()
        throws SAXException
        {
            try {
                if (!started)
                    error ("not a catalog!");
            } finally {
                locator = null;
                handler = null;
                externals = null;
                bases = null;
            }
        }

        // XML Base support for external entities.

        // NOTE: expects parser is in default "resolve-dtd-uris" mode.
        public void externalEntityDecl (String name, String pub, String sys)
        throws SAXException
        {
            if (externals == null)
                externals = new Hashtable ();
            if (externals.get (name) == null)
                externals.put (name, pub);
        }

        public void startEntity (String name)
        throws SAXException
        {
            if (externals == null)
                return;
            String uri = (String) externals.get (name);

            // NOTE: breaks if an EntityResolver substitutes these URIs.
            // If toplevel loader supports one, must intercept calls...
            if (uri != null) {
                try {
                    bases.push (new URL (uri));
                } catch (IOException e) {
                    fatal ("entity '" + name + "', bad URI: " + uri);
                }
            }
        }

        public void endEntity (String name)
        {
            if (externals == null)
                return;
            String value = (String) externals.get (name);

            if (value != null)
                bases.pop ();
        }

        /**
         * Processes catalog elements, saving their data.
         */
        public void startElement (String namespace, String local,
            String qName, Attributes atts)
        throws SAXException
        {
            // must ignore non-catalog elements, and their contents
            if (ignoreDepth != 0 || !catalogNamespace.equals (namespace)) {
                ignoreDepth++;
                return;
            }

            // basic sanity checks
            if (!preInterned)
                local = local.intern ();
            if (!started) {
                started = true;
                if ("catalog" != local)
                    fatal ("root element not 'catalog': " + local);
            }

            // Handle any xml:base attribute
            String      xmlbase = atts.getValue ("xml:base");

            if (xmlbase != null) {
                URL     base = (URL) bases.peek ();
                try {
                    base = new URL (base, xmlbase);
                } catch (IOException e) {
                    fatal ("can't resolve xml:base attribute: " + xmlbase);
                }
                bases.push (base);
            } else
                bases.push (bases.peek ());

            // fetch multi-element attributes, apply standard tweaks
            // values (uri, catalog, rewritePrefix) get normalized too,
            // as a precaution and since we may compare the values
            String      catalog = atts.getValue ("catalog");
            if (catalog != null)
                catalog = normalizeURI (absolutize (catalog));

            String      rewritePrefix = atts.getValue ("rewritePrefix");
            if (rewritePrefix != null)
                rewritePrefix = normalizeURI (absolutize (rewritePrefix));

            String      systemIdStartString;
            systemIdStartString = atts.getValue ("systemIdStartString");
            if (systemIdStartString != null) {
                systemIdStartString = normalizeURI (systemIdStartString);
                // unmatchable <rewriteSystemId>, <delegateSystemId> elements
                if (systemIdStartString.startsWith ("urn:publicid:")) {
                    error ("systemIdStartString is really a publicId!!");
                    return;
                }
            }

            String      uri = atts.getValue ("uri");
            if (uri != null)
                uri = normalizeURI (absolutize (uri));

            String      uriStartString;
            uriStartString = atts.getValue ("uriStartString");
            if (uriStartString != null) {
                uriStartString = normalizeURI (uriStartString);
                // unmatchable <rewriteURI>, <delegateURI> elements
                if (uriStartString.startsWith ("urn:publicid:")) {
                    error ("uriStartString is really a publicId!!");
                    return;
                }
            }

            // strictly speaking "group" and "catalog" shouldn't nest
            // ... arbitrary restriction, no evident motivation

// FIXME stack "prefer" settings (two elements only!) and use
// them to populate different public mapping/delegation tables

            if ("catalog" == local || "group" == local) {
                String  prefer = atts.getValue ("prefer");

                if (prefer != null && !"public".equals (prefer)) {
                    if (!"system".equals (prefer)) {
                        error ("in <" + local + " ... prefer='...'>, "
                            + "assuming 'public'");
                        prefer = "public";
                    }
                }
                if (prefer != null) {
                    if ("catalog" == local) {
                        cat.hasPreference = true;
                        cat.usingPublic = "public".equals (prefer);
                    } else {
                        if (!cat.hasPreference || cat.usingPublic
                                    != "public".equals (prefer)) {
fatal ("<group prefer=...> case not handled");
                        }
                    }
                } else if ("group" == local && cat.hasPreference) {
fatal ("<group prefer=...> case not handled");
                }

            //
            // PUBLIC ids:  cleanly set up for id substitution
            //
            } else if ("public" == local) {
                String  publicId = atts.getValue ("publicId");
                String  value = null;

                if (publicId == null || uri == null) {
                    error ("expecting <public publicId=... uri=.../>");
                    return;
                }
                publicId = normalizePublicId (true, publicId);
                uri = nofrag (uri);
                if (cat.publicIds == null)
                    cat.publicIds = new Hashtable ();
                else
                    value = (String) cat.publicIds.get (publicId);
                if (value != null) {
                    if (!value.equals (uri))
                        warn ("ignoring <public...> entry for " + publicId);
                } else
                    cat.publicIds.put (publicId, uri);

            } else if ("delegatePublic" == local) {
                String  publicIdStartString;
                Object  value = null;

                publicIdStartString = atts.getValue ("publicIdStartString");
                if (publicIdStartString == null || catalog == null) {
                    error ("expecting <delegatePublic "
                        + "publicIdStartString=... catalog=.../>");
                    return;
                }
                publicIdStartString = normalizePublicId (true,
                        publicIdStartString);
                if (cat.publicDelegations == null)
                    cat.publicDelegations = new Hashtable ();
                else
                    value = cat.publicDelegations.get (publicIdStartString);
                if (value != null) {
                    if (!value.equals (catalog))
                        warn ("ignoring <delegatePublic...> entry for "
                            + uriStartString);
                } else
                    cat.publicDelegations.put (publicIdStartString, catalog);


            //
            // SYSTEM ids:  need substitution due to operational issues
            //
            } else if ("system" == local) {
                String  systemId = atts.getValue ("systemId");
                String  value = null;

                if (systemId == null || uri == null) {
                    error ("expecting <system systemId=... uri=.../>");
                    return;
                }
                systemId = normalizeURI (systemId);
                uri = nofrag (uri);
                if (systemId.startsWith ("urn:publicid:")) {
                    error ("systemId is really a publicId!!");
                    return;
                }
                if (cat.systemIds == null) {
                    cat.systemIds = new Hashtable ();
                    if (unified)
                        cat.uris = cat.systemIds;
                } else
                    value = (String) cat.systemIds.get (systemId);
                if (value != null) {
                    if (!value.equals (uri))
                        warn ("ignoring <system...> entry for " + systemId);
                } else
                    cat.systemIds.put (systemId, uri);

            } else if ("rewriteSystem" == local) {
                String  value = null;

                if (systemIdStartString == null || rewritePrefix == null
                        || systemIdStartString.length () == 0
                        || rewritePrefix.length () == 0
                        ) {
                    error ("expecting <rewriteSystem "
                        + "systemIdStartString=... rewritePrefix=.../>");
                    return;
                }
                if (cat.systemRewrites == null) {
                    cat.systemRewrites = new Hashtable ();
                    if (unified)
                        cat.uriRewrites = cat.systemRewrites;
                } else
                    value = (String) cat.systemRewrites.get (
                                                systemIdStartString);
                if (value != null) {
                    if (!value.equals (rewritePrefix))
                        warn ("ignoring <rewriteSystem...> entry for "
                            + systemIdStartString);
                } else
                    cat.systemRewrites.put (systemIdStartString,
                                rewritePrefix);

            } else if ("delegateSystem" == local) {
                Object  value = null;

                if (systemIdStartString == null || catalog == null) {
                    error ("expecting <delegateSystem "
                        + "systemIdStartString=... catalog=.../>");
                    return;
                }
                if (cat.systemDelegations == null) {
                    cat.systemDelegations = new Hashtable ();
                    if (unified)
                        cat.uriDelegations = cat.systemDelegations;
                } else
                    value = cat.systemDelegations.get (systemIdStartString);
                if (value != null) {
                    if (!value.equals (catalog))
                        warn ("ignoring <delegateSystem...> entry for "
                            + uriStartString);
                } else
                    cat.systemDelegations.put (systemIdStartString, catalog);


            //
            // URI:  just like "system" ID support, except that
            // fragment IDs are disallowed in "system" elements.
            //
            } else if ("uri" == local) {
                String  name = atts.getValue ("name");
                String  value = null;

                if (name == null || uri == null) {
                    error ("expecting <uri name=... uri=.../>");
                    return;
                }
                if (name.startsWith ("urn:publicid:")) {
                    error ("name is really a publicId!!");
                    return;
                }
                name = normalizeURI (name);
                if (cat.uris == null) {
                    cat.uris = new Hashtable ();
                    if (unified)
                        cat.systemIds = cat.uris;
                } else
                    value = (String) cat.uris.get (name);
                if (value != null) {
                    if (!value.equals (uri))
                        warn ("ignoring <uri...> entry for " + name);
                } else
                    cat.uris.put (name, uri);

            } else if ("rewriteURI" == local) {
                String value = null;

                if (uriStartString == null || rewritePrefix == null
                        || uriStartString.length () == 0
                        || rewritePrefix.length () == 0
                        ) {
                    error ("expecting <rewriteURI "
                        + "uriStartString=... rewritePrefix=.../>");
                    return;
                }
                if (cat.uriRewrites == null) {
                    cat.uriRewrites = new Hashtable ();
                    if (unified)
                        cat.systemRewrites = cat.uriRewrites;
                } else
                    value = (String) cat.uriRewrites.get (uriStartString);
                if (value != null) {
                    if (!value.equals (rewritePrefix))
                        warn ("ignoring <rewriteURI...> entry for "
                            + uriStartString);
                } else
                    cat.uriRewrites.put (uriStartString, rewritePrefix);

            } else if ("delegateURI" == local) {
                Object  value = null;

                if (uriStartString == null || catalog == null) {
                    error ("expecting <delegateURI "
                        + "uriStartString=... catalog=.../>");
                    return;
                }
                if (cat.uriDelegations == null) {
                    cat.uriDelegations = new Hashtable ();
                    if (unified)
                        cat.systemDelegations = cat.uriDelegations;
                } else
                    value = cat.uriDelegations.get (uriStartString);
                if (value != null) {
                    if (!value.equals (catalog))
                        warn ("ignoring <delegateURI...> entry for "
                            + uriStartString);
                } else
                    cat.uriDelegations.put (uriStartString, catalog);

            //
            // NON-DELEGATING approach to modularity
            //
            } else if ("nextCatalog" == local) {
                if (catalog == null) {
                    error ("expecting <nextCatalog catalog=.../>");
                    return;
                }
                if (cat.next == null)
                    cat.next = new Vector ();
                cat.next.addElement (catalog);

            //
            // EXTENSIONS from appendix E
            //
            } else if ("doctype" == local) {
                String  name = atts.getValue ("name");
                String  value = null;

                if (name == null || uri == null) {
                    error ("expecting <doctype name=... uri=.../>");
                    return;
                }
                name = normalizeURI (name);
                if (cat.doctypes == null)
                    cat.doctypes = new Hashtable ();
                else
                    value = (String) cat.doctypes.get (name);
                if (value != null) {
                    if (!value.equals (uri))
                        warn ("ignoring <doctype...> entry for "
                            + uriStartString);
                } else
                    cat.doctypes.put (name, uri);


            //
            // RESERVED ... ignore (like reserved attributes) but warn
            //
            } else {
                warn ("ignoring unknown catalog element: " + local);
                ignoreDepth++;
            }
        }

        public void endElement (String uri, String local, String qName)
        throws SAXException
        {
            if (ignoreDepth != 0)
                ignoreDepth--;
            else
                bases.pop ();
        }
    }
}
