/*
 * 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 Venice Web Communities System.
 * 
 * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
 * for Silverwrist Design Studios.  Portions created by Eric J. Bowersox are
 * Copyright (C) 2001-02 Eric J. Bowersox/Silverwrist Design Studios.  All Rights Reserved.
 * 
 * Contributor(s): 
 */
package com.silverwrist.venice.ui.helpers;

import java.io.PrintStream;
import java.io.PrintWriter;
import com.silverwrist.venice.except.VeniceException;

/**
 * Intended as the &quot;superclass&quot; of content objects which may be thrown from UI code, as
 * if they were exceptions.  These are generally used in a similar context to exceptions, such as,
 * for example, {@link com.silverwrist.venice.ui.helpers.ErrorBox <CODE>ErrorBox</CODE>}, which
 * displays an error message.<P>
 * Objects extending this class will generally also implement one or more of the
 * {@link com.silverwrist.venice.ui.Content <CODE>Content</CODE>} interfaces, such as
 * {@link com.silverwrist.venice.ui.ContentDirect <CODE>ContentDirect</CODE>} or
 * {@link com.silverwrist.venice.ui.ContentJSP <CODE>ContentJSP</CODE>}.
 *
 * @author Eric J. Bowersox &lt;erbo@silcom.com&gt;
 * @version X
 */
public abstract class ThrowableContent extends Throwable
{
  /*--------------------------------------------------------------------------------
   * Attributes
   *--------------------------------------------------------------------------------
   */

  private Throwable inner;                     // encapsulated exception
  private boolean have_stack_trace = false;    // do we have a stack trace?

  /*--------------------------------------------------------------------------------
   * Constructors
   *--------------------------------------------------------------------------------
   */

  /**
   * Constructs a new <CODE>ThrowableContent</CODE> with <CODE>null</CODE> as its error message
   * string. Also, the method {@link #fillInStackTrace() fillInStackTrace()} is called for this object.
   */
  protected ThrowableContent()
  {
    super();
    inner = null;

  } // end constructor

  /**
   * Constructs a new <CODE>ThrowableContent</CODE> with the specified error message. Also, the method
   * {@link #fillInStackTrace() fillInStackTrace()} is called for this object.
   *
   * @param msg The error message. The error message is saved for later retrieval by the
   *            {@link java.lang.Throwable#getMessage() getMessage()} method.
   */
  protected ThrowableContent(String msg)
  {
    super(msg);
    inner = null;

  } // end constructor

  /**
   * Constructs a <CODE>ThrowableContent</CODE> that wraps another exception.  The error message of the
   * &quot;wrapped&quot; exception is used as the error message of this exception.  Also, the method
   * {@link #fillInStackTrace() fillInStackTrace()} is called for this object.
   *
   * @param t The exception to be wrapped by this <CODE>ThrowableContent</CODE>.
   */
  protected ThrowableContent(Throwable t)
  {
    super(t.getMessage());
    inner = t;

  } // end constructor

  /**
   * Constructs a <CODE>ThrowableContent</CODE> that wraps another exception, with a specified error message.
   * Also, the method {@link #fillInStackTrace() fillInStackTrace()} is called for this object.
   *
   * @param msg The error message. The error message is saved for later retrieval by the
   *            {@link java.lang.Throwable#getMessage() getMessage()} method.
   * @param t The exception to be wrapped by this <CODE>ThrowableContent</CODE>.
   */
  protected ThrowableContent(String msg, Throwable t)
  {
    super(msg);
    inner = t;

  } // end constructor

  /*--------------------------------------------------------------------------------
   * Overrides from class Object
   *--------------------------------------------------------------------------------
   */

  /**
   * Returns a short description of this throwable object.
   *
   * @return See above.
   */
  public String toString()
  {
    return getMessage();

  } // end toString

  /*--------------------------------------------------------------------------------
   * Overrides from class Throwable
   *--------------------------------------------------------------------------------
   */

  /**
   * Fills in the execution stack trace. This method records within this <CODE>Throwable</CODE> object
   * information about the current state of the stack frames for the current thread. This method is useful
   * when an application is re-throwing an error or exception.
   *
   * @return This <CODE>Throwable</CODE> object.
   * @see java.lang.Throwable#fillInStackTrace
   */
  public Throwable fillInStackTrace()
  {
    have_stack_trace = true;
    return super.fillInStackTrace();

  } // end fillInStackTrace

  /**
   * Prints this exception and its backtrace to the standard error stream.  Also prints the backtrace
   * of any &quot;wrapped&quot; exception.
   *
   * @see java.lang.System#err
   */
  public void printStackTrace()
  {
    this.printStackTrace(System.err);

  } // end printStackTrace

  /**
   * Prints this exception and its backtrace to the specified <CODE>PrintStream</CODE>.  Also prints the
   * backtrace of any &quot;wrapped&quot; exception.
   *
   * @param s <CODE>PrintStream</CODE> to use for output.
   */
  public void printStackTrace(PrintStream s)
  {
    if (have_stack_trace)
      super.printStackTrace(s);
    VeniceException.printRootCause(s,inner);

  } // end printStackTrace

  /**
   * Prints this exception and its backtrace to the specified <CODE>PrintWriter</CODE>.  Also prints the
   * backtrace of any &quot;wrapped&quot; exception.
   *
   * @param s <CODE>PrintWriter</CODE> to use for output.
   */
  public void printStackTrace(PrintWriter s)
  {
    if (have_stack_trace)
      super.printStackTrace(s);
    VeniceException.printRootCause(s,inner);

  } // end printStackTrace

  /*--------------------------------------------------------------------------------
   * External operations
   *--------------------------------------------------------------------------------
   */

  /**
   * Returns the exception wrapped by this exception, or <CODE>null</CODE> if there is none.
   *
   * @return See above.
   */
  public Throwable getException()
  {
    return inner;

  } // end getException

  /**
   * Returns <CODE>true</CODE> if this object contains a stack trace which can be printed,
   * <CODE>false</CODE> if not.
   *
   * @return See above.
   */
  public boolean canPrintStackTrace()
  {
    return (have_stack_trace || (inner!=null));

  } // end canPrintStackTrace

} // end class ThrowableContent
