FileDocCategorySizeDatePackage
ListingErrorHandler.javaAPI DocJava SE 6 API18961Tue Jun 10 00:23:10 BST 2008com.sun.org.apache.xml.internal.utils

ListingErrorHandler

public class ListingErrorHandler extends Object implements ErrorListener, ErrorHandler
Sample implementation of similar SAX ErrorHandler and JAXP ErrorListener.

This implementation is suitable for various use cases, and provides some basic configuration API's as well to control when we re-throw errors, etc.

author
shane_curcuru@us.ibm.com
version
$Id: ListingErrorHandler.java,v 1.2.4.1 2005/09/15 08:15:46 suresh_emailid Exp $
xsl.usage
general

Fields Summary
protected PrintWriter
m_pw
protected boolean
throwOnWarning
If we should throw exception on warnings; default:false.
protected boolean
throwOnError
If we should throw exception on errors; default:true.
protected boolean
throwOnFatalError
If we should throw exception on fatalErrors; default:true.
Constructors Summary
public ListingErrorHandler(PrintWriter pw)
Constructor ListingErrorHandler; user-supplied PrintWriter.

  

               
      
    
        if (null == pw)
            throw new NullPointerException(XMLMessages.createXMLMessage(XMLErrorResources.ER_ERRORHANDLER_CREATED_WITH_NULL_PRINTWRITER, null));
            // "ListingErrorHandler created with null PrintWriter!");
            
        m_pw = pw;
    
public ListingErrorHandler()
Constructor ListingErrorHandler; uses System.err.

        m_pw = new PrintWriter(System.err, true);
    
Methods Summary
public voiderror(org.xml.sax.SAXParseException exception)
Receive notification of a recoverable error.

This corresponds to the definition of "error" in section 1.2 of the W3C XML 1.0 Recommendation. For example, a validating parser would use this callback to report the violation of a validity constraint. The default behaviour is to take no action.

The SAX parser must continue to provide normal parsing events after invoking this method: it should still be possible for the application to process the document through to the end. If the application cannot do so, then the parser should report a fatal error even if the XML 1.0 recommendation does not require it to do so.

Filters may use this method to report other, non-XML errors as well.

param
exception The error information encapsulated in a SAX parse exception.
exception
org.xml.sax.SAXException Any SAX exception, possibly wrapping another exception; only if setThrowOnErroris true.
see
org.xml.sax.SAXParseException

    	logExceptionLocation(m_pw, exception);
        m_pw.println("error: " + exception.getMessage());
        m_pw.flush();

        if (getThrowOnError())
            throw exception;
    
public voiderror(javax.xml.transform.TransformerException exception)
Receive notification of a recoverable error.

The transformer must continue to try and provide normal transformation after invoking this method. It should still be possible for the application to process the document through to the end if no other errors are encountered.

param
exception The error information encapsulated in a transformer exception.
throws
javax.xml.transform.TransformerException only if setThrowOnError is true.
see
javax.xml.transform.TransformerException

    	logExceptionLocation(m_pw, exception);
        m_pw.println("error: " + exception.getMessage());
        m_pw.flush();

        if (getThrowOnError())
            throw exception;
    
public voidfatalError(org.xml.sax.SAXParseException exception)
Receive notification of a non-recoverable error.

This corresponds to the definition of "fatal error" in section 1.2 of the W3C XML 1.0 Recommendation. For example, a parser would use this callback to report the violation of a well-formedness constraint.

The application must assume that the document is unusable after the parser has invoked this method, and should continue (if at all) only for the sake of collecting addition error messages: in fact, SAX parsers are free to stop reporting any other events once this method has been invoked.

param
exception The error information encapsulated in a SAX parse exception.
exception
org.xml.sax.SAXException Any SAX exception, possibly wrapping another exception; only if setThrowOnFatalError is true.
see
org.xml.sax.SAXParseException

    	logExceptionLocation(m_pw, exception);
        m_pw.println("fatalError: " + exception.getMessage());
        m_pw.flush();

        if (getThrowOnFatalError())
            throw exception;
    
public voidfatalError(javax.xml.transform.TransformerException exception)
Receive notification of a non-recoverable error.

The transformer must continue to try and provide normal transformation after invoking this method. It should still be possible for the application to process the document through to the end if no other errors are encountered, but there is no guarantee that the output will be useable.

