private static EntityResolver getResolver() { EntityResolver resolver = null; if (resolver == null) { // set up a manager CatalogManager manager = new CatalogManager(); manager.setIgnoreMissingProperties(true); try { // if(System.getProperty(getClass().getName()+".verbose")!=null) manager.setVerbosity(0); } catch (SecurityException e) { // recover by not setting the debug flag. } // parse the catalog ClassLoader cl = Thread.currentThread().getContextClassLoader(); Enumeration catalogEnum; try { if (cl == null) catalogEnum = ClassLoader.getSystemResources("/META-INF/jaxws-catalog.xml"); else catalogEnum = cl.getResources("/META-INF/jaxws-catalog.xml"); while (catalogEnum.hasMoreElements()) { URL url = (URL) catalogEnum.nextElement(); manager.getCatalog().parseCatalog(url); } } catch (IOException e) { e.printStackTrace(); } resolver = new CatalogResolver(manager); } return resolver; }
/** Adds a new catalog file. */ public void addCatalog(File catalogFile) throws IOException { if (entityResolver == null) { CatalogManager.getStaticManager().setIgnoreMissingProperties(true); entityResolver = new CatalogResolver(true); } ((CatalogResolver) entityResolver).getCatalog().parseCatalog(catalogFile.getPath()); }
/** * SAX ContentHandler API. * * <p>Detect and use the oasis-xml-catalog PI if it occurs. */ public void processingInstruction(String target, String pidata) throws SAXException { if (target.equals("oasis-xml-catalog")) { URL catalog = null; String data = pidata; int pos = data.indexOf("catalog="); if (pos >= 0) { data = data.substring(pos + 8); if (data.length() > 1) { String quote = data.substring(0, 1); data = data.substring(1); pos = data.indexOf(quote); if (pos >= 0) { data = data.substring(0, pos); try { if (baseURL != null) { catalog = new URL(baseURL, data); } else { catalog = new URL(data); } } catch (MalformedURLException mue) { // nevermind } } } } if (allowXMLCatalogPI) { if (catalogManager.getAllowOasisXMLCatalogPI()) { catalogManager.debug.message(4, "oasis-xml-catalog PI", pidata); if (catalog != null) { try { catalogManager.debug.message(4, "oasis-xml-catalog", catalog.toString()); oasisXMLCatalogPI = true; if (piCatalogResolver == null) { piCatalogResolver = new CatalogResolver(true); } piCatalogResolver.getCatalog().parseCatalog(catalog.toString()); } catch (Exception e) { catalogManager.debug.message( 3, "Exception parsing oasis-xml-catalog: " + catalog.toString()); } } else { catalogManager.debug.message(3, "PI oasis-xml-catalog unparseable: " + pidata); } } else { catalogManager.debug.message(4, "PI oasis-xml-catalog ignored: " + pidata); } } else { catalogManager.debug.message( 3, "PI oasis-xml-catalog occurred in an invalid place: " + pidata); } } else { super.processingInstruction(target, pidata); } }
/** * Initialization. Create a CatalogManager and set all the properties upfront. This prevents JVM * wide system properties or a property file somewhere in the environment from affecting the * behaviour of this catalog resolver. */ private void init(String[] catalogs, boolean preferPublic) { fCatalogsList = (catalogs != null) ? (String[]) catalogs.clone() : null; fPreferPublic = preferPublic; fResolverCatalogManager = new CatalogManager(); fResolverCatalogManager.setAllowOasisXMLCatalogPI(false); fResolverCatalogManager.setCatalogClassName("com.sun.org.apache.xml.internal.resolver.Catalog"); fResolverCatalogManager.setCatalogFiles(""); fResolverCatalogManager.setIgnoreMissingProperties(true); fResolverCatalogManager.setPreferPublic(fPreferPublic); fResolverCatalogManager.setRelativeCatalogs(false); fResolverCatalogManager.setUseStaticCatalog(false); fResolverCatalogManager.setVerbosity(0); }
/** * A SAX XMLFilter that performs catalog-based entity resolution. * * <p>This class implements a SAX XMLFilter that performs entity resolution using the * CatalogResolver. The actual, underlying parser is obtained from a SAXParserFactory. * * @see CatalogResolver * @see org.xml.sax.XMLFilter * @author Norman Walsh <a href="mailto:[email protected]">[email protected]</a> */ public class ResolvingXMLFilter extends XMLFilterImpl { /** * Suppress explanatory message? * * @see #parse(InputSource) */ public static boolean suppressExplanation = false; /** The manager for the underlying resolver. */ private CatalogManager catalogManager = CatalogManager.getStaticManager(); /** The underlying catalog resolver. */ private CatalogResolver catalogResolver = null; /** A separate resolver for oasis-xml-pi catalogs. */ private CatalogResolver piCatalogResolver = null; /** Are we in the prolog? Is an oasis-xml-catalog PI valid now? */ private boolean allowXMLCatalogPI = false; /** Has an oasis-xml-catalog PI been seen? */ private boolean oasisXMLCatalogPI = false; /** The base URI of the input document, if known. */ private URL baseURL = null; /** Construct an empty XML Filter with no parent. */ public ResolvingXMLFilter() { super(); catalogResolver = new CatalogResolver(catalogManager); } /** Construct an XML filter with the specified parent. */ public ResolvingXMLFilter(XMLReader parent) { super(parent); catalogResolver = new CatalogResolver(catalogManager); } /** Construct an XML filter with the specified parent. */ public ResolvingXMLFilter(CatalogManager manager) { super(); catalogManager = manager; catalogResolver = new CatalogResolver(catalogManager); } /** Construct an XML filter with the specified parent. */ public ResolvingXMLFilter(XMLReader parent, CatalogManager manager) { super(parent); catalogManager = manager; catalogResolver = new CatalogResolver(catalogManager); } /** Provide accessto the underlying Catalog. */ public Catalog getCatalog() { return catalogResolver.getCatalog(); } /** * SAX XMLReader API. * * <p>Note that the JAXP 1.1ea2 parser crashes with an InternalError if it encounters a system * identifier that appears to be a relative URI that begins with a slash. For example, the * declaration: * * <pre> * <!DOCTYPE book SYSTEM "/path/to/dtd/on/my/system/docbookx.dtd"> * </pre> * * <p>would cause such an error. As a convenience, this method catches that error and prints an * explanation. (Unfortunately, it's not possible to identify the particular system identifier * that causes the problem.) * * <p>The underlying error is forwarded after printing the explanatory message. The message is * only every printed once and if <code>suppressExplanation</code> is set to <code>false</code> * before parsing, it will never be printed. */ public void parse(InputSource input) throws IOException, SAXException { allowXMLCatalogPI = true; setupBaseURI(input.getSystemId()); try { super.parse(input); } catch (InternalError ie) { explain(input.getSystemId()); throw ie; } } /** * SAX XMLReader API. * * @see #parse(InputSource) */ public void parse(String systemId) throws IOException, SAXException { allowXMLCatalogPI = true; setupBaseURI(systemId); try { super.parse(systemId); } catch (InternalError ie) { explain(systemId); throw ie; } } /** * Implements the <code>resolveEntity</code> method for the SAX interface, using an underlying * CatalogResolver to do the real work. */ public InputSource resolveEntity(String publicId, String systemId) { allowXMLCatalogPI = false; String resolved = catalogResolver.getResolvedEntity(publicId, systemId); if (resolved == null && piCatalogResolver != null) { resolved = piCatalogResolver.getResolvedEntity(publicId, systemId); } if (resolved != null) { try { InputSource iSource = new InputSource(resolved); iSource.setPublicId(publicId); // Ideally this method would not attempt to open the // InputStream, but there is a bug (in Xerces, at least) // that causes the parser to mistakenly open the wrong // system identifier if the returned InputSource does // not have a byteStream. // // It could be argued that we still shouldn't do this here, // but since the purpose of calling the entityResolver is // almost certainly to open the input stream, it seems to // do little harm. // URL url = new URL(resolved); InputStream iStream = url.openStream(); iSource.setByteStream(iStream); return iSource; } catch (Exception e) { catalogManager.debug.message(1, "Failed to create InputSource", resolved); return null; } } else { return null; } } /** * SAX DTDHandler API. * * <p>Captured here only to detect the end of the prolog so that we can ignore subsequent * oasis-xml-catalog PIs. Otherwise the events are just passed through. */ public void notationDecl(String name, String publicId, String systemId) throws SAXException { allowXMLCatalogPI = false; super.notationDecl(name, publicId, systemId); } /** * SAX DTDHandler API. * * <p>Captured here only to detect the end of the prolog so that we can ignore subsequent * oasis-xml-catalog PIs. Otherwise the events are just passed through. */ public void unparsedEntityDecl(String name, String publicId, String systemId, String notationName) throws SAXException { allowXMLCatalogPI = false; super.unparsedEntityDecl(name, publicId, systemId, notationName); } /** * SAX ContentHandler API. * * <p>Captured here only to detect the end of the prolog so that we can ignore subsequent * oasis-xml-catalog PIs. Otherwise the events are just passed through. */ public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { allowXMLCatalogPI = false; super.startElement(uri, localName, qName, atts); } /** * SAX ContentHandler API. * * <p>Detect and use the oasis-xml-catalog PI if it occurs. */ public void processingInstruction(String target, String pidata) throws SAXException { if (target.equals("oasis-xml-catalog")) { URL catalog = null; String data = pidata; int pos = data.indexOf("catalog="); if (pos >= 0) { data = data.substring(pos + 8); if (data.length() > 1) { String quote = data.substring(0, 1); data = data.substring(1); pos = data.indexOf(quote); if (pos >= 0) { data = data.substring(0, pos); try { if (baseURL != null) { catalog = new URL(baseURL, data); } else { catalog = new URL(data); } } catch (MalformedURLException mue) { // nevermind } } } } if (allowXMLCatalogPI) { if (catalogManager.getAllowOasisXMLCatalogPI()) { catalogManager.debug.message(4, "oasis-xml-catalog PI", pidata); if (catalog != null) { try { catalogManager.debug.message(4, "oasis-xml-catalog", catalog.toString()); oasisXMLCatalogPI = true; if (piCatalogResolver == null) { piCatalogResolver = new CatalogResolver(true); } piCatalogResolver.getCatalog().parseCatalog(catalog.toString()); } catch (Exception e) { catalogManager.debug.message( 3, "Exception parsing oasis-xml-catalog: " + catalog.toString()); } } else { catalogManager.debug.message(3, "PI oasis-xml-catalog unparseable: " + pidata); } } else { catalogManager.debug.message(4, "PI oasis-xml-catalog ignored: " + pidata); } } else { catalogManager.debug.message( 3, "PI oasis-xml-catalog occurred in an invalid place: " + pidata); } } else { super.processingInstruction(target, pidata); } } /** Save the base URI of the document being parsed. */ private void setupBaseURI(String systemId) { URL cwd = null; try { cwd = FileURL.makeURL("basename"); } catch (MalformedURLException mue) { cwd = null; } try { baseURL = new URL(systemId); } catch (MalformedURLException mue) { if (cwd != null) { try { baseURL = new URL(cwd, systemId); } catch (MalformedURLException mue2) { // give up baseURL = null; } } else { // give up baseURL = null; } } } /** Provide one possible explanation for an InternalError. */ private void explain(String systemId) { if (!suppressExplanation) { System.out.println("XMLReader probably encountered bad URI in " + systemId); System.out.println("For example, replace '/some/uri' with 'file:/some/uri'."); } suppressExplanation = true; } }
/** * Sets the preference for whether system or public matches are preferred. This is used in the * absence of any occurence of the <code>prefer</code> attribute on the <code>catalog</code> entry * of a catalog. * * @param preferPublic the prefer public setting */ public final void setPreferPublic(boolean preferPublic) { fPreferPublic = preferPublic; fResolverCatalogManager.setPreferPublic(preferPublic); }