001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tcclient.util;
005:
006: import com.tc.object.SerializationUtil;
007: import com.tc.object.bytecode.ManagerUtil;
008:
009: import java.lang.reflect.Array;
010: import java.util.Collection;
011: import java.util.Iterator;
012: import java.util.Map;
013: import java.util.Set;
014: import java.util.Map.Entry;
015:
016: /**
017: * A wrapper for Map.entrySet() that keeps DSO informed of changes
018: */
019: public class MapEntrySetWrapper implements Set {
020: public final static String CLASS_SLASH = "com/tcclient/util/MapEntrySetWrapper";
021:
022: protected final Set realEntrySet;
023: protected final Map map;
024:
025: public MapEntrySetWrapper(Map map, Set realEntrySet) {
026: this .realEntrySet = realEntrySet;
027: this .map = map;
028: }
029:
030: public final boolean add(Object o) {
031: return realEntrySet.add(o);
032: }
033:
034: public final boolean addAll(Collection c) {
035: return realEntrySet.addAll(c);
036: }
037:
038: public final void clear() {
039: realEntrySet.clear();
040: }
041:
042: public final boolean contains(Object o) {
043: return realEntrySet.contains(o);
044: }
045:
046: public final boolean containsAll(Collection c) {
047: return realEntrySet.containsAll(c);
048: }
049:
050: public final boolean equals(Object o) {
051: return realEntrySet.equals(o);
052: }
053:
054: public final int hashCode() {
055: return realEntrySet.hashCode();
056: }
057:
058: public final boolean isEmpty() {
059: return realEntrySet.isEmpty();
060: }
061:
062: public Iterator iterator() {
063: return new IteratorWrapper(map, realEntrySet.iterator());
064: }
065:
066: public boolean remove(Object o) {
067: ManagerUtil.checkWriteAccess(map);
068: boolean removed = realEntrySet.remove(o);
069: if (removed) {
070: ManagerUtil.logicalInvoke(map,
071: SerializationUtil.REMOVE_KEY_SIGNATURE,
072: new Object[] { ((Map.Entry) o).getKey() });
073: }
074: return removed;
075: }
076:
077: public final boolean removeAll(Collection c) {
078: boolean modified = false;
079:
080: if (size() > c.size()) {
081: for (Iterator i = c.iterator(); i.hasNext();)
082: modified |= remove(i.next());
083: } else {
084: for (Iterator i = iterator(); i.hasNext();) {
085: if (c.contains(i.next())) {
086: i.remove();
087: modified = true;
088: }
089: }
090: }
091: return modified;
092: }
093:
094: public final boolean retainAll(Collection c) {
095: boolean modified = false;
096: Iterator i = iterator();
097: while (i.hasNext()) {
098: if (!c.contains(i.next())) {
099: i.remove();
100: modified = true;
101: }
102: }
103: return modified;
104:
105: }
106:
107: public final int size() {
108: return realEntrySet.size();
109: }
110:
111: public final Object[] toArray() {
112: return realEntrySet.toArray();
113: }
114:
115: public final Object[] toArray(Object[] a) {
116: int size = size();
117: if (a.length < size)
118: a = (Object[]) Array.newInstance(((Object) (a)).getClass()
119: .getComponentType(), size);
120:
121: int index = 0;
122: for (Iterator iterator = iterator(); iterator.hasNext();) {
123: ManagerUtil.objectArrayChanged(a, index++, iterator.next());
124: }
125:
126: if (a.length > size) {
127: ManagerUtil.objectArrayChanged(a, size, null);
128: }
129: return a;
130: }
131:
132: private static class IteratorWrapper implements Iterator {
133:
134: protected final Iterator realIterator;
135: protected final Map map;
136: protected Entry current;
137:
138: IteratorWrapper(Map map, Iterator realIterator) {
139: this .map = map;
140: this .realIterator = realIterator;
141: }
142:
143: public void remove() {
144: ManagerUtil.checkWriteAccess(map);
145: realIterator.remove();
146:
147: // important to do this after the real remove() since an exception can be thrown (never
148: // started, at end, concurrent mod, etc)
149: ManagerUtil.logicalInvoke(map,
150: SerializationUtil.REMOVE_KEY_SIGNATURE,
151: new Object[] { current.getKey() });
152: }
153:
154: public final boolean hasNext() {
155: boolean rv = realIterator.hasNext();
156: return rv;
157: }
158:
159: public final Object next() {
160: current = new EntryWrapper(map, (Entry) realIterator.next());
161: return current;
162: }
163:
164: }
165:
166: protected static class EntryWrapper implements Entry {
167: private final Object key;
168: private Object value;
169: private final Map map;
170:
171: EntryWrapper(Map map, Entry entry) {
172: this .map = map;
173: this .key = entry.getKey();
174: this .value = entry.getValue();
175: }
176:
177: public final boolean equals(Object o) {
178: if (!(o instanceof Entry)) {
179: return false;
180: }
181: Entry e2 = (Entry) o;
182: return (key == null ? e2.getKey() == null : key.equals(e2
183: .getKey()))
184: && (value == null ? e2.getValue() == null : value
185: .equals(e2.getValue()));
186: }
187:
188: public final Object getKey() {
189: return key;
190: }
191:
192: public final Object getValue() {
193: return value;
194: }
195:
196: public final int hashCode() {
197: return (key == null ? 0 : key.hashCode())
198: ^ (value == null ? 0 : value.hashCode());
199: }
200:
201: public final Object setValue(Object value) {
202: Object rv = map.put(this .key, value);
203: this .value = value;
204: return rv;
205: }
206:
207: public String toString() {
208: return key + "=" + value;
209: }
210: }
211:
212: }
|