FileDocCategorySizeDatePackage
ResolvingXMLFilter.javaAPI DocJava SE 6 API10260Tue Jun 10 00:23:00 BST 2008com.sun.org.apache.xml.internal.resolver.tools

ResolvingXMLFilter

public class ResolvingXMLFilter extends XMLFilterImpl
A SAX XMLFilter that performs catalog-based entity resolution.

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 Norman.Walsh@Sun.COM
version
1.0

Fields Summary
public static boolean
suppressExplanation
Suppress explanatory message?
private com.sun.org.apache.xml.internal.resolver.CatalogManager
catalogManager
The manager for the underlying resolver.
private CatalogResolver
catalogResolver
The underlying catalog resolver.
private CatalogResolver
piCatalogResolver
A separate resolver for oasis-xml-pi catalogs.
private boolean
allowXMLCatalogPI
Are we in the prolog? Is an oasis-xml-catalog PI valid now?
private boolean
oasisXMLCatalogPI
Has an oasis-xml-catalog PI been seen?
private URL
baseURL
The base URI of the input document, if known.
Constructors Summary
public ResolvingXMLFilter()
Construct an empty XML Filter with no parent.


           
    
    super();
    catalogResolver = new CatalogResolver(catalogManager);
  
public ResolvingXMLFilter(XMLReader parent)
Construct an XML filter with the specified parent.

    super(parent);
    catalogResolver = new CatalogResolver(catalogManager);
  
public ResolvingXMLFilter(com.sun.org.apache.xml.internal.resolver.CatalogManager manager)
Construct an XML filter with the specified parent.

    super();
    catalogManager = manager;
    catalogResolver = new CatalogResolver(catalogManager);
  
public ResolvingXMLFilter(XMLReader parent, com.sun.org.apache.xml.internal.resolver.CatalogManager manager)
Construct an XML filter with the specified parent.

    super(parent);
    catalogManager = manager;
    catalogResolver = new CatalogResolver(catalogManager);
  
Methods Summary
private voidexplain(java.lang.String systemId)
Provide one possible explanation for an InternalError.

    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;
  
public com.sun.org.apache.xml.internal.resolver.CataloggetCatalog()
Provide accessto the underlying Catalog.

    return catalogResolver.getCatalog();
  
public voidnotationDecl(java.lang.String name, java.lang.String publicId, java.lang.String systemId)
SAX DTDHandler API.

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.

    allowXMLCatalogPI = false;
    super.notationDecl(name,publicId,systemId);
  
public voidparse(org.xml.sax.InputSource input)
SAX XMLReader API.

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:

<!DOCTYPE book SYSTEM "/path/to/dtd/on/my/system/docbookx.dtd">

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.)

The underlying error is forwarded after printing the explanatory message. The message is only every printed once and if suppressExplanation is set to false before parsing, it will never be printed.

    allowXMLCatalogPI = true;

    setupBaseURI(input.getSystemId());

    try {
      super.parse(input);
    } catch (InternalError ie) {
      explain(input.getSystemId());
      throw ie;
    }
  
public voidparse(java.lang.String systemId)
SAX XMLReader API.

see
#parse(InputSource)

    allowXMLCatalogPI = true;

    setupBaseURI(systemId);

    try {
      super.parse(systemId);
    } catch (InternalError ie) {
      explain(systemId);
      throw ie;
    }
  
public voidprocessingInstruction(java.lang.String target, java.lang.String pidata)
SAX ContentHandler API.

Detect and use the oasis-xml-catalog PI if it occurs.

    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);
    }
  
public org.xml.sax.InputSourceresolveEntity(java.lang.String publicId, java.lang.String systemId)
Implements the resolveEntity method for the SAX interface, using an underlying CatalogResolver to do the real work.

    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;
    }
  
private voidsetupBaseURI(java.lang.String systemId)
Save the base URI of the document being parsed.

    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;
      }
    }
  
public voidstartElement(java.lang.String uri, java.lang.String localName, java.lang.String qName, org.xml.sax.Attributes atts)
SAX ContentHandler API.

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.

    allowXMLCatalogPI = false;
    super.startElement(uri,localName,qName,atts);
  
public voidunparsedEntityDecl(java.lang.String name, java.lang.String publicId, java.lang.String systemId, java.lang.String notationName)
SAX DTDHandler API.

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.

    allowXMLCatalogPI = false;
    super.unparsedEntityDecl (name, publicId, systemId, notationName);