/* 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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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 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:")) {
	    StringBuffer	buf = new StringBuffer ();
	    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) {
		    StringBuffer	buf = new StringBuffer (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 ();
	}
    }
}