param
exception The error information encapsulated in a transformer exception.
throws
javax.xml.transform.TransformerException only if setThrowOnError is true.
see
javax.xml.transform.TransformerException

    	logExceptionLocation(m_pw, exception);
        m_pw.println("error: " + exception.getMessage());
        m_pw.flush();

        if (getThrowOnError())
            throw exception;
    
protected static java.lang.StringgetSourceLine(java.lang.String sourceUrl, int lineNum)
Return the specific source line that caused the exception, if possible to load it; allow exceptions to be thrown.

author
shane_curcuru@us.ibm.com

        URL url = null;
        // Get a URL from the sourceUrl
        try
        {
            // Try to get a URL from it as-is
            url = new URL(sourceUrl);
        }
        catch (java.net.MalformedURLException mue)
        {
            int indexOfColon = sourceUrl.indexOf(':");
            int indexOfSlash = sourceUrl.indexOf('/");
            
            if ((indexOfColon != -1)
                && (indexOfSlash != -1)
                && (indexOfColon < indexOfSlash))
            {
                // The url is already absolute, but we could not get 
                //  the system to form it, so bail
                throw mue;
            }
            else
            {
                // The url is relative, so attempt to get absolute
                url = new URL(SystemIDResolver.getAbsoluteURI(sourceUrl));
                // If this fails, allow the exception to propagate
            }
        }
        
        String line = null;
        InputStream is = null;
        BufferedReader br = null;
        try
        {
            // Open the URL and read to our specified line
            URLConnection uc = url.openConnection();
            is = uc.getInputStream();
            br = new BufferedReader(new InputStreamReader(is));

            // Not the most efficient way, but it works
            // (Feel free to patch to seek to the appropriate line)
            for (int i = 1; i <= lineNum; i++)
            {
                line = br.readLine();
            }
            
        } 
        // Allow exceptions to propagate from here, but ensure 
        //  streams are closed!
        finally
        {
            br.close();
            is.close();
        }
        
        // Return whatever we found
        return line;
    
public booleangetThrowOnError()
User-settable behavior: when to re-throw exceptions.

return
if we throw an exception on errors

        return throwOnError;
    
public booleangetThrowOnFatalError()
User-settable behavior: when to re-throw exceptions.

return
if we throw an exception on fatalErrors

        return throwOnFatalError;
    
public booleangetThrowOnWarning()
User-settable behavior: when to re-throw exceptions.

return
if we throw an exception on warnings

        return throwOnWarning;
    
public static voidlogExceptionLocation(java.io.PrintWriter pw, java.lang.Throwable exception)
Print out location information about the exception. Cribbed from DefaultErrorHandler.printLocation()

param
pw PrintWriter to send output to
param
exception TransformerException or SAXParseException to log information about

        if (null == pw)
            pw = new PrintWriter(System.err, true);
        
        SourceLocator locator = null;
        Throwable cause = exception;

        // Try to find the locator closest to the cause.
        do
        {
            // Find the current locator, if one present
            if(cause instanceof SAXParseException)
            {
                // A SAXSourceLocator is a Xalan helper class 
                //  that implements both a SourceLocator and a SAX Locator
                //@todo check that the new locator actually has 
                //  as much or more information as the 
                //  current one already does
                locator = new SAXSourceLocator((SAXParseException)cause);
            }
            else if (cause instanceof TransformerException)
            {
                SourceLocator causeLocator = ((TransformerException)cause).getLocator();
                if(null != causeLocator)
                {
                    locator = causeLocator;
                }
            }
            
            // Then walk back down the chain of exceptions
            if(cause instanceof TransformerException)
                cause = ((TransformerException)cause).getCause();
            else if(cause instanceof WrappedRuntimeException)
                cause = ((WrappedRuntimeException)cause).getException();
            else if(cause instanceof SAXException)
                cause = ((SAXException)cause).getException();
            else
                cause = null;
        }
        while(null != cause);

        // Formatting note: mimic javac-like errors:
        //  path\filename:123: message-here
        //  systemId:L=1;C=2: message-here
        if(null != locator)
        {
            String id = (locator.getPublicId() != locator.getPublicId())
                      ? locator.getPublicId()
                        : (null != locator.getSystemId())
                          ? locator.getSystemId() : "SystemId-Unknown";

            pw.print(id + ":Line=" + locator.getLineNumber()
                             + ";Column=" + locator.getColumnNumber()+": ");
            pw.println("exception:" + exception.getMessage());
            pw.println("root-cause:" 
                       + ((null != cause) ? cause.getMessage() : "null"));
            logSourceLine(pw, locator); 
        }
        else
        {
            pw.print("SystemId-Unknown:locator-unavailable: ");
            pw.println("exception:" + exception.getMessage());
            pw.println("root-cause:" 
                       + ((null != cause) ? cause.getMessage() : "null"));
        }
    
public static voidlogSourceLine(java.io.PrintWriter pw, javax.xml.transform.SourceLocator locator)
Print out the specific source line that caused the exception, if possible to load it.

param
pw PrintWriter to send output to
param
locator Xalan wrapper for either a JAXP or a SAX source location object

        if (null == locator)
            return;
            
        if (null == pw)
            pw = new PrintWriter(System.err, true);

        String url = locator.getSystemId();
        // Bail immediately if we get SystemId-Unknown
        //@todo future improvement: attempt to get resource 
        //  from a publicId if possible
        if (null == url)
        {
            pw.println("line: (No systemId; cannot read file)");
            pw.println();
            return;
        }
        
        //@todo attempt to get DOM backpointer or other ids

        try
        {
            int line = locator.getLineNumber();
            int column = locator.getColumnNumber();
            pw.println("line: " + getSourceLine(url, line));
            StringBuffer buf = new StringBuffer("line: ");
            for (int i = 1; i < column; i++)
            {
                buf.append(' ");
            }
            buf.append('^");
            pw.println(buf.toString());
        }
        catch (Exception e)
        {
            pw.println("line: logSourceLine unavailable due to: " + e.getMessage());
            pw.println();
        }
    
public voidsetThrowOnError(boolean b)
User-settable behavior: when to re-throw exceptions.

This allows per-instance configuration of ListingErrorHandlers. You can ask us to either throw an exception when we're called for various warning / error / fatalErrors, or simply log them and continue.

Note that the behavior of many parsers/transformers after an error is not necessarily defined!

param
b if we should throw an exception on errors



                                                                             
       
    
        throwOnError = b;
    
public voidsetThrowOnFatalError(boolean b)
User-settable behavior: when to re-throw exceptions.

This allows per-instance configuration of ListingErrorHandlers. You can ask us to either throw an exception when we're called for various warning / error / fatalErrors, or simply log them and continue.

Note that the behavior of many parsers/transformers after a fatalError is not necessarily defined, most products will probably barf if you continue.

param
b if we should throw an exception on fatalErrors



                                                                                      
       
    
        throwOnFatalError = b;
    
public voidsetThrowOnWarning(boolean b)
User-settable behavior: when to re-throw exceptions.

This allows per-instance configuration of ListingErrorHandlers. You can ask us to either throw an exception when we're called for various warning / error / fatalErrors, or simply log them and continue.

param
b if we should throw an exception on warnings

        throwOnWarning = b;
    
public voidwarning(org.xml.sax.SAXParseException exception)
Receive notification of a warning.

SAX parsers will use this method to report conditions that are not errors or fatal errors as defined by the XML 1.0 recommendation. The default behaviour is to take no action.

The SAX parser must continue to provide normal parsing events after invoking this method: it should still be possible for the application to process the document through to the end.

Filters may use this method to report other, non-XML warnings as well.

param
exception The warning information encapsulated in a SAX parse exception.
exception
org.xml.sax.SAXException Any SAX exception, possibly wrapping another exception; only if setThrowOnWarning is true.
see
org.xml.sax.SAXParseException

    	logExceptionLocation(m_pw, exception);
        // Note: should we really call .toString() below, since 
        //  sometimes the message is not properly set?
        m_pw.println("warning: " + exception.getMessage());
        m_pw.flush();

        if (getThrowOnWarning())
            throw exception;
    
public voidwarning(javax.xml.transform.TransformerException exception)
Receive notification of a warning.

{@link javax.xml.transform.Transformer} can use this method to report conditions that are not errors or fatal errors. The default behaviour is to take no action.

After invoking this method, the Transformer must continue with the transformation. It should still be possible for the application to process the document through to the end.

param
exception The warning information encapsulated in a transformer exception.
throws
javax.xml.transform.TransformerException only if setThrowOnWarning is true.
see
javax.xml.transform.TransformerException

    	logExceptionLocation(m_pw, exception);
        m_pw.println("warning: " + exception.getMessage());
        m_pw.flush();

        if (getThrowOnWarning())
            throw exception;