001: /*
002: * ReflectException.java --
003: *
004: * The file implements the handling of the Exception's caught
005: * while invoking the Reflection API.
006: *
007: * Copyright (c) 1997 Sun Microsystems, Inc.
008: *
009: * See the file "license.terms" for information on usage and
010: * redistribution of this file, and for a DISCLAIMER OF ALL
011: * WARRANTIES.
012: *
013: * RCS: @(#) $Id: ReflectException.java,v 1.4 2002/12/30 22:49:24 mdejong Exp $
014: *
015: */
016: package tcl.lang;
017:
018: import java.lang.reflect.*;
019:
020: /**
021: * This class handles Exception's caught while invoking the Reflection
022: * API. It records the string form of the Exception into the result
023: * of the interpreter and stores the actual Exception object in the
024: * errorCode of the interpreter.
025: */
026:
027: class ReflectException extends TclException {
028:
029: // The throwable object passed to the constructor
030: Throwable throwable;
031:
032: /*
033: *----------------------------------------------------------------------
034: *
035: * ReflectException --
036: *
037: * Records the string form of the Exception into the result
038: * of the interpreter and stores the actual Exception object in the
039: * errorCode of the interpreter.
040: *
041: * Results:
042: * None.
043: *
044: * Side effects:
045: * If interp is non-null, the interpreter result and errorCode
046: * are modified
047: *
048: *----------------------------------------------------------------------
049: */
050:
051: ReflectException(Interp interp, // Current interpreter. May be null.
052: // If non-null, its result object and
053: // errorCode variable will be changed.
054: Throwable e) // The exception to record in the interp.
055: {
056: super (TCL.ERROR);
057:
058: if (throwable instanceof TclException)
059: throw new TclRuntimeError(
060: "don't wrap TclException in ReflectException");
061:
062: if (e instanceof InvocationTargetException) {
063: // The original exception is wrapped in InvocationTargetException
064: // for us by the Java Reflection API. This fact doesn't provide
065: // any interesting information to script writers, so we'll
066: // unwrap it so that is more convenient for scripts to
067: // figure out the exception.
068:
069: throwable = ((InvocationTargetException) e)
070: .getTargetException();
071: } else {
072: throwable = e;
073: }
074:
075: if (interp != null) {
076: TclObject errCode = TclList.newInstance();
077: errCode.preserve();
078:
079: try {
080: TclList.append(interp, errCode, TclString
081: .newInstance("JAVA"));
082: TclList.append(interp, errCode,
083: ReflectObject.newInstance(interp,
084: Throwable.class, throwable));
085: } catch (TclException tclex) {
086: throw new TclRuntimeError("unexpected TclException: "
087: + tclex);
088: }
089:
090: // interp.setErrorCode() may fail silently if there is an bad
091: // trace on the "errorCode" variable. If that happens, the
092: // errCode list we created above may hang around
093: // forever. Hence, we added the pair of preserve() + release()
094: // calls to ensure that errCode will get cleaned up if
095: // interp.setErrorCode() fails.
096:
097: interp.setErrorCode(errCode);
098: errCode.release();
099:
100: interp.setResult(throwable.toString());
101: }
102: }
103:
104: /*
105: *----------------------------------------------------------------------
106: *
107: * getThrowable --
108: *
109: * Return the Throwable object that was recorded into the
110: * errorCode global variable. Invoking this method should
111: * be significantly faster than getting the value of the
112: * errorCode variable.
113: *
114: * Results:
115: * Return a Throwable object.
116: *
117: * Side effects:
118: * None.
119: *
120: *----------------------------------------------------------------------
121: */
122:
123: Throwable getThrowable() {
124: return throwable;
125: }
126:
127: } // end ReflectException
|