/* TransformerException.java -- 
   Copyright (C) 2004, 2005  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */
package javax.xml.transform;

import java.io.PrintStream;
import java.io.PrintWriter;

/**
 * An exception occurred during the transformation process.
 *
 * @author (a href='mailto:dog@gnu.org'>Chris Burdess</a)
 */
public class TransformerException
  extends Exception
{

  private SourceLocator  locator;
  private Throwable  cause;

  /**
   * Constructor with a detail message.
   */
  public TransformerException(String msg)
  {
    this(msg, null, null);
  }

  /**
   * Constructor with an underlying cause.
   */
  public TransformerException(Throwable cause)
  {
    this(cause.getMessage(), null, cause);
  }

  /**
   * Constructor with a detail message and underlying cause.
   */
  public TransformerException(String msg, Throwable cause)
  {
    this(msg, null, cause);
  }

  /**
   * Constructor with a detail message and locator.
   */
  public TransformerException(String msg, SourceLocator locator)
  {
    this(msg, locator, null);
  }

  /**
   * Constructor with detail message, locator and underlying cause.
   */
  public TransformerException(String msg, SourceLocator locator, 
                              Throwable cause)
  {
    super(msg);
    this.locator = locator;
    if (cause != null)
      {
        initCause(cause);
        this.cause = cause;
      }
  }

  /**
   * Returns a locator indicating where the error occurred.
   */
  public SourceLocator getLocator()
  {
    return locator;
  }

  /**
   * Sets the locator indicating where the error occurred.
   */
  public void setLocator(SourceLocator location)
  {
    locator = location;
  }

  /**
   * Returns the underlying cause of this exception.
   */
  public Throwable getException()
  {
    return cause;
  }

  /**
   * Returns the underlying cause of this exception.
   */
  public Throwable getCause()
  {
    return cause;
  }

  /**
   * Initializes the root cause of this exception.
   * This method may be called only once, and will be called by the
   * constructor if a non-null cause is specified.
   * Really phenomenally poor API design.
   * @param cause the underlying cause
   * @exception IllegalArgumentException if this exception is passed as the
   * argument
   * @exception IllegalStateException if a cause has already been
   * initialized
   */
  public Throwable initCause(Throwable cause)
  {
    if (this.cause != null)
      {
        throw new IllegalStateException();
      }
    if (cause == this)
      {
        throw new IllegalArgumentException();
      }
    this.cause = cause;
    return this;
  }

  /**
   * Returns the exception message with location information appended.
   */
  public String getMessageAndLocation()
  {
    return (locator == null) ? getMessage() :
      getMessage() + ": " + getLocationAsString();
  }

  /**
   * Returns the location information as a string.
   */
  public String getLocationAsString()
  {
    if (locator == null)
      {
        return null;
      }
    String publicId = locator.getPublicId();
    String systemId = locator.getSystemId();
    int lineNumber = locator.getLineNumber();
    int columnNumber = locator.getColumnNumber();
    StringBuffer buffer = new StringBuffer ();
    if (publicId != null)
      {
        buffer.append ("publicId=");
        buffer.append (publicId);
      }
    if (systemId != null)
      {
        if (buffer.length() > 0)
          {
            buffer.append(' ');
          }
        buffer.append ("systemId=");
        buffer.append (systemId);
      }
    if (lineNumber != -1)
      {
        if (buffer.length() > 0)
          {
            buffer.append(' ');
          }
        buffer.append ("lineNumber=");
        buffer.append (lineNumber);
      }
    if (columnNumber != -1)
      {
        if (buffer.length() > 0)
          {
            buffer.append(' ');
          }
        buffer.append ("columnNumber=");
        buffer.append (columnNumber);
      }
    return buffer.toString();
  }

  public void printStackTrace()
  {
    printStackTrace(System.out);
  }

  public void printStackTrace(PrintStream s)
  {
    super.printStackTrace(s);
    if (cause != null)
      {
        s.print("caused by ");
        cause.printStackTrace(s);
      }
  }

  public void printStackTrace(PrintWriter s)
  {
    super.printStackTrace(s);
    if (cause != null)
      {
        s.print("caused by ");
        cause.printStackTrace(s);
      }
  }

}
