001: /*
002: * BeanEvent.java --
003: *
004: * Handles JavaBean events in Tcl.
005: *
006: * Copyright (c) 1997 Sun Microsystems, Inc.
007: *
008: * See the file "license.terms" for information on usage and
009: * redistribution of this file, and for a DISCLAIMER OF ALL
010: * WARRANTIES.
011: *
012: * RCS: @(#) $Id: BeanEvent.java,v 1.4 2005/11/16 21:08:11 mdejong Exp $
013: *
014: */
015:
016: package tcl.lang;
017:
018: import java.util.*;
019:
020: /**
021: * This class handles JavaBean events in Tcl.
022: */
023:
024: class BeanEvent extends TclEvent {
025:
026: // The interpreter to execute the callback command.
027:
028: Interp interp;
029:
030: // The callback command to execute when the event is fired.
031:
032: String command;
033:
034: // Types of the event parameters.
035:
036: Class paramTypes[];
037:
038: // The parameters for the event.
039:
040: Object params[];
041:
042: // If an Exception is throws during the execution of the callback
043: // script, it is stored in this member variable.
044:
045: Throwable exception;
046:
047: /*
048: *----------------------------------------------------------------------
049: *
050: * BeanEvent --
051: *
052: * Creates a new BeanEvent instance.
053: *
054: * side effects:
055: * Member fields are initialized.
056: *
057: *----------------------------------------------------------------------
058: */
059:
060: BeanEvent(Interp i, // Interpreter to execute the callback command.
061: Class t[], // Types of the event parameters.
062: Object p[], // Parameters for this event.
063: TclObject cmd) // The callback command.
064: {
065: interp = i;
066: command = cmd.toString();
067: paramTypes = t;
068: params = p;
069: }
070:
071: /*
072: *----------------------------------------------------------------------
073: *
074: * processEvent --
075: *
076: * Process the bean event.
077: *
078: * Results:
079: * Always returns 1 -- the event has been processed and can be
080: * removed from the event queue.
081: *
082: * Side effects:
083: * A script is eval'ed to handle the event. The script may may have
084: * arbitrary side effects.
085: *
086: *----------------------------------------------------------------------
087: */
088:
089: public int processEvent(int flags) // Same as flags passed to
090: // InterpGroup.doOneEvent.
091: {
092: BeanEventMgr mgr = BeanEventMgr.getBeanEventMgr(interp);
093:
094: try {
095: exception = null;
096: mgr.pushEventParamSet(new BeanEventParamSet(paramTypes,
097: params));
098: interp.eval(command, 0);
099: } catch (TclException e) {
100: int code = e.getCompletionCode();
101:
102: if (code == TCL.ERROR) {
103: exception = e;
104:
105: // If the exception is a ReflectException, we throw the
106: // actual Java exception, which is stored in the
107: // errorCode.
108:
109: try {
110: TclObject errCode = interp.getVar("errorCode",
111: null, TCL.GLOBAL_ONLY);
112:
113: if (errCode != null) {
114: TclObject elm1 = TclList.index(interp, errCode,
115: 0);
116: TclObject elm2 = TclList.index(interp, errCode,
117: 1);
118:
119: if ((elm1 != null)
120: && (elm1.toString().equals("JAVA"))) {
121: if (elm2 != null) {
122: Object obj = null;
123: TclObject oldResult = interp
124: .getResult();
125: oldResult.preserve();
126:
127: try {
128: obj = ReflectObject.get(interp,
129: elm2);
130: } catch (TclException e3) {
131: // The second element in errorCode
132: // doesn't contain a Java object
133: // handle. Let's restore the interp's
134: // result to the old result.
135:
136: interp.setResult(oldResult);
137: } finally {
138: oldResult.release();
139: }
140:
141: if ((obj != null)
142: && (obj instanceof Throwable)) {
143: exception = (Throwable) obj;
144: exception.fillInStackTrace();
145: }
146: }
147: }
148: }
149: } catch (TclException e2) {
150: throw new TclRuntimeError(
151: "unexpected TclException " + e2);
152: }
153: } else if (code == TCL.RETURN) {
154: // The script invoked the "return" command. We treat this
155: // as a normal completion -- even if the command
156: // was "return -code error".
157:
158: } else if (code == TCL.BREAK) {
159: exception = new TclException(interp,
160: "invoked \"break\" outside of a loop");
161: } else if (code == TCL.CONTINUE) {
162: exception = new TclException(interp,
163: "invoked \"continue\" outside of a loop");
164: } else {
165: exception = e;
166: }
167: } finally {
168: mgr.popEventParamSet();
169: }
170:
171: return 1;
172: }
173:
174: } // end BeanEvent
|