/*
 * Copyright 2005 The Apache Software Foundation.
 * 
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License.
 */

/*
 * JDOException.java
 *
 */

package javax.jdo;

import javax.jdo.spi.I18NHelper;

/** This is the root of all JDO Exceptions.  It contains an optional detail
 * message, an optional nested <code>Throwable</code> array and an optional failed object.
 * @author Craig Russell
 * @version 1.0.2
 */
public class JDOException extends java.lang.RuntimeException {
  
  /** This exception was generated because of an exception in the runtime library.
   * @serial the nested <code>Throwable</code> array
   */
  Throwable[] nested;
  
  /** This exception may be the result of incorrect parameters supplied
   * to an API.  This is the object from which the user can determine
   * the cause of the problem.
   * @serial the failed <code>Object</code>
   */
  Object failed;

    /** The Internationalization message helper.
     */
    private static I18NHelper msg = I18NHelper.getInstance ("javax.jdo.Bundle"); //NOI18N

    /** Flag indicating whether printStackTrace is being executed.
     */
    private boolean inPrintStackTrace = false;
    
  /**
   * Constructs a new <code>JDOException</code> without a detail message.
   */
  public JDOException() {
  }
  

  /**
   * Constructs a new <code>JDOException</code> with the specified detail message.
   * @param msg the detail message.
   */
  public JDOException(String msg) {
    super(msg);
  }

  /** Constructs a new <code>JDOException</code> with the specified detail message
   * and nested <code>Throwable</code>s.
   * @param msg the detail message.
   * @param nested the nested <code>Throwable[]</code>.
   */
  public JDOException(String msg, Throwable[] nested) {
    super(msg);
    this.nested = nested;
  }
  
  /** Constructs a new <code>JDOException</code> with the specified detail message
   * and nested <code>Throwable</code>.
   * @param msg the detail message.
   * @param nested the nested <code>Throwable</code>.
   */
  public JDOException(String msg, Throwable nested) {
    super(msg);
    this.nested = new Throwable[] {nested};
  }
  
  /** Constructs a new <code>JDOException</code> with the specified detail message
   * and failed object.
   * @param msg the detail message.
   * @param failed the failed object.
   */
  public JDOException(String msg, Object failed) {
    super(msg);
    this.failed = failed;
  }
  
  /** Constructs a new <code>JDOException</code> with the specified detail message,
   * nested <code>Throwable</code>s, and failed object.
   * @param msg the detail message.
   * @param nested the nested <code>Throwable[]</code>.
   * @param failed the failed object.
   */
  public JDOException(String msg, Throwable[] nested, Object failed) {
    super(msg);
    this.nested = nested;
    this.failed = failed;
  }
  
  /** Constructs a new <code>JDOException</code> with the specified detail message,
   * nested <code>Throwable</code>, and failed object.
   * @param msg the detail message.
   * @param nested the nested <code>Throwable</code>.
   * @param failed the failed object.
   */
  public JDOException(String msg, Throwable nested, Object failed) {
    super(msg);
    this.nested = new Throwable[] {nested};
    this.failed = failed;
  }
  
  /** The exception may include a failed object.
   * @return the failed object.
   */
  public Object getFailedObject() {
    return failed;
  }
  
  /** The exception may have been caused by multiple exceptions in the runtime.
   * If multiple objects caused the problem, each failed object will have
   * its own <code>Exception</code>.
   * @return the nested Throwable array.
   */
  public Throwable[] getNestedExceptions() {
    return nested;
  }
  
  /** Often there is only one nested exception, and this method returns it.
   * If there are more than one, then this method returns the first nested
   * exception. If there is no nested exception, then null is returned.
   * @return the first or only nested Throwable.
   * @since 1.0.1
   */
  public synchronized Throwable getCause() {
      // super.printStackTrace calls getCause to handle the cause. 
      // Returning null prevents the superclass from handling the cause;
      // instead the local implementation of printStackTrace should
      // handle the cause. Otherwise, the cause is printed twice.
      if (nested == null || nested.length == 0 || inPrintStackTrace) {
          return null;
      } else {
          return nested[0];
      }
  }
  
  /** JDK 1.4 includes a new chaining mechanism for Throwable, but since
   * JDO has its own "legacy" chaining mechanism, the "standard" mechanism
   * cannot be used. This method always throws a JDOFatalInternalException.
   * @param cause ignored.
   * @return never.
   */
  public Throwable initCause(Throwable cause) {
      throw new JDOFatalInternalException(msg.msg("ERR_CannotInitCause"));
  }
  
