xcat.java

来自「kaffe Java 解释器语言,源码,Java的子集系统,开放源代码」· Java 代码 · 共 1,599 行 · 第 1/4 页

JAVA
1,599
字号
/* * Copyright (C) 2001 David Brownell *  * This file is part of GNU JAXP, a library. * * GNU JAXP 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 of the License, or * (at your option) any later version. *  * GNU JAXP 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * * As a special exception, if you link this library with other files to * produce an executable, this library does not by itself cause the * resulting executable to be covered by the GNU General Public License. * This exception does not however invalidate any other reasons why the * executable file might be covered by the GNU General Public License.  */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 ();

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?