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

ResolvingParser

public class ResolvingParser extends Object implements DocumentHandler, EntityResolver, DTDHandler, Parser
A SAX Parser that performs catalog-based entity resolution.

This class implements a SAX Parser that performs entity resolution using the CatalogResolver. The actual, underlying parser is obtained from a SAXParserFactory.

deprecated
This interface has been replaced by the {@link com.sun.org.apache.xml.internal.resolver.tools.ResolvingXMLReader} for SAX2.
see
CatalogResolver
see
org.xml.sax.Parser
author
Norman Walsh Norman.Walsh@Sun.COM
version
1.0

Fields Summary
public static boolean
namespaceAware
Make the parser Namespace aware?
public static boolean
validating
Make the parser validating?
public static boolean
suppressExplanation
Suppress explanatory message?
private SAXParser
saxParser
The underlying parser.
private Parser
parser
The underlying reader.
private DocumentHandler
documentHandler
The underlying DocumentHandler.
private DTDHandler
dtdHandler
The underlying DTDHandler.
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 ResolvingParser()
Constructor.


    
    
    initParser();
  
public ResolvingParser(com.sun.org.apache.xml.internal.resolver.CatalogManager manager)
Constructor.

    catalogManager = manager;
    initParser();
  
Methods Summary
public voidcharacters(char[] ch, int start, int length)
SAX DocumentHandler API.

    if (documentHandler != null) {
      documentHandler.characters(ch,start,length);
    }
  
public voidendDocument()
SAX DocumentHandler API.

    if (documentHandler != null) {
      documentHandler.endDocument();
    }
  
public voidendElement(java.lang.String name)
SAX DocumentHandler API.

    if (documentHandler != null) {
      documentHandler.endElement(name);
    }
  
private voidexplain(java.lang.String systemId)
Provide one possible explanation for an InternalError.

    if (!suppressExplanation) {
      System.out.println("Parser probably encountered bad URI in " + systemId);
      System.out.println("For example, replace '/some/uri' with 'file:/some/uri'.");
    }
  
public com.sun.org.apache.xml.internal.resolver.CataloggetCatalog()
Return the Catalog being used.

    return catalogResolver.getCatalog();
  
public voidignorableWhitespace(char[] ch, int start, int length)
SAX DocumentHandler API.

    if (documentHandler != null) {
      documentHandler.ignorableWhitespace(ch,start,length);
    }
  
private voidinitParser()
Initialize the parser.

    catalogResolver = new CatalogResolver(catalogManager);

    SAXParserFactory spf = SAXParserFactory.newInstance();
    spf.setNamespaceAware(namespaceAware);
    spf.setValidating(validating);

    try {
      saxParser = spf.newSAXParser();
      parser = saxParser.getParser();
      documentHandler = null;
      dtdHandler = null;
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  
public voidnotationDecl(java.lang.String name, java.lang.String publicId, java.lang.String systemId)
SAX DTDHandler API.

    allowXMLCatalogPI = false;
    if (dtdHandler != null) {
      dtdHandler.notationDecl(name,publicId,systemId);
    }
  
public voidparse(org.xml.sax.InputSource input)
SAX Parser 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.

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

see
#parse(InputSource)

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


    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 {
      if (documentHandler != null) {
	documentHandler.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;
    }
  
public voidsetDTDHandler(org.xml.sax.DTDHandler handler)
SAX Parser API.

    dtdHandler = handler;
  
public voidsetDocumentHandler(org.xml.sax.DocumentHandler handler)
SAX Parser API.

    documentHandler = handler;
  
public voidsetDocumentLocator(org.xml.sax.Locator locator)
SAX DocumentHandler API.

    if (documentHandler != null) {
      documentHandler.setDocumentLocator(locator);
    }
  
public voidsetEntityResolver(org.xml.sax.EntityResolver resolver)
SAX Parser API.

The purpose of this class is to implement an entity resolver. Attempting to set a different one is pointless (and ignored).

    // nop
  
public voidsetErrorHandler(org.xml.sax.ErrorHandler handler)
SAX Parser API.

    parser.setErrorHandler(handler);
  
public voidsetLocale(java.util.Locale locale)
SAX Parser API.

    parser.setLocale(locale);
  
private voidsetupParse(java.lang.String systemId)
Setup for parsing.

    allowXMLCatalogPI = true;
    parser.setEntityResolver(this);
    parser.setDocumentHandler(this);
    parser.setDTDHandler(this);

    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 voidstartDocument()
SAX DocumentHandler API.

    if (documentHandler != null) {
      documentHandler.startDocument();
    }
  
public voidstartElement(java.lang.String name, org.xml.sax.AttributeList atts)
SAX DocumentHandler API.

    allowXMLCatalogPI = false;
    if (documentHandler != null) {
      documentHandler.startElement(name,atts);
    }
  
public voidunparsedEntityDecl(java.lang.String name, java.lang.String publicId, java.lang.String systemId, java.lang.String notationName)
SAX DTDHandler API.

    allowXMLCatalogPI = false;
    if (dtdHandler != null) {
      dtdHandler.unparsedEntityDecl (name, publicId, systemId, notationName);
    }