📄 xmlcatalog.java
字号:
* @param publicId the public id to resolve. * @param systemId the system id to resolve. * @throws SAXException if there is a parsing problem. * @throws IOException if there is an IO problem. * @return the resolved entity. * @see org.xml.sax.EntityResolver#resolveEntity */ public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { if (isReference()) { return getRef().resolveEntity(publicId, systemId); } dieOnCircularReference(); log("resolveEntity: '" + publicId + "': '" + systemId + "'", Project.MSG_DEBUG); InputSource inputSource = getCatalogResolver().resolveEntity(publicId, systemId); if (inputSource == null) { log("No matching catalog entry found, parser will use: '" + systemId + "'", Project.MSG_DEBUG); } return inputSource; } /** * Implements the URIResolver.resolve() interface method. * @param href an href attribute. * @param base the base URI. * @return a Source object, or null if href cannot be resolved. * @throws TransformerException if an error occurs. * @see javax.xml.transform.URIResolver#resolve */ public Source resolve(String href, String base) throws TransformerException { if (isReference()) { return getRef().resolve(href, base); } dieOnCircularReference(); SAXSource source = null; String uri = removeFragment(href); log("resolve: '" + uri + "' with base: '" + base + "'", Project.MSG_DEBUG); source = (SAXSource) getCatalogResolver().resolve(uri, base); if (source == null) { log("No matching catalog entry found, parser will use: '" + href + "'", Project.MSG_DEBUG); // // Cannot return a null source, because we have to call // setEntityResolver (see setEntityResolver javadoc comment) // source = new SAXSource(); URL baseURL = null; try { if (base == null) { baseURL = FILE_UTILS.getFileURL(getProject().getBaseDir()); } else { baseURL = new URL(base); } URL url = (uri.length() == 0 ? baseURL : new URL(baseURL, uri)); source.setInputSource(new InputSource(url.toString())); } catch (MalformedURLException ex) { // At this point we are probably in failure mode, but // try to use the bare URI as a last gasp source.setInputSource(new InputSource(uri)); } } setEntityResolver(source); return source; } /** * @since Ant 1.6 */ private XMLCatalog getRef() { if (!isReference()) { return this; } return (XMLCatalog) getCheckedRef(XMLCatalog.class, "xmlcatalog"); } /** * The instance of the CatalogResolver strategy to use. */ private CatalogResolver catalogResolver = null; /** * Factory method for creating the appropriate CatalogResolver * strategy implementation. * <p> Until we query the classpath, we don't know whether the Apache * resolver (Norm Walsh's library from xml-commons) is available or not. * This method determines whether the library is available and creates the * appropriate implementation of CatalogResolver based on the answer.</p> * <p>This is an application of the Gang of Four Strategy Pattern * combined with Template Method.</p> */ private CatalogResolver getCatalogResolver() { if (catalogResolver == null) { AntClassLoader loader = null; loader = getProject().createClassLoader(Path.systemClasspath); try { Class clazz = Class.forName(APACHE_RESOLVER, true, loader); // The Apache resolver is present - Need to check if it can // be seen by the catalog resolver class. Start by getting // the actual loader ClassLoader apacheResolverLoader = clazz.getClassLoader(); // load the base class through this loader. Class baseResolverClass = Class.forName(CATALOG_RESOLVER, true, apacheResolverLoader); // and find its actual loader ClassLoader baseResolverLoader = baseResolverClass.getClassLoader(); // We have the loader which is being used to load the // CatalogResolver. Can it see the ApacheResolver? The // base resolver will only be able to create the ApacheResolver // if it can see it - doesn't use the context loader. clazz = Class.forName(APACHE_RESOLVER, true, baseResolverLoader); Object obj = clazz.newInstance(); // // Success! The xml-commons resolver library is // available, so use it. // catalogResolver = new ExternalResolver(clazz, obj); } catch (Throwable ex) { // // The xml-commons resolver library is not // available, so we can't use it. // catalogResolver = new InternalResolver(); if (getCatalogPath() != null && getCatalogPath().list().length != 0) { log("Warning: XML resolver not found; external catalogs" + " will be ignored", Project.MSG_WARN); } log("Failed to load Apache resolver: " + ex, Project.MSG_DEBUG); } } return catalogResolver; } /** * <p>This is called from the URIResolver to set an EntityResolver * on the SAX parser to be used for new XML documents that are * encountered as a result of the document() function, xsl:import, * or xsl:include. This is done because the XSLT processor calls * out to the SAXParserFactory itself to create a new SAXParser to * parse the new document. The new parser does not automatically * inherit the EntityResolver of the original (although arguably * it should). See below:</p> * * <tt>"If an application wants to set the ErrorHandler or * EntityResolver for an XMLReader used during a transformation, * it should use a URIResolver to return the SAXSource which * provides (with getXMLReader) a reference to the XMLReader"</tt> * * <p>...quoted from page 118 of the Java API for XML * Processing 1.1 specification</p> * */ private void setEntityResolver(SAXSource source) throws TransformerException { XMLReader reader = source.getXMLReader(); if (reader == null) { SAXParserFactory spFactory = SAXParserFactory.newInstance(); spFactory.setNamespaceAware(true); try { reader = spFactory.newSAXParser().getXMLReader(); } catch (ParserConfigurationException ex) { throw new TransformerException(ex); } catch (SAXException ex) { throw new TransformerException(ex); } } reader.setEntityResolver(this); source.setXMLReader(reader); } /** * Find a ResourceLocation instance for the given publicId. * * @param publicId the publicId of the Resource for which local information * is required. * @return a ResourceLocation instance with information on the local location * of the Resource or null if no such information is available. */ private ResourceLocation findMatchingEntry(String publicId) { Enumeration e = getElements().elements(); ResourceLocation element = null; while (e.hasMoreElements()) { Object o = e.nextElement(); if (o instanceof ResourceLocation) { element = (ResourceLocation) o; if (element.getPublicId().equals(publicId)) { return element; } } } return null; } /** * Utility method to remove trailing fragment from a URI. * For example, * <code>http://java.sun.com/index.html#chapter1</code> * would return <code>http://java.sun.com/index.html</code>. * * @param uri The URI to process. It may or may not contain a * fragment. * @return The URI sans fragment. */ private String removeFragment(String uri) { String result = uri; int hashPos = uri.indexOf("#"); if (hashPos >= 0) { result = uri.substring(0, hashPos); } return result; } /** * Utility method to lookup a ResourceLocation in the filesystem. * * @return An InputSource for reading the file, or <code>null</code> * if the file does not exist or is not readable. */ private InputSource filesystemLookup(ResourceLocation matchingEntry) { String uri = matchingEntry.getLocation(); // the following line seems to be necessary on Windows under JDK 1.2 uri = uri.replace(File.separatorChar, '/'); URL baseURL = null; // // The ResourceLocation may specify a relative path for its // location attribute. This is resolved using the appropriate // base. // if (matchingEntry.getBase() != null) { baseURL = matchingEntry.getBase(); } else { try { baseURL = FILE_UTILS.getFileURL(getProject().getBaseDir()); } catch (MalformedURLException ex) { throw new BuildException("Project basedir cannot be converted to a URL"); } } InputSource source = null; URL url = null; try { url = new URL(baseURL, uri); } catch (MalformedURLException ex) { // this processing is useful under Windows when the location of the DTD // has been given as an absolute path // see Bugzilla Report 23913 File testFile = new File(uri); if (testFile.exists() && testFile.canRead()) { log("uri : '" + uri + "' matches a readable file", Project.MSG_DEBUG); try { url = FILE_UTILS.getFileURL(testFile); } catch (MalformedURLException ex1) { throw new BuildException( "could not find an URL for :" + testFile.getAbsolutePath()); } } else { log("uri : '" + uri + "' does not match a readable file", Project.MSG_DEBUG); } } if (url != null && url.getProtocol().equals("file")) { String fileName = FILE_UTILS.fromURI(url.toString()); if (fileName != null) { log("fileName " + fileName, Project.MSG_DEBUG); File resFile = new File(fileName); if (resFile.exists() && resFile.canRead()) { try { source = new InputSource(new FileInputStream(resFile)); String sysid = JAXPUtils.getSystemId(resFile); source.setSystemId(sysid); log("catalog entry matched a readable file: '" + sysid + "'", Project.MSG_DEBUG); } catch (IOException ex) { // ignore } } } } return source; } /** * Utility method to lookup a ResourceLocation in the classpath. * * @return An InputSource for reading the resource, or <code>null</code> * if the resource does not exist in the classpath or is not readable. */ private InputSource classpathLookup(ResourceLocation matchingEntry) { InputSource source = null; AntClassLoader loader = null; Path cp = classpath; if (cp != null) { cp = classpath.concatSystemClasspath("ignore"); } else { cp = (new Path(getProject())).concatSystemClasspath("last"); } loader = getProject().createClassLoader(cp); // // for classpath lookup we ignore the base directory // InputStream is = loader.getResourceAsStream(matchingEntry.getLocation()); if (is != null) { source = new InputSource(is); URL entryURL = loader.getResource(matchingEntry.getLocation()); String sysid = entryURL.toExternalForm(); source.setSystemId(sysid); log("catalog entry matched a resource in the classpath: '" + sysid + "'", Project.MSG_DEBUG); } return source; } /** * Utility method to lookup a ResourceLocation in URL-space. * * @return An InputSource for reading the resource, or <code>null</code> * if the resource does not identify a valid URL or is not readable. */ private InputSource urlLookup(ResourceLocation matchingEntry) { String uri = matchingEntry.getLocation(); URL baseURL = null; // // The ResourceLocation may specify a relative url for its // location attribute. This is resolved using the appropriate // base. // if (matchingEntry.getBase() != null) { baseURL = matchingEntry.getBase(); } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -