All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.enhydra.xml.io.XMLEntityResolver Maven / Gradle / Ivy

The newest version!
/*
 * Enhydra Java Application Server Project
 * 
 * The contents of this file are subject to the Enhydra Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License on
 * the Enhydra web site ( http://www.enhydra.org/ ).
 * 
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 
 * the License for the specific terms governing rights and limitations
 * under the License.
 * 
 * The Initial Developer of the Enhydra Application Server is Lutris
 * Technologies, Inc. The Enhydra Application Server and portions created
 * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
 * All Rights Reserved.
 * 
 * Contributor(s):
 * 
 * $Id: XMLEntityResolver.java,v 1.3 2005/01/26 08:29:24 jkjome Exp $
 */

package org.enhydra.xml.io;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.Vector;

import org.enhydra.apache.xerces.readers.XCatalog;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * A flexable entity resolver for use with parsing XML files.
 * This implements:
 * 
    *
  • XCatalog support. *
  • Resolving entities from class loaders. *
  • Resolving standard URL entities. *
  • A debug output stream, useful for debugging resolution problems. *
*

* A list of class loaders maybe associated with this object. If so * an attempt will be made to resolve file: URLs from * the class path. * * @see org.enhydra.apache.xerces.readers.XCatalog */ public class XMLEntityResolver implements EntityResolver { /** * Protocol to use in specifying a URL pointing to the CLASSPATH. */ public static final String CLASSPATH_PROTOCOL = "file"; /** * Protocol prefix. */ public static final String CLASSPATH_PROTOCOL_PREFIX = CLASSPATH_PROTOCOL + ":"; /** * URL for Enhydra default entity catalog. * @see #setDefaultResolving */ public static final String DEFAULT_ENTITY_CATALOG = CLASSPATH_PROTOCOL_PREFIX + "/org/enhydra/xml/catalog/default.xcat"; /** * URL for Lutrus Enhydra default entity catalog. Only loaded if * available. * @see #setDefaultResolving */ public static final String LUTRIS_ENTITY_CATALOG = CLASSPATH_PROTOCOL_PREFIX + "/org/enhydra/xml/catalog/lutris.xcat"; /** * If not null, write debug information to this writer. */ private PrintWriter fDebugWriter = null; /** * XCatalog catalog and entity resolver.. */ private XCatalog fXCatalog = new XCatalog(); /** * List of ClassLoaders use to resolve entities. */ private Vector fClassLoaders = new Vector(); /** * Set a writer used to output debug messages. */ public void setDebugWriter(PrintWriter writer) { fDebugWriter = writer; } /** * Get the debug writer. */ public PrintWriter getDebugWriter() { return fDebugWriter; } /** * Loads a catalog specified by the given input source and * appends the contents to the catalog object. * * @param source The catalog source. * * @exception org.xml.sax.SAXException Throws exception on SAX error. * @exception java.io.IOException Throws exception on i/o error. */ public void loadCatalog(InputSource source) throws SAXException, IOException { if (fDebugWriter != null) { fDebugWriter.println("loadCatalog(" + InputSourceOps.getName(source) + ")"); } // Check for catalog on the CLASSPATH InputSource loadSource = searchClassPath(source); if (loadSource == null) { loadSource = source; } if (fDebugWriter != null) { fDebugWriter.println("loading catalog from(" + InputSourceOps.getName(loadSource) + ")"); } fXCatalog.loadCatalog(loadSource); } /** * Load the default entity catalog and enable loading entities the * classloader for the classloader that loaded this class. */ public void setDefaultResolving() throws SAXException, IOException { // JDeveloper JVM doesn't correctly return system class loader // if it loaded this class, so we do it explictly. ClassLoader classLoader = XMLEntityResolver.class.getClassLoader(); if (classLoader == null) { classLoader = ClassLoader.getSystemClassLoader(); } addClassLoader(classLoader); loadCatalog(new InputSource(DEFAULT_ENTITY_CATALOG)); // Check for optional default catalog InputSource optSource = searchClassPath(LUTRIS_ENTITY_CATALOG); if (optSource != null) { loadCatalog(optSource); } } /** * Adds a public to system identifier mapping. * * @param publicId The public identifier, or "key". * @param systemId The system identifier, or "value". */ public void addPublicMapping(String publicId, String systemId) { fXCatalog.addPublicMapping(publicId, systemId); } /** * Removes a public identifier mapping. * * @param publicId The public identifier to remove. */ public void removePublicMapping(System publicId) { fXCatalog.removePublicMapping(publicId); } /** Returns an enumeration of public identifier mapping keys. */ public Enumeration getPublicMappingKeys() { return fXCatalog.getPublicMappingKeys(); } /** * Returns a public identifier mapping. * * @param publicId The public identifier, or "key". * * @return Returns the system identifier value or null if there * is no mapping defined. */ public String getPublicMapping(String publicId) { return fXCatalog.getPublicMapping(publicId); } /** * Adds a system identifier alias. * * @param publicId The system identifier "key". * @param systemId The system identifier "value". */ public void addSystemMapping(String systemId1, String systemId2) { fXCatalog.addSystemMapping(systemId1, systemId2); } /** * Removes a system identifier alias. * * @param systemId The system identifier to remove. */ public void removeSystemMapping(String systemId) { fXCatalog.removeSystemMapping(systemId); } /** Returns an enumeration of system identifier mapping keys. */ public Enumeration getSystemMappingKeys() { return fXCatalog.getSystemMappingKeys(); } /** * Returns a system identifier alias. * * @param systemId The system identifier "key". * * @return Returns the system identifier alias value or null if there * is no alias defined. */ public String getSystemMapping(String systemId) { return fXCatalog.getSystemMapping(systemId); } /** * Add a classloader to the end of the order list of classloaders to * search for entities. */ public void addClassLoader(ClassLoader classLoader) { fClassLoaders.add(classLoader); } /** * Get an enumeration of the class loaders. */ public Enumeration getClassLoaders() { return fClassLoaders.elements(); } /** * Attempt to load a systemId from a classloader. */ private InputSource loadFromClassLoader(ClassLoader loader, String resourceId) throws IOException { // Drop leading `/' from path. if (resourceId.startsWith("/")) { resourceId = resourceId.substring(1); } InputStream in = loader.getResourceAsStream(resourceId); if (in != null) { return new ClosingInputSource(in); } else { return null; } } /** * Determine if a a system id is a CLASSPATH URL. */ private boolean isClassPathURL(String systemId) { return ((systemId != null) && systemId.startsWith(CLASSPATH_PROTOCOL_PREFIX)); } /** * Get the file name from a CLASSPATH URL. */ private String parseClassPathURL(String url) { return url.substring(CLASSPATH_PROTOCOL_PREFIX.length()); } /** * Attempt to load a systemId from a classpath. Will return an * InputSource with a contained byte stream (doesn't need closed). If * systemId is null or dosen't have the file: protocal, then null is * returned. */ private InputSource searchClassPath(String systemId) throws IOException { InputSource source = null; if ((systemId != null) && isClassPathURL(systemId)) { String resourceName = parseClassPathURL(systemId); int len = fClassLoaders.size(); for (int idx = 0; (idx < len) && (source == null); idx++) { source = loadFromClassLoader((ClassLoader)fClassLoaders.get(idx), resourceName); } if (source != null) { source.setSystemId(systemId); } } if (fDebugWriter != null) { fDebugWriter.println("Entity " + ((source == null) ? "not " : "") + "found searching " + fClassLoaders.size() + " class loader(s): " + systemId + " => " + InputSourceOps.getName(source)); } return source; } /** * @see #searchClassPath#String */ private InputSource searchClassPath(InputSource source) throws IOException { if ((source.getByteStream() != null) || (source.getCharacterStream() != null)) { return null; // Already open. } else { return searchClassPath(source.getSystemId()); } } /** * @see org.xml.sax.EntityResolver */ public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { if (fDebugWriter != null) { fDebugWriter.println("resolveEntity(" + publicId + ", " + systemId + ")"); } InputSource source; InputSource catalogSource = fXCatalog.resolveEntity(publicId, systemId); if (catalogSource != null) { if (fDebugWriter != null) { fDebugWriter.println("XMLCatalog maps entity to: " + catalogSource.getSystemId()); // } source = searchClassPath(catalogSource); if (source == null) { source = catalogSource; // Use unchanged. } } else { source = searchClassPath(systemId); } if (fDebugWriter != null) { fDebugWriter.println("Resolved: " + InputSourceOps.getName(source)); } return source; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy