KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > portal > generic > StoreUpdateMap


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  * Copyright (c) 2001-2004 Caucho Technology, Inc. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  *
18  * 3. The end-user documentation included with the redistribution, if
19  * any, must include the following acknowlegement:
20  * "This product includes software developed by the
21  * Caucho Technology (http://www.caucho.com/)."
22  * Alternately, this acknowlegement may appear in the software itself,
23  * if and wherever such third-party acknowlegements normally appear.
24  *
25  * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
26  * endorse or promote products derived from this software without prior
27  * written permission. For written permission, please contact
28  * info@caucho.com.
29  *
30  * 5. Products derived from this software may not be called "Resin"
31  * nor may "Resin" appear in their names without prior written
32  * permission of Caucho Technology.
33  *
34  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
35  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
36  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37  * DISCLAIMED. IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
38  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
39  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
40  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
41  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
42  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
43  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
44  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45  *
46  * @author Sam
47  */

48
49 package com.caucho.portal.generic;
50
51 import java.util.*;
52 import java.util.logging.Logger JavaDoc;
53
54 public class StoreUpdateMap<K, V> implements Map<K, V>
55 {
56   static protected final Logger JavaDoc log =
57     Logger.getLogger(StoreUpdateMap.class.getName());
58
59   private Map<K, K> _nameLinkMap;
60   private Map<K, K> _reverseNameLinkMap;
61   private Map<K, V> _storeMapUnlinked;
62   private Map<K, V> _storeMap;
63   private Map<K, V> _defaultMap;
64   private Set<K> _names;
65   private V _deletedValue;
66
67   private Set<K> _keySet;
68   private boolean _keySetModifiable;
69   private Map<K, V> _updateMapUnlinked;
70   private Map<K, V> _updateMap;
71
72   void start( Map<K, K> nameLinkMap,
73               Map<K, K> reverseNameLinkMap,
74               Map<K, V> defaultMap,
75               Map<K, V> storeMap,
76               Set<K> names,
77               V deletedValue )
78   {
79     if (_defaultMap != null || _storeMap != null)
80       throw new IllegalStateException JavaDoc("missing finish()?");
81
82     _nameLinkMap = nameLinkMap;
83     _reverseNameLinkMap = reverseNameLinkMap;
84
85     if (nameLinkMap != null) {
86       _defaultMap = new KeyLinkMap<K, V>( defaultMap,
87                                           _nameLinkMap,
88                                           _reverseNameLinkMap );
89       _storeMapUnlinked = storeMap;
90       _storeMap = new KeyLinkMap<K, V>( storeMap,
91                                         _nameLinkMap,
92                                         _reverseNameLinkMap );
93     }
94     else {
95       _defaultMap = defaultMap;
96       _storeMapUnlinked = storeMap;
97       _storeMap = storeMap;
98     }
99
100     _names = names;
101     _deletedValue = deletedValue;
102   }
103
104   void finish()
105   {
106     _updateMap = null;
107     _updateMapUnlinked = null;
108     _keySet = null;
109     _keySetModifiable = false;
110
111     _nameLinkMap = null;
112     _defaultMap = null;
113     _storeMapUnlinked = null;
114     _storeMap = null;
115     _names = null;
116   }
117
118   Map<K, V> getStoreMap()
119   {
120     return _storeMapUnlinked;
121   }
122
123   Map<K, V> getUpdateMap()
124   {
125     return _updateMapUnlinked;
126   }
127
128   private Set<K> getKeySet(boolean modifiable)
129   {
130
131     if (!modifiable) {
132       if (_keySet != null)
133         return _keySet;
134
135       while (true) {
136         Set<K> keySet = _names;
137
138         if (_defaultMap != null) {
139           if (keySet != null)
140             break;
141           else
142             keySet = _defaultMap.keySet();
143         }
144
145         if (_storeMap != null) {
146           if (keySet != null)
147             break;
148           else
149             keySet = _storeMap.keySet();
150         }
151
152         if (_updateMap != null) {
153           if (keySet != null)
154             break;
155           else
156             keySet = _updateMap.keySet();
157         }
158       }
159     }
160
161     if (_keySetModifiable)
162       return _keySet;
163
164     _keySet = new HashSet<K>();
165     _keySetModifiable = true;
166
167     if (_names != null) {
168       Iterator<K> iter = _names.iterator();
169
170       while (iter.hasNext()) {
171         K key = iter.next();
172
173         if ((_storeMap != null && _storeMap.containsKey(key))
174             ||
175             (_defaultMap != null && _defaultMap.containsKey(key)))
176         {
177           _keySet.add(key);
178         }
179       }
180     }
181     else {
182       if (_defaultMap != null)
183         _keySet.addAll(_defaultMap.keySet());
184
185       if (_storeMap != null)
186         _keySet.addAll(_storeMap.keySet());
187     }
188
189
190     return _keySet;
191   }
192
193   public int size()
194   {
195     return getKeySet(false).size();
196   }
197
198   public boolean isEmpty()
199   {
200     return getKeySet(false).isEmpty();
201   }
202
203   public boolean containsKey(Object JavaDoc key)
204   {
205     return getKeySet(false).contains(key);
206   }
207
208   public V get(Object JavaDoc key)
209   {
210     if (!getKeySet(false).contains(key))
211       return null;
212
213     if (_updateMap != null && _updateMap.containsKey(key)) {
214       V v = _updateMap.get(key);
215
216       return v;
217     } else if (_storeMap != null && _storeMap.containsKey(key))
218       return _storeMap.get(key);
219     else if (_defaultMap != null)
220       return _defaultMap.get(key);
221     else
222       return null;
223   }
224
225   public Set<K> keySet()
226   {
227     return getKeySet(false);
228   }
229
230   public boolean containsValue(Object JavaDoc v)
231   {
232     Iterator<K> iter = _keySet.iterator();
233
234     while (iter.hasNext()) {
235       K key = iter.next();
236       V value = get(key);
237
238       if (value == null) {
239         if (v == null)
240           return true;
241       }
242       else {
243         if (value.equals(v))
244           return true;
245       }
246     }
247
248     return false;
249   }
250
251   public Collection<V> values()
252   {
253     LinkedList<V> values = new LinkedList<V>();
254
255     Iterator<K> iter = getKeySet(false).iterator();
256
257     while (iter.hasNext()) {
258       K key = iter.next();
259       V value = get(key);
260
261       values.add(value);
262     }
263
264     return values;
265   }
266
267   public Set<Map.Entry<K, V>> entrySet()
268   {
269     // XXX: better implemented as custom class extending AbstractSet
270
LinkedHashMap<K, V> map = new LinkedHashMap<K, V>();
271
272     Iterator<K> iter = getKeySet(false).iterator();
273
274     while (iter.hasNext()) {
275       K key = iter.next();
276       V value = get(key);
277
278       map.put(key, value);
279     }
280
281     return map.entrySet();
282   }
283
284   private void makeUpdateMap()
285   {
286     if (_updateMap == null) {
287       _updateMapUnlinked = new LinkedHashMap<K, V>();
288       if (_nameLinkMap != null)
289         _updateMap = new KeyLinkMap<K, V>( _updateMapUnlinked,
290                                            _nameLinkMap,
291                                            _reverseNameLinkMap );
292       else
293         _updateMap = _updateMapUnlinked;
294     }
295   }
296
297   public V put(K key, V value)
298   {
299     if (_names != null && !_names.contains(key))
300       throw new IllegalArgumentException JavaDoc(
301           "attribute name `" + key + "' not allowed");
302
303     makeUpdateMap();
304
305     Set<K> keySet = getKeySet(false);
306
307     if (!keySet.contains(key)) {
308       if (keySet != _updateMap.keySet())
309         keySet = getKeySet(true);
310
311       if (value != _deletedValue)
312         keySet.add(key);
313     }
314
315     V oldValue = _updateMap.put(key, value);
316
317     if (oldValue == _deletedValue)
318       oldValue = null;
319
320     return oldValue;
321   }
322
323   public void putAll(Map<? extends K, ? extends V> srcMap)
324   {
325     Iterator<? extends Entry<? extends K, ? extends V>> iter
326       = srcMap.entrySet().iterator();
327
328     while (iter.hasNext()) {
329       Map.Entry<? extends K, ? extends V> entry = iter.next();
330       put(entry.getKey(), entry.getValue());
331     }
332   }
333
334   public V remove(Object JavaDoc key)
335   {
336     Set<K> keySet = getKeySet(false);
337
338     V oldValue = null;
339
340     if (keySet.contains(key)) {
341       oldValue = put( (K) key, _deletedValue);
342       getKeySet(true).remove(key);
343     }
344
345     return oldValue;
346   }
347
348   public void clear()
349   {
350     Iterator<K> iter = getKeySet(true).iterator();
351
352     while (iter.hasNext()) {
353       K key = iter.next();
354
355       if (_storeMap != null && _storeMap.containsKey(key))
356         put(key, _deletedValue);
357       else if (_updateMap != null)
358         _updateMap.remove(key);
359
360       iter.remove();
361     }
362   }
363 }
364
365
Popular Tags