/* 
 * <copyright> 
 *  Copyright (c) 2001 by Hyperwave AG
 * </copyright> 
 * 
 * <file> 
 *  Name:        AbstractResource.js
 *  Created:     2001-01-14
 *  $Id: Exception.js,v 1.3.2.7 2004/09/20 08:37:20 mmair Exp $
 * </file>
 */

initPackage ( "lang" );

//----------------------------------------------------------------------
/**
 * This exception class wraps all current resource exceptions.
 * The only purpose is to hold an array which can get a kind
 * of error stack.
 */
// <JSClass Name="lang.Exception">
{

  //--------------------------------------------------------------------
  /**
    * The Constructor an exception creates an error array and
    * the default exceptionname.
    * @param aParam: (Object | void): if given, an initial string
    *   or error which must have a <i>string</i> representation.
    */
  lang.Exception = function ( aParam )
  {
    if ( aParam == "__proto__" )
      return;

    this.exceptionName_ = "lang.Exception";
    this.errors_ = [];

    // an empty exception is instantiated in the XMLResourceReader...
    if (aParam){
      this.message_ = (typeof(aParam).toLowerCase() == "string") ? aParam : "no message";
    }
    else {
      this.message_ = "no message";
    }
    // nested exception, if an exception handed over
    this.cause_ = (aParam instanceof lang.Exception) ? aParam : null;

    // for finding out file name and line number
    this.internalTrick_ = new Error( );
  }
  class$ = doInherit ( lang.Exception );

  class$.static_.EXCEPTION_FILE_INDEX1 = "/lib/share/Exceptions/";
  class$.static_.EXCEPTION_FILE_INDEX2 = "/lib/base/v1.x/lang/Exception.js";

  //--------------------------------------------------------------------
  /**
   * Add a new error to the exception object.
   * @param anError: (Object | void): an object describing the error
   *   which is put to the exception.
   */
  class$.pushError = function ( anError )
  {
    if ( anError != null )
      this.errors_ [this.errors_.length] = anError;
  }

  //--------------------------------------------------------------------
  /**
   * Check whether or not errors have been pushed to the Exception
   * object and gives the number of errors or 0 if no errors
   * are present.
   * @return Number: 0 if no error is present or otherwise the
   *   current number of errrors.
   */
  class$.errorCount = function ()
  {
    return this.errors_.length;
  }

  //------------------------------------------------------------
  /**
   * Assigns a given exception as the cause of the current exception.
   * @param anException: lang.Exception: the cause of the current exception.
   */
  class$.initCause = function( anException )
  {
    if (anException instanceof lang.Exception){
      this.cause_ = anException;
    }
    else if (anException instanceof Error) {
      this.cause_ = anException;
    }
  }
  
  //-----------------------------------------------------------
  /**
   * Returns the message text of this exception. 
   *
   * @return string: a message text describing the exception.
   */
  class$.getMessage = function()
  {
    return this.message_;
  }
  
  //-----------------------------------------------------------
  /**
   * Returns the name of this exception. 
   *
   * @return string: the name of the exception.
   */
  class$.getName = function()
  {
    return this.exceptionName_;
  }
  
  //-----------------------------------------------------------
  /**
   * Returns the cause of this exception.
   *
   * @return lang.Exception: the nested exception that lead to this one (can be 
   *   an <code>lang.Exception</code> or a subclass of it
   *   or <code>null</code> if no cause was defined during the exception.
   */
  class$.getCause = function()
  {
    return this.cause_;
  }

  
  //--------------------------------------------------------------------
  /**
   * Provides the basic mechanism of creating an output
   * string from the Exception class.
   * @return String: a String containing the class type and the
   *   errors.
   */
  class$.toString = function ()
  {
    var out_array = [];
    for ( var index = 0; index < this.errors_.length; ++index ) {
      out_array [index] = this.errors_ [index].toString();
    }

    var ret = [];

    ret[ret.length] = "@" + this.exceptionName_ + ": " + this.message_;
    ret[ret.length] = this._parseStackTrace(this.internalTrick_.stack);

    if (out_array.length > 0) {
      ret[ret.length] = "\nerrors: " + out_array[0];
    }

    for (var i = 1; i < out_array.length; i ++) {
      ret[ret.length] = " - " + out_array[i];
    }

    if (this.cause_) {
      ret[ret.length] = "\nbecause of: ";
      ret[ret.length] = this.cause_;
      if (this.cause_ instanceof Error) {
        ret[ret.length] = this._parseStackTrace(this.cause_.stack);
      }
    }

    return ret.join("\n");
  }

  //--------------------------------------------------------------------
  /**
   * ###METHOD DESCRIPTION###
   *
   * @return string: ###PARAMETER DESCRIPTION###
   */
  class$._parseStackTrace = function (theStack)
  {
    if (!theStack) {
      // the client side doesn't know the stack
      return "";
    }
    var ret = "";
    var trace = theStack.split("\n");
    for (var i = trace.length - 1; i -- > 0;) {
      var curr = trace[i];
      if (curr.indexOf(this.static_.EXCEPTION_FILE_INDEX1) > -1 ||
          curr.indexOf(this.static_.EXCEPTION_FILE_INDEX2) > -1) {
        break;
      }
      if (curr.indexOf("()") == 0) {
        curr = curr.substr(2);
      }
      ret = curr.replace(/\)\@file\:/g, ")\n@file:") + (ret ? "\n" : "") + ret;
    }
    return ret;
  }

  //--------------------------------------------------------------------
  /**
   * Test main routine
   */
  class$.static_.main = function ()
  {
    var x = new lang.Exception ( "Error 1" );
    x.pushError ( "Error 2" );
    var y = new lang.Exception ( "Error 3" );
    x.pushError ( y );
    writeln ( "There are " + x.errorCount () + " errors" );
    writeln ( x.toString () );
  }

}
// </JSClass>
//----------------------------------------------------------------------

/* End of "lang.Exception" */


