public InputSource resolveEntity(String publicId,
String systemId) throws SAXException {
try {
InputSource is=null;
// ask the client-specified entity resolver first
if( this.getEntityResolver()!=null)
is = this.getEntityResolver().resolveEntity(publicId,systemId);
if( is!=null ) return is; // if that succeeds, fine.
// rather than returning null, resolve it now
// so that we can detect errors.
is = new InputSource( new URL(systemId).openStream() );
is.setSystemId(systemId);
is.setPublicId(publicId);
return is;
} catch( IOException e ) {
// catch this error and provide a nice error message, rather than
// just throwing this IOException.
SAXParseException spe = new SAXParseException(
Messages.format(Messages.ERR_ENTITY_RESOLUTION_FAILURE,
systemId, e.toString()), // use the toString method to get the class name
locator, e );
if(this.getErrorHandler()!=null)
this.getErrorHandler().fatalError(spe);
throw spe;
}
}
Resolves entities and reports user-friendly error messages.
Some XML parser (at least Xerces) does not report much information
when it fails to resolve an entity, which is often quite
frustrating. For example, if you are behind a firewall and the
schema contains a reference to www.w3.org, and there is no
entity resolver, the parser will just throw an IOException
that doesn't contain any information about where that reference
occurs nor what it is accessing.
By implementing an EntityResolver and resolving the reference
by ourselves, we can report an error message with all the
necessary information to fix the problem.
Note that we still need to the client-specified entity resolver
to let the application handle entity resolution. Here we just catch
an IOException and add more information. |