/* * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is the Kowari Metadata Store. * * The Initial Developer of the Original Code is Plugged In Software Pty * Ltd (http://www.pisoftware.com, mailto:info@pisoftware.com). Portions * created by Plugged In Software Pty Ltd are Copyright (C) 2001,2002 * Plugged In Software Pty Ltd. All Rights Reserved. * * Contributor(s): N/A. * * [NOTE: The text of this Exhibit A may differ slightly from the text * of the notices in the Source Code files of the Original Code. You * should use the text of this Exhibit A rather than the text found in the * Original Code Source Code for Your Modifications.] * */ package org.mulgara.descriptor; import java.io.PrintStream; import java.io.PrintWriter; import java.lang.reflect.Method; import javax.xml.transform.*; import org.apache.log4j.Logger; import org.xml.sax.*; import org.xml.sax.helpers.LocatorImpl; /** * <meta name="usage" content="general"/> Implement SAX error handler for * default reporting. * * @created 2002-03-15 * * @author Keith Ahern * * @version $Revision: 1.8 $ * * @modified $Date: 2005/01/05 04:58:11 $ * * @maintenanceAuthor $Author: newmana $ * * @company <A href="mailto:info@PIsoftware.com">Plugged In Software</A> * * @copyright © 2001-2003 <A href="http://www.PIsoftware.com/">Plugged In * Software Pty Ltd</A> * * @licence <a href="{@docRoot}/../../LICENCE">Mozilla Public License v1.1</a> */ public class PIErrorHandler implements ErrorHandler, ErrorListener { /** * Get line separator. */ private static final String eol = System.getProperty("line.separator"); /** * Description of the Field */ @SuppressWarnings("unused") private static final Logger log = Logger.getLogger("XALAN"); /** * Description of the Field */ PrintWriter m_pw; /** * Constructor DefaultErrorHandler * * @param pw PARAMETER TO DO */ public PIErrorHandler(PrintWriter pw) { m_pw = pw; } /** * Constructor DefaultErrorHandler * * @param pw PARAMETER TO DO */ public PIErrorHandler(PrintStream pw) { m_pw = new PrintWriter(pw, true); } /** * Constructor DefaultErrorHandler * */ public PIErrorHandler() { m_pw = new PrintWriter(System.err, true); } /** * METHOD TO DO * * @param exception PARAMETER TO DO */ public static void ensureLocationSet(TransformerException exception) { // SourceLocator locator = exception.getLocator(); SourceLocator locator = null; Throwable cause = exception; // Try to find the locator closest to the cause. do { if (cause instanceof SAXParseException) { locator = new ComboLocator( (SAXParseException) cause); } else if (cause instanceof TransformerException) { SourceLocator causeLocator = ( (TransformerException) cause).getLocator(); if (null != causeLocator) { locator = causeLocator; } } if (cause instanceof TransformerException) { cause = ( (TransformerException) cause).getCause(); } else if (cause instanceof SAXException) { cause = ( (SAXException) cause).getException(); } else { cause = null; } } while (null != cause); exception.setLocator(locator); } /** * Receive notification of a warning. <p> * * 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.</p> <p> * * 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.</p> * * @param exception The warning information encapsulated in a SAX parse * exception. * @throws SAXException Any SAX exception, possibly wrapping another * exception. */ public void warning(SAXParseException exception) throws SAXException { printLocation(m_pw, exception); } /** * Receive notification of a recoverable error. <p> * * 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.</p> <p> * * 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.</p> * * @param exception The error information encapsulated in a SAX parse * exception. * @throws SAXException Any SAX exception, possibly wrapping another * exception. */ public void error(SAXParseException exception) throws SAXException { printLocation(m_pw, exception); throw exception; } /** * Receive notification of a non-recoverable error. <p> * * 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.</p> <p> * * 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.</p> * * @param exception The error information encapsulated in a SAX parse * exception. * @throws SAXException Any SAX exception, possibly wrapping another * exception. */ public void fatalError(SAXParseException exception) throws SAXException { printLocation(m_pw, exception); throw exception; } /** * Receive notification of a warning. <p> * * 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.</p> <p> * * 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.</p> * * @param exception The warning information encapsulated in a SAX parse * exception. * @throws javax.xml.transform.TransformerException Any SAX exception, * possibly wrapping another exception. * @see javax.xml.transform.TransformerException * @throws TransformerException EXCEPTION TO DO */ public void warning(TransformerException exception) throws TransformerException { printLocation(m_pw, exception); } /** * Receive notification of a recoverable error. <p> * * 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.</p> <p> * * 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.</p> * * @param exception The error information encapsulated in a SAX parse * exception. * @throws javax.xml.transform.TransformerException Any SAX exception, * possibly wrapping another exception. * @see javax.xml.transform.TransformerException * @throws TransformerException EXCEPTION TO DO */ public void error(TransformerException exception) throws TransformerException { printLocation(m_pw, exception); throw exception; } /** * Receive notification of a non-recoverable error. <p> * * 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.</p> <p> * * 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.</p> * * @param exception The error information encapsulated in a SAX parse * exception. * @throws javax.xml.transform.TransformerException Any SAX exception, * possibly wrapping another exception. * @see javax.xml.transform.TransformerException * @throws TransformerException EXCEPTION TO DO */ public void fatalError(TransformerException exception) throws TransformerException { printLocation(m_pw, exception); throw exception; } /** * METHOD TO DO * * @param pw PARAMETER TO DO * @param exception PARAMETER TO DO */ public void printLocation(PrintStream pw, TransformerException exception) { printLocation(new PrintWriter(pw), exception); } /** * METHOD TO DO * * @param pw PARAMETER TO DO * @param exception PARAMETER TO DO */ public void printLocation(java.io.PrintStream pw, org.xml.sax.SAXParseException exception) { printLocation(new PrintWriter(pw), exception); } /** * Print location of error to several destinations including log files, files * and console. * * @param pw PARAMETER TO DO * @param exception PARAMETER TO DO */ public void printLocation(PrintWriter pw, Throwable exception) { // writes out stack trace Descriptor.writeStackTrace(exception, "XALAN ERROR"); // Try to find the locator closest to the cause. SourceLocator locator = null; Throwable cause = exception; do { if (cause instanceof SAXParseException) { locator = new ComboLocator( (SAXParseException) cause); } else if (cause instanceof TransformerException) { SourceLocator causeLocator = ( (TransformerException) cause).getLocator(); if (null != causeLocator) { locator = causeLocator; } } if (cause instanceof TransformerException) { cause = ( (TransformerException) cause).getCause(); } else { cause = getWrappedException(cause); } } while (null != cause); if (null != locator) { String id = (locator.getPublicId() != null) ? locator.getPublicId() : ( (null != locator.getSystemId()) ? locator.getSystemId() : "SystemId Unknown"); m_pw.print(id + "; Line " + locator.getLineNumber() + "; Column " + locator.getColumnNumber() + "; "); } else { m_pw.print("(Location of error unknown)"); } // Write Cause stack to decsriptor log file m_pw.println("Cause: " + exception.getMessage()); // reset cause to top level cause cause = exception.getCause(); while (cause != null) { // get Cause Exception String cname = cause.getClass().getName(); // get Message String message = cause.getMessage(); // fix up message if null message = (message == null) ? "No Exception Message" : message; m_pw.println("which was caused by:"); m_pw.println("(" + cname + ") " + message); // go again cause = cause.getCause(); } // write pointer to stack output m_pw.println(eol + "Full Stack Trace in file " + Descriptor.DESCRIPTOR_STACKTRACE_OUTPUT + " in directory where Mulgara was started from"); } /** * Retrieve an exception from the .getException method of the parameter. * If the e parameter has no such method, then return null. * * @param e The object to call getException() on. * @return The wrapped exception, or <code>null</code> if there is no getException method on e. */ private static Exception getWrappedException(Object e) { Class<?> c = e.getClass(); try { Method m = c.getMethod("getException"); return (Exception)m.invoke(e); } catch (Exception nse) { return null; } } /** * This class merges the interfaces of Locator and SourceLocator * as they are completely identical. */ private static class ComboLocator extends LocatorImpl implements SourceLocator { /** * Main constructor. * * @param e The exception to get the location info from. */ public ComboLocator(SAXParseException e) { setColumnNumber(e.getColumnNumber()); setLineNumber(e.getLineNumber()); setPublicId(e.getPublicId()); setSystemId(e.getSystemId()); } } }