comparison src/com/go/trove/util/NullKeyMap.java @ 0:3dc0c5604566

Initial checkin of blitz 2.0 fcs - no installer yet.
author Dan Creswell <dan.creswell@gmail.com>
date Sat, 21 Mar 2009 11:00:06 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:3dc0c5604566
1 /* ====================================================================
2 * Trove - Copyright (c) 1997-2000 Walt Disney Internet Group
3 * ====================================================================
4 * The Tea Software License, Version 1.1
5 *
6 * Copyright (c) 2000 Walt Disney Internet Group. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. The end-user documentation included with the redistribution,
21 * if any, must include the following acknowledgment:
22 * "This product includes software developed by the
23 * Walt Disney Internet Group (http://opensource.go.com/)."
24 * Alternately, this acknowledgment may appear in the software itself,
25 * if and wherever such third-party acknowledgments normally appear.
26 *
27 * 4. The names "Tea", "TeaServlet", "Kettle", "Trove" and "BeanDoc" must
28 * not be used to endorse or promote products derived from this
29 * software without prior written permission. For written
30 * permission, please contact opensource@dig.com.
31 *
32 * 5. Products derived from this software may not be called "Tea",
33 * "TeaServlet", "Kettle" or "Trove", nor may "Tea", "TeaServlet",
34 * "Kettle", "Trove" or "BeanDoc" appear in their name, without prior
35 * written permission of the Walt Disney Internet Group.
36 *
37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40 * DISCLAIMED. IN NO EVENT SHALL THE WALT DISNEY INTERNET GROUP OR ITS
41 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
42 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
43 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
44 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
45 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
47 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * For more information about Tea, please see http://opensource.go.com/.
51 */
52
53 package com.go.trove.util;
54
55 import java.util.*;
56 import java.io.Serializable;
57
58 /******************************************************************************
59 * A Map supporting null keys that wraps a Map that doesn't support null keys.
60 * NullKeyMap substitutes null keys with a special placeholder object. This
61 * technique does not work when the wrapped Map is a TreeMap because it cannot
62 * be compared against other objects. In order for TreeMaps to support null
63 * keys, use any of the null ordering comparators found in the {@link Utils}
64 * class.
65 *
66 * @author Brian S O'Neill
67 * @version
68 * <!--$$Revision: 1.1 $-->, <!--$$JustDate:--> 9/07/00 <!-- $-->
69 */
70 public class NullKeyMap extends AbstractMap implements Serializable {
71 // Instead of using null as a key, use this placeholder.
72 private static final Object NULL = new Serializable() {};
73
74 private Map mMap;
75
76 private transient Set mKeySet;
77 private transient Set mEntrySet;
78
79 /**
80 * @param map The map to wrap.
81 */
82 public NullKeyMap(Map map) {
83 mMap = map;
84 }
85
86 public int size() {
87 return mMap.size();
88 }
89
90 public boolean isEmpty() {
91 return mMap.isEmpty();
92 }
93
94 public boolean containsKey(Object key) {
95 return (key == null) ? mMap.containsKey(NULL) : mMap.containsKey(key);
96 }
97
98 public boolean containsValue(Object value) {
99 return mMap.containsValue(value);
100 }
101
102 public Object get(Object key) {
103 return (key == null) ? mMap.get(NULL) : mMap.get(key);
104 }
105
106 public Object put(Object key, Object value) {
107 return mMap.put((key == null) ? NULL : key, value);
108 }
109
110 public Object remove(Object key) {
111 return (key == null) ? mMap.remove(NULL) : mMap.remove(key);
112 }
113
114 public void putAll(Map map) {
115 Iterator it = map.entrySet().iterator();
116 while (it.hasNext()) {
117 Map.Entry entry = (Map.Entry)it.next();
118 put(entry.getKey(), entry.getValue());
119 }
120 }
121
122 public void clear() {
123 mMap.clear();
124 }
125
126 public Set keySet() {
127 if (mKeySet == null) {
128 mKeySet = new AbstractSet() {
129 public Iterator iterator() {
130 final Iterator it = mMap.keySet().iterator();
131
132 return new Iterator() {
133 public boolean hasNext() {
134 return it.hasNext();
135 }
136
137 public Object next() {
138 Object key = it.next();
139 return (key == NULL) ? null : key;
140 }
141
142 public void remove() {
143 it.remove();
144 }
145 };
146 }
147
148 public boolean contains(Object key) {
149 return containsKey((key == null) ? NULL : key);
150 }
151
152 public boolean remove(Object key) {
153 if (key == null) {
154 key = NULL;
155 }
156 if (containsKey(key)) {
157 NullKeyMap.this.remove(key);
158 return true;
159 }
160 else {
161 return false;
162 }
163 }
164
165 public int size() {
166 return NullKeyMap.this.size();
167 }
168
169 public void clear() {
170 NullKeyMap.this.clear();
171 }
172 };
173 }
174
175 return mKeySet;
176 }
177
178 public Collection values() {
179 return mMap.values();
180 }
181
182 public Set entrySet() {
183 if (mEntrySet == null) {
184 mEntrySet = new AbstractSet() {
185 public Iterator iterator() {
186 final Iterator it = mMap.entrySet().iterator();
187
188 return new Iterator() {
189 public boolean hasNext() {
190 return it.hasNext();
191 }
192
193 public Object next() {
194 final Map.Entry entry = (Map.Entry)it.next();
195 if (entry.getKey() == NULL) {
196 return new AbstractMapEntry() {
197 public Object getKey() {
198 return null;
199 }
200
201 public Object getValue() {
202 return entry.getValue();
203 }
204
205 public Object setValue(Object value) {
206 return entry.setValue(value);
207 }
208 };
209 }
210 else {
211 return entry;
212 }
213 }
214
215 public void remove() {
216 it.remove();
217 }
218 };
219 }
220
221 public boolean contains(Object obj) {
222 if (!(obj instanceof Map.Entry)) {
223 return false;
224 }
225 Map.Entry entry = (Map.Entry)obj;
226 Object key = entry.getKey();
227 Object value = entry.getValue();
228 if (key == null) {
229 key = NULL;
230 }
231 Object lookup = get(key);
232 if (lookup == null) {
233 return value == null;
234 }
235 else {
236 return lookup.equals(value);
237 }
238 }
239
240 public boolean remove(Object obj) {
241 if (!(obj instanceof Map.Entry)) {
242 return false;
243 }
244 Map.Entry entry = ((Map.Entry)obj);
245 Object key = entry.getKey();
246 if (key == null) {
247 key = NULL;
248 }
249 if (containsKey(key)) {
250 NullKeyMap.this.remove(key);
251 return true;
252 }
253 else {
254 return false;
255 }
256 }
257
258 public int size() {
259 return NullKeyMap.this.size();
260 }
261
262 public void clear() {
263 NullKeyMap.this.clear();
264 }
265 };
266 }
267
268 return mEntrySet;
269 }
270 }