KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > polyglot > util > NestedMap


1 /*
2  * NestedMap.java
3  */

4
5 package polyglot.util;
6
7 import java.util.Map JavaDoc;
8 import java.util.AbstractMap JavaDoc;
9 import java.util.HashMap JavaDoc;
10 import java.util.Set JavaDoc;
11 import java.util.Iterator JavaDoc;
12 import java.util.AbstractSet JavaDoc;
13
14 /**
15  * A NestedMap is a map which, when it cannot find an element in itself,
16  * defers to another map. Modifications, however, are not passed on to
17  * the supermap.
18  *
19  * A NestedMap and its backing collections and iterators support all
20  * operations except 'remove' and 'clear', since operations to a
21  * NestedMap must not affect the backing map. Instead, use the 'release'
22  * method.
23  *
24  * It is used to implement nested namespaces, such as those which store
25  * local-variable bindings.
26  **/

27 public class NestedMap extends AbstractMap JavaDoc implements Map JavaDoc {
28   /**
29    * Creates a new nested map, which defers to <containing>. If containing
30    * is null, it defaults to a NilMap.
31    **/

32   public NestedMap(Map JavaDoc containing) {
33     this.superMap = containing == null ? NilMap.EMPTY_MAP : containing;
34     this.myMap = new HashMap JavaDoc();
35     setView = new EntrySet();
36     nShadowed = 0;
37   }
38
39   /////
40
// For NestedMap.
41
/////
42
/**
43    * Returns the map to which this map defers, or null for none.
44    **/

45   public Map JavaDoc getContainingMap() {
46     return superMap instanceof NilMap ? null : superMap;
47   }
48
49   /**
50    * Removes any binding in this for <key>, returning to the binding (if any)
51    * from the supermap.
52    **/

53   public void release(Object JavaDoc key) {
54     myMap.remove(key);
55   }
56
57   /**
58    * Returns the map containing the elements for this level of nesting.
59    **/

60   public Map JavaDoc getInnerMap() {
61     return myMap;
62   }
63
64   /////
65
// Methods required for AbstractMap.
66
/////
67

68   public Set JavaDoc entrySet() {
69     return setView;
70   }
71
72   public int size() {
73     return superMap.size() + myMap.size() - nShadowed;
74   }
75
76   public boolean containsKey(Object JavaDoc key) {
77     return myMap.containsKey(key) || superMap.containsKey(key);
78   }
79
80   public Object JavaDoc get(Object JavaDoc key) {
81     if (myMap.containsKey(key))
82       return myMap.get(key);
83     else
84       return superMap.get(key);
85   }
86   
87   public Object JavaDoc put(Object JavaDoc key, Object JavaDoc value) {
88     if (myMap.containsKey(key)) {
89       return myMap.put(key,value);
90     } else {
91       Object JavaDoc oldV = superMap.get(key);
92       myMap.put(key,value);
93       nShadowed++;
94       return oldV;
95     }
96   }
97
98   public Object JavaDoc remove(Object JavaDoc key) {
99     throw new UnsupportedOperationException JavaDoc("Remove from NestedMap");
100   }
101
102   public void clear() {
103     throw new UnsupportedOperationException JavaDoc("Clear in NestedMap");
104   }
105
106   public final class KeySet extends AbstractSet JavaDoc {
107     public Iterator JavaDoc iterator() {
108       return new ConcatenatedIterator(
109        myMap.keySet().iterator(),
110        new FilteringIterator(superMap.keySet(), keyNotInMyMap));
111     }
112     public int size() {
113       return NestedMap.this.size();
114     }
115     // No add; it's not meaningful.
116
public boolean contains(Object JavaDoc o) {
117       return NestedMap.this.containsKey(o);
118     }
119     public boolean remove(Object JavaDoc o) {
120       throw new UnsupportedOperationException JavaDoc(
121                "Remove from NestedMap.keySet");
122     }
123   }
124
125   private final class EntrySet extends AbstractSet JavaDoc {
126     public Iterator JavaDoc iterator() {
127       return new ConcatenatedIterator(
128       myMap.entrySet().iterator(),
129       new FilteringIterator(superMap.entrySet(), entryKeyNotInMyMap));
130     }
131     public int size() {
132       return NestedMap.this.size();
133     }
134     // No add; it's not meaningful.
135
public boolean contains(Object JavaDoc o) {
136       if (! (o instanceof Map.Entry JavaDoc)) return false;
137       Map.Entry JavaDoc ent = (Map.Entry JavaDoc) o;
138       Object JavaDoc entKey = ent.getKey();
139       Object JavaDoc entVal = ent.getValue();
140       if (entVal != null) {
141     Object JavaDoc val = NestedMap.this.get(entKey);
142     return (val != null) && val.equals(entVal);
143       } else {
144     return NestedMap.this.containsKey(entKey) &&
145       (NestedMap.this.get(entKey) == null);
146       }
147     }
148     public boolean remove(Object JavaDoc o) {
149       throw new UnsupportedOperationException JavaDoc(
150                "Remove from NestedMap.entrySet");
151     }
152   }
153  
154   private HashMap JavaDoc myMap;
155   private int nShadowed;
156   private Set JavaDoc setView; // the set view of this.
157
private Map JavaDoc superMap;
158   private Predicate entryKeyNotInMyMap = new Predicate() {
159     public boolean isTrue(Object JavaDoc o) {
160       Map.Entry JavaDoc ent = (Map.Entry JavaDoc) o;
161       return ! myMap.containsKey(ent.getKey());
162     }
163   };
164   private Predicate keyNotInMyMap = new Predicate() {
165     public boolean isTrue(Object JavaDoc o) {
166       return ! myMap.containsKey(o);
167     }
168   };
169
170 }
171
172
Popular Tags