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   
57