  /** The <code>String</code> representation includes the name of the class,
   * the descriptive comment (if any),
   * the <code>String</code> representation of the failed <code>Object</code> (if any),
   * and the <code>String</code> representation of the nested <code>Throwable</code>s (if any).
   * @return the <code>String</code>.
   */
  public synchronized String toString() {
    int len = nested==null?0:nested.length;
    // calculate approximate size of the String to return
    StringBuffer sb = new StringBuffer (10 + 100 * len);
    sb.append (super.toString());
    // include failed object information
    if (failed != null) {
        sb.append ("\n").append (msg.msg ("MSG_FailedObject"));
      String failedToString = null;
      try {
          failedToString = failed.toString();
      } catch (Exception ex) {
          // include the information from the exception thrown by failed.toString
          Object objectId = JDOHelper.getObjectId(failed);
          if (objectId == null) {
              failedToString = msg.msg("MSG_ExceptionGettingFailedToString", //NOI18N
                                       exceptionToString(ex));
          }
          else {
              // include the ObjectId information
              String objectIdToString = null;
              try {
                  objectIdToString = objectId.toString();
              }
              catch (Exception ex2) {
                  objectIdToString = exceptionToString(ex2);
              }
              failedToString = msg.msg("MSG_ExceptionGettingFailedToStringObjectId", //NOI18N
                                       exceptionToString(ex), objectIdToString);
          }
      }
      sb.append (failedToString);
    }
    // include nested Throwable information, but only if not called by
    // printStackTrace; the stacktrace will include the cause anyway.
    if (len > 0 && !inPrintStackTrace) {
      sb.append ("\n").append (msg.msg ("MSG_NestedThrowables")).append ("\n");
      Throwable exception = nested[0];
      sb.append (exception==null?"null":exception.toString()); //NOI18N
      for (int i=1; i<len; ++i) {
        sb.append ("\n"); //NOI18N
        exception = nested[i];
      sb.append (exception==null?"null":exception.toString()); //NOI18N
      }
    }
    return sb.toString();
  }    
  
    /**
     * Prints this <code>JDOException</code> and its backtrace to the 
     * standard error output.
     * Print nested Throwables' stack trace as well.
     */
    public void printStackTrace() { 
        printStackTrace (System.err);
    }

    /**
     * Prints this <code>JDOException</code> and its backtrace to the 
     * specified print stream.
     * Print nested Throwables' stack trace as well.
     * @param s <code>PrintStream</code> to use for output
     */
    public synchronized void printStackTrace(java.io.PrintStream s) { 
    int len = nested==null?0:nested.length;
        synchronized (s) {
            inPrintStackTrace = true;
            super.printStackTrace(s);
            if (len > 0) {
                s.println (msg.msg ("MSG_NestedThrowablesStackTrace"));
                for (int i=0; i<len; ++i) {
                    Throwable exception = nested[i];
                    if (exception != null) {
                        exception.printStackTrace(s);
                    }
                }
            }
            inPrintStackTrace = false;
        }
    }

    /**
     * Prints this <code>JDOException</code> and its backtrace to the specified
     * print writer.
     * Print nested Throwables' stack trace as well.
     * @param s <code>PrintWriter</code> to use for output
     */
    public synchronized void printStackTrace(java.io.PrintWriter s) { 
    int len = nested==null?0:nested.length;
        synchronized (s) {
            inPrintStackTrace = true;
            super.printStackTrace(s);
            if (len > 0) {
                s.println (msg.msg ("MSG_NestedThrowablesStackTrace"));
                for (int i=0; i<len; ++i) {
                    Throwable exception = nested[i];
                    if (exception != null) {
                        exception.printStackTrace(s);
                    }
                }
            }
            inPrintStackTrace = false;
        }
    }

    /**
     * Helper method returning a short description of the exception passed
     * as an argument. The returned string has the format defined by
     * Throwable.toString. If the exception has a non-null detail message 
     * string, then it returns the name of exception class concatenated
     * with ": " concatenated with the detailed message. Otherwise it
     * returns the name of exception class.
     * @param ex the exception to be represented.
     * @return a string representation of the exception passed as an argument.
     */
    private static String exceptionToString(Exception ex)
    {
        if (ex == null) return null;
        String s = ex.getClass().getName();
        String message = ex.getMessage();
        return (message != null) ? (s + ": " + message) : s;
    }
}

