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><?oasis-xml-catalog...?></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 + -
显示快捷键?