/*
* $Id: AnyThrowable.java,v 1.7 2002/09/16 08:05:02 jkl Exp $
*
* Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
*
* Use is subject to license terms, as defined in
* Anvil Sofware License, Version 1.1. See LICENSE
* file, or http://njet.org/license-1.1.txt
*/
package anvil.core;
import anvil.ErrorEvent;
import anvil.ErrorListener;
import anvil.Location;
import anvil.script.Context;
import anvil.script.Function;
import anvil.script.Scope;
import anvil.script.Module;
import anvil.script.StackFrame;
import anvil.core.runtime.AnyScope;
import anvil.core.runtime.AnyFunction;
import anvil.core.runtime.AnyStackTraceElement;
import java.util.Enumeration;
import java.net.URL;
/// @class throwable
/// Throwable is a carrier for exceptions, capable of holding of
/// message and stack trace.
/**
* class AnyThrowable
*
* @author: Jani Lehtim�ki
*/
public class AnyThrowable extends AnyAbstractClass
{
public static final anvil.script.compiler.NativeClass __class__ =
new anvil.script.compiler.NativeClass("throwable", AnyThrowable.class,
//DOC{{
""+
" @class throwable\n" +
" Throwable is a carrier for exceptions, capable of holding of\n" +
" message and stack trace.\n" +
" @method fillInStackTrace\n" +
" Inserts to current stack frame to this \n" +
" throwable object.\n" +
" @synopsis throwable fillInStackTrace()\n" +
" @method fill\n" +
" Inserts to current stack frame to this \n" +
" throwable object.\n" +
" @synopsis throwable fill()\n" +
" @method getMessage\n" +
" Returns the error message of this throwable.\n" +
" @synopsis string getMessage()\n" +
" @method getStackTrace\n" +
" Returns the list containing instances of \n" +
" anvil.runtime.StackTraceElement:s.\n" +
" @synopsis list getStackTrace()\n" +
" @method getErrors\n" +
" Returns array of (parsing) errors, if any.\n" +
" @synopsis array getErrors()\n"
//}}DOC
);
private static final Any STR_LINE = Any.create("line");
private static final Any STR_URL = Any.create("url");
private static final Any STR_COLUMN = Any.create("column");
private static final Any STR_MESSAGE = Any.create("message");
private static final Any STR_EXCEPTION = Any.create("exception");
private String _message = null;
private AnyList _stacktrace = null;
private ErrorListener _listener = null;
private Any _errors = null;
public AnyThrowable(Context context)
{
_stacktrace = context.getStackTrace();
}
public AnyThrowable(Context context, String message)
{
_stacktrace = context.getStackTrace();
_message = message;
}
public AnyThrowable(Context context, String message, ErrorListener listener)
{
_stacktrace = context.getStackTrace();
_message = message;
_listener = listener;
}
public anvil.script.ClassType classOf()
{
return __class__;
}
public String toString()
{
StringBuffer buffer = new StringBuffer();
buffer.append(classOf().getName());
if (_message != null) {
buffer.append(" (");
buffer.append(_message);
buffer.append(')');
}
buffer.append('\n');
Any[] frames = _stacktrace.toTuple();
int n = _stacktrace.sizeOf();
for(int i=0; i<n; i++) {
buffer.append(" at ");
buffer.append(frames[i].toString());
buffer.append('\n');
}
if (_listener != null) {
buffer.append("\n");
Enumeration e = _listener.getEvents();
while(e.hasMoreElements()) {
ErrorEvent evt = (ErrorEvent)e.nextElement();
Location loc = evt.getLocation();
URL url;
int line, column;
if (loc != null) {
url = loc.getURL();
line = loc.getLine();
column = loc.getColumn();
} else {
url = null;
line = 0;
column = 0;
}
url = (loc != null) ? loc.getURL() : null;
if (url != null) {
buffer.append(url.toString());
} else {
buffer.append("unknown");
}
if (line != 0) {
buffer.append(" [");
buffer.append(line);
if (column != 0) {
buffer.append(":");
buffer.append(column);
}
buffer.append(']');
}
buffer.append("\n ");
buffer.append(evt.getMessage());
buffer.append('\n');
Throwable throwable = evt.getThrowable();
if (throwable != null) {
buffer.append(" ");
buffer.append(throwable.toString());
buffer.append('\n');
}
}
}
return buffer.toString();
}
public Object toObject()
{
return null;
}
public void fillInStackTrace(int index, Module module, Any instance, Function method)
{
_stacktrace.setSlice(0, 0, new AnyStackTraceElement(module, instance, method, 0));
}
public void fillInStackTrace(Module module, int line, Any instance, Function method)
{
_stacktrace.setSlice(0, 0, new AnyStackTraceElement(module, instance, method, line));
}
public void fillInStackTrace(StackFrame frame)
{
_stacktrace.setSlice(0, 0, new AnyStackTraceElement(frame));
}
private Any buildErrors()
{
if (_listener != null) {
Array errors = new Array(_listener.errors());
Enumeration e = _listener.getEvents();
while(e.hasMoreElements()) {
ErrorEvent evt = (ErrorEvent)e.nextElement();
Location loc = evt.getLocation();
URL url;
int line;
int column;
if (loc != null) {
url = loc.getURL();
line = loc.getLine();
column = loc.getColumn();
} else {
url = null;
line = 0;
column = 0;
}
url = (loc != null) ? loc.getURL() : null;
Array error = new Array(7);
error.append(STR_URL, (url != null) ? new anvil.core.net.AnyURL(url) : Any.NULL);
error.append(STR_LINE, Any.create(line));
error.append(STR_COLUMN, Any.create(column));
error.append(STR_MESSAGE, Any.create(evt.getMessage()));
Throwable throwable = evt.getThrowable();
if (throwable != null) {
error.append(STR_EXCEPTION, Any.create(throwable.toString()));
} else {
error.append(STR_EXCEPTION, Any.NULL);
}
errors.append(error);
}
return errors;
} else {
return new Array();
}
}
/// @method fillInStackTrace
/// Inserts to current stack frame to this
/// throwable object.
/// @synopsis throwable fillInStackTrace()
public Any m_fillInStackTrace(Context context)
{
fillInStackTrace(context.frame());
return this;
}
/// @method fill
/// Inserts to current stack frame to this
/// throwable object.
/// @synopsis throwable fill()
public Any m_fill(Context context)
{
fillInStackTrace(context.frame());
return this;
}
/// @method getMessage
/// Returns the error message of this throwable.
/// @synopsis string getMessage()
public Any m_getMessage()
{
return Any.create(_message);
}
/// @method getStackTrace
/// Returns the list containing instances of
/// anvil.runtime.StackTraceElement:s.
/// @synopsis list getStackTrace()
public Any m_getStackTrace(Context context)
{
context.checkAccess(anvil.core.runtime.stack.StackModule.CAN_READ);
return _stacktrace;
}
/// @method getErrors
/// Returns array of (parsing) errors, if any.
/// @synopsis array getErrors()
public Any m_getErrors()
{
if (_errors == null) {
return (_errors = buildErrors());
} else {
return _errors;
}
}
}