2003/11/16 08:28:10
[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         public abstract void putAndTriggerJSTraps(Object key, Object value);
42     }
43
44     static class JSTrapScope extends JSScope {
45         JSTrap t;
46         Object val = null;
47         boolean cascadeHappened = false;
48         public JSTrapScope(JSScope parent, JSTrap t, Object val) { super(parent); this.t = t; this.val = val; }
49         public Object get(Object key) {
50             if (key.equals("trapee")) return t.trapee;
51             if (key.equals("trapname")) return t.name;
52             return super.get(key);
53         }
54     }
55 }
56