3eefe14130af2efea04370541bb073565b6a97d5
[org.ibex.core.git] / src / org / xwt / js / JSTrap.java
1 // Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL]
2 package org.xwt.js;
3
4 import java.util.*;
5 import org.xwt.util.*;
6 import java.io.*;
7
8 /**
9  *  This class encapsulates a single trap placed on a given node. The
10  *  traps for a given property name on a given box are maintained as a
11  *  linked list stack, with the most recently placed trap at the head
12  *  of the list.
13  */
14 public class JSTrap {
15
16     JSTrappable trapee = null;   ///< the box on which this trap was placed
17     JSFunction f = null;                 ///< the function for this trap
18     JSTrap next = null;          ///< the next trap down the trap stack
19     Object name = null;          ///< the property that the trap was placed on
20
21     private JSTrap(JSTrappable b, String n, JSFunction f, JSTrap nx) { trapee = b; name = n; this.f = f; this.next = nx; }
22
23     /** adds a trap, avoiding duplicates */
24     public static void addTrap(JSTrappable trapee, Object name, JSFunction f) {
25         for(JSTrap t = trapee.getTrap(name); t != null; t = t.next) if (t.f == f) return;
26         trapee.putTrap(name, new JSTrap(trapee, name.toString(), f, (JSTrap)trapee.getTrap(name)));
27     }
28
29     /** deletes a trap, if present */
30     public static void delTrap(JSTrappable trapee, Object name, JSFunction f) {
31         JSTrap t = (JSTrap)trapee.getTrap(name);
32         if (t == null) return;
33         if (t.f == f) { trapee.putTrap(t.name, t.next); return; }
34         for(; t.next != null; t = t.next) if (t.next.f == f) { t.next = t.next.next; return; }
35     }
36
37     /** objects onto which traps may be placed */
38     public static interface JSTrappable {
39         public abstract JSTrap getTrap(Object key);
40         public abstract void putTrap(Object key, JSTrap trap);
41
42         /** puts to this value using an unpauseable context, triggering any traps */
43         public abstract void putAndTriggerJSTraps(Object key, Object value);
44     }
45
46     // FIXME: cascadeHappened gets set, but autocascade does not happen
47     static class JSTrapScope extends JSScope {
48         JSTrap t;
49         Object val = null;
50         boolean cascadeHappened = false;
51         public JSTrapScope(JSScope parent, JSTrap t, Object val) { super(parent); this.t = t; this.val = val; }
52         public Object get(Object key) {
53             if (key.equals("trapee")) return t.trapee;
54             if (key.equals("trapname")) return t.name;
55             return super.get(key);
56         }
57     }
58 }
59