KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > quartz > utils > DirtyFlagMap


1 /*
2  * Copyright 2004-2005 OpenSymphony
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy
6  * of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations
14  * under the License.
15  *
16  */

17
18 /*
19  * Previously Copyright (c) 2001-2004 James House
20  */

21 package org.quartz.utils;
22
23 import java.lang.reflect.Array JavaDoc;
24 import java.util.Collection JavaDoc;
25 import java.util.HashMap JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.Map JavaDoc;
28 import java.util.Set JavaDoc;
29
30 /**
31  * <p>
32  * An implementation of <code>Map</code> that wraps another <code>Map</code>
33  * and flags itself 'dirty' when it is modified.
34  * </p>
35  *
36  * @author James House
37  */

38 public class DirtyFlagMap implements Map JavaDoc, Cloneable JavaDoc, java.io.Serializable JavaDoc {
39
40     /*
41      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
42      *
43      * Data members.
44      *
45      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
46      */

47     private static final long serialVersionUID = 1433884852607126222L;
48
49     private boolean dirty = false;
50     private Map JavaDoc map;
51
52     /*
53      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
54      *
55      * Constructors.
56      *
57      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
58      */

59
60     /**
61      * <p>
62      * Create a DirtyFlagMap that 'wraps' a <code>HashMap</code>.
63      * </p>
64      *
65      * @see java.util.HashMap
66      */

67     public DirtyFlagMap() {
68         map = new HashMap JavaDoc();
69     }
70
71     /**
72      * <p>
73      * Create a DirtyFlagMap that 'wraps' a <code>HashMap</code> that has the
74      * given initial capacity.
75      * </p>
76      *
77      * @see java.util.HashMap
78      */

79     public DirtyFlagMap(int initialCapacity) {
80         map = new HashMap JavaDoc(initialCapacity);
81     }
82
83     /**
84      * <p>
85      * Create a DirtyFlagMap that 'wraps' a <code>HashMap</code> that has the
86      * given initial capacity and load factor.
87      * </p>
88      *
89      * @see java.util.HashMap
90      */

91     public DirtyFlagMap(int initialCapacity, float loadFactor) {
92         map = new HashMap JavaDoc(initialCapacity, loadFactor);
93     }
94
95     /*
96      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
97      *
98      * Interface.
99      *
100      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
101      */

102
103     /**
104      * <p>
105      * Clear the 'dirty' flag (set dirty flag to <code>false</code>).
106      * </p>
107      */

108     public void clearDirtyFlag() {
109         dirty = false;
110     }
111
112     /**
113      * <p>
114      * Determine whether the <code>Map</code> is flagged dirty.
115      * </p>
116      */

117     public boolean isDirty() {
118         return dirty;
119     }
120
121     /**
122      * <p>
123      * Get a direct handle to the underlying Map.
124      * </p>
125      */

126     public Map JavaDoc getWrappedMap() {
127         return map;
128     }
129
130     public void clear() {
131         if (map.isEmpty() == false) {
132             dirty = true;
133         }
134         
135         map.clear();
136     }
137
138     public boolean containsKey(Object JavaDoc key) {
139         return map.containsKey(key);
140     }
141
142     public boolean containsValue(Object JavaDoc val) {
143         return map.containsValue(val);
144     }
145
146     public Set JavaDoc entrySet() {
147         return new DirtyFlagMapEntrySet(map.entrySet());
148     }
149     
150     public boolean equals(Object JavaDoc obj) {
151         if (obj == null || !(obj instanceof DirtyFlagMap)) {
152             return false;
153         }
154
155         return map.equals(((DirtyFlagMap) obj).getWrappedMap());
156     }
157
158     public Object JavaDoc get(Object JavaDoc key) {
159         return map.get(key);
160     }
161
162     public boolean isEmpty() {
163         return map.isEmpty();
164     }
165
166     public Set JavaDoc keySet() {
167         return new DirtyFlagSet(map.keySet());
168     }
169
170     public Object JavaDoc put(Object JavaDoc key, Object JavaDoc val) {
171         dirty = true;
172
173         return map.put(key, val);
174     }
175
176     public void putAll(Map JavaDoc t) {
177         if (!t.isEmpty()) {
178             dirty = true;
179         }
180
181         map.putAll(t);
182     }
183
184     public Object JavaDoc remove(Object JavaDoc key) {
185         Object JavaDoc obj = map.remove(key);
186
187         if (obj != null) {
188             dirty = true;
189         }
190
191         return obj;
192     }
193
194     public int size() {
195         return map.size();
196     }
197
198     public Collection JavaDoc values() {
199         return new DirtyFlagCollection(map.values());
200     }
201
202     public Object JavaDoc clone() {
203         DirtyFlagMap copy;
204         try {
205             copy = (DirtyFlagMap) super.clone();
206             if (map instanceof HashMap JavaDoc) {
207                 copy.map = (Map JavaDoc)((HashMap JavaDoc)map).clone();
208             }
209         } catch (CloneNotSupportedException JavaDoc ex) {
210             throw new IncompatibleClassChangeError JavaDoc("Not Cloneable.");
211         }
212
213         return copy;
214     }
215     
216     /**
217      * Wrap a Collection so we can mark the DirtyFlagMap as dirty if
218      * the underlying Collection is modified.
219      */

220     private class DirtyFlagCollection implements Collection JavaDoc {
221         private Collection JavaDoc collection;
222         
223         public DirtyFlagCollection(Collection JavaDoc c) {
224             collection = c;
225         }
226
227         protected Collection JavaDoc getWrappedCollection() {
228             return collection;
229         }
230         
231         public Iterator JavaDoc iterator() {
232             return new DirtyFlagIterator(collection.iterator());
233         }
234
235         public boolean remove(Object JavaDoc o) {
236             boolean removed = collection.remove(o);
237             if (removed) {
238                 dirty = true;
239             }
240             return removed;
241         }
242
243         public boolean removeAll(Collection JavaDoc c) {
244             boolean changed = collection.removeAll(c);
245             if (changed) {
246                 dirty = true;
247             }
248             return changed;
249         }
250
251         public boolean retainAll(Collection JavaDoc c) {
252             boolean changed = collection.retainAll(c);
253             if (changed) {
254                 dirty = true;
255             }
256             return changed;
257         }
258
259         public void clear() {
260             if (collection.isEmpty() == false) {
261                 dirty = true;
262             }
263             collection.clear();
264         }
265         
266         // Pure wrapper methods
267
public int size() { return collection.size(); }
268         public boolean isEmpty() { return collection.isEmpty(); }
269         public boolean contains(Object JavaDoc o) { return collection.contains(o); }
270         public boolean add(Object JavaDoc o) { return add(o); } // Not supported
271
public boolean addAll(Collection JavaDoc c) { return collection.addAll(c); } // Not supported
272
public boolean containsAll(Collection JavaDoc c) { return collection.containsAll(c); }
273         public Object JavaDoc[] toArray() { return collection.toArray(); }
274         public Object JavaDoc[] toArray(Object JavaDoc[] array) { return collection.toArray(array); }
275     }
276     
277     /**
278      * Wrap a Set so we can mark the DirtyFlagMap as dirty if
279      * the underlying Collection is modified.
280      */

281     private class DirtyFlagSet extends DirtyFlagCollection implements Set JavaDoc {
282         public DirtyFlagSet(Set JavaDoc set) {
283             super(set);
284         }
285         
286         protected Set JavaDoc getWrappedSet() {
287             return (Set JavaDoc)getWrappedCollection();
288         }
289     }
290     
291     /**
292      * Wrap an Iterator so that we can mark the DirtyFlagMap as dirty if an
293      * element is removed.
294      */

295     private class DirtyFlagIterator implements Iterator JavaDoc {
296         private Iterator JavaDoc iterator;
297         
298         public DirtyFlagIterator(Iterator JavaDoc iterator) {
299             this.iterator = iterator;
300         }
301         
302         public void remove() {
303             dirty = true;
304             iterator.remove();
305         }
306         
307         // Pure wrapper methods
308
public boolean hasNext() { return iterator.hasNext(); }
309         public Object JavaDoc next() { return iterator.next(); }
310     }
311
312     /**
313      * Wrap a Map.Entry Set so we can mark the Map as dirty if
314      * the Set is modified, and return Map.Entry objects
315      * wrapped in the <code>DirtyFlagMapEntry</code> class.
316      */

317     private class DirtyFlagMapEntrySet extends DirtyFlagSet {
318         
319         public DirtyFlagMapEntrySet(Set JavaDoc set) {
320             super(set);
321         }
322         
323         public Iterator JavaDoc iterator() {
324             return new DirtyFlagMapEntryIterator(getWrappedSet().iterator());
325         }
326
327         public Object JavaDoc[] toArray() {
328             return toArray(new Object JavaDoc[super.size()]);
329         }
330
331         public Object JavaDoc[] toArray(Object JavaDoc[] array) {
332             if (array.getClass().getComponentType().isAssignableFrom(Map.Entry JavaDoc.class) == false) {
333                 throw new IllegalArgumentException JavaDoc("Array must be of type assignable from Map.Entry");
334             }
335             
336             int size = super.size();
337             
338             Object JavaDoc[] result =
339                 (array.length < size) ?
340                     (Object JavaDoc[])Array.newInstance(array.getClass().getComponentType(), size) : array;
341
342             Iterator JavaDoc entryIter = iterator(); // Will return DirtyFlagMapEntry objects
343
for (int i = 0; i < size; i++) {
344                 result[i] = entryIter.next();
345             }
346             
347             if (result.length > size) {
348                 result[size] = null;
349             }
350             
351             return result;
352         }
353     }
354     
355     /**
356      * Wrap an Iterator over Map.Entry objects so that we can
357      * mark the Map as dirty if an element is removed or modified.
358      */

359     private class DirtyFlagMapEntryIterator extends DirtyFlagIterator {
360         public DirtyFlagMapEntryIterator(Iterator JavaDoc iterator) {
361             super(iterator);
362         }
363         
364         public Object JavaDoc next() {
365             return new DirtyFlagMapEntry((Map.Entry JavaDoc)super.next());
366         }
367     }
368     
369     /**
370      * Wrap a Map.Entry so we can mark the Map as dirty if
371      * a value is set.
372      */

373     private class DirtyFlagMapEntry implements Map.Entry JavaDoc {
374         private Map.Entry JavaDoc entry;
375         
376         public DirtyFlagMapEntry(Map.Entry JavaDoc entry) {
377             this.entry = entry;
378         }
379         
380         public Object JavaDoc setValue(Object JavaDoc o) {
381             dirty = true;
382             return entry.setValue(o);
383         }
384         
385         // Pure wrapper methods
386
public Object JavaDoc getKey() { return entry.getKey(); }
387         public Object JavaDoc getValue() { return entry.getValue(); }
388     }
389 }
Popular Tags