Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: jtemporal/PublishedSortedMap.java


1   /*
2      Copyright (C) 2002 Thomas A Beck (http://thomas.beck.name)
3   
4      This library is free software; you can redistribute it and/or
5      modify it under the terms of the GNU Lesser General Public
6      License as published by the Free Software Foundation; either
7      version 2.1 of the License, or (at your option) any later version.
8   
9      This library is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12     Lesser General Public License for more details.
13  
14     You should have received a copy of the GNU Lesser General Public
15     License along with this library; if not, write to the Free Software
16     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA    */
17  
18  package jtemporal;
19  
20  import java.util.SortedMap;
21  import java.util.Comparator;
22  import java.util.Map;
23  import java.util.Set;
24  import java.util.Collection;
25  import java.util.AbstractSet;
26  import java.util.Iterator;
27  import java.util.NoSuchElementException;
28  import java.util.AbstractMap;
29  
30  /**
31   * Decorates a SortedMap allowing a single third object to subscribe to updates.
32   * That's more efficient in terms of performance than using events and listeners.
33   * If you need events and multiple listener, you need to create an intermediate
34   * map subscriber class, which creates and dispatches the events.  <BR>
35   * This class is optimized for the jtemporal use, that's
36   * why the class is not public (also some methods not used by JTemporal are not
37   * implemented). However with minimal changes, this class can become generic.
38   * @author Thomas Beck
39   * @version $Id$
40   */
41  
42  class PublishedSortedMap implements SortedMap {
43  
44    private final SortedMap map;
45    private final MapSubscriber subscriber;
46  
47    // compulsory constructor
48    public PublishedSortedMap(SortedMap decoratedMap, MapSubscriber sub) {
49        this.map = decoratedMap;
50        this.subscriber = sub;
51    }
52  
53    //accessors
54    public SortedMap getDecoratedMap() {
55      return this.map;
56    }
57    public MapSubscriber getSubscriber() {
58      return this.subscriber;
59    }
60  
61    // notifications
62    private void firePut(Object key, Object value) {
63      this.subscriber.put(this, key, value);
64    }
65  
66    private void fireRemoved(Object key) {
67      this.subscriber.removed(this, key);
68    }
69  
70  
71    // read-only methods
72  
73    public Comparator comparator() {
74      return this.map.comparator();
75    }
76    public Object firstKey() {
77      return this.map.firstKey();
78    }
79    public Object lastKey() {
80      return this.map.lastKey();
81    }
82    public int size() {
83      return this.map.size();
84    }
85    public boolean isEmpty() {
86      return this.map.isEmpty();
87    }
88    public boolean containsKey(Object key) {
89      return this.map.containsKey(key);
90    }
91    public boolean containsValue(Object value) {
92      return this.map.containsValue(value);
93    }
94    public Object get(Object key) {
95      return this.map.get(key);
96    }
97    public boolean equals(Object o) {
98      return this.map.equals(o);
99    }
100   public int hashCode() {
101     return this.map.hashCode();
102   }
103 
104 
105   // submaps
106 
107   public SortedMap subMap(Object fromKey, Object toKey) {
108     SortedMap subMap = this.map.subMap(fromKey, toKey);
109     return new PublishedSortedMap(subMap, this.subscriber);
110   }
111   public SortedMap headMap(Object toKey) {
112     SortedMap subMap = this.map.headMap(toKey);
113     return new PublishedSortedMap(subMap, this.subscriber);
114   }
115   public SortedMap tailMap(Object fromKey) {
116     SortedMap subMap = this.map.tailMap(fromKey);
117     return new PublishedSortedMap(subMap, this.subscriber);
118   }
119 
120 
121   // changes
122 
123   public Object put(Object key, Object value) {
124     Object replaced = this.map.put(key, value);
125     this.firePut(key, value);
126     return replaced;
127   }
128   public Object remove(Object key) {
129     Object removed = this.map.remove(key);
130     this.fireRemoved(key);
131     return removed;
132   }
133 
134   /**
135    * Internaly, instead caling clear(); this method iterates and removes all the
136    * elements one by one.  That allows a subscriber to receive the detail of the
137    * deletions.
138    */
139   public void clear() {
140     Iterator i = this.keySet().iterator();
141     while (i.hasNext()) {
142       i.next();
143       i.remove();
144     }
145     //consistency check
146     if (this.map.size() != 0) {
147       // should never happen
148       throw new IllegalStateException("The published SortedMap is inconsistent");
149     }
150   }
151   public void putAll(Map t) {
152     Iterator i = t.entrySet().iterator();
153     while (i.hasNext()) {
154       Map.Entry e = (Map.Entry) i.next();
155       put(e.getKey(), e.getValue());
156     }
157   }
158   public Set keySet() {
159     Set decSet = this.map.keySet();
160     return new PublishedSortedMap.KeySet(decSet);
161   }
162   public Collection values() {
163     // not used by JTemporal
164     // must be implemented if used outside JTemporal
165     throw new UnsupportedOperationException();
166     //return this.map.values();
167   }
168   public Set entrySet() {
169     // not used by JTemporal
170     // must be implemented if used outside JTemporal
171     throw new UnsupportedOperationException();
172     //return this.map.entrySet();
173   }
174 
175 
176   private class KeySet extends AbstractSet
177   {
178     final Set decSet;
179 
180     public KeySet(Set decoratedSet) {
181       this.decSet = decoratedSet;
182     }
183 
184     public int size() {
185       return this.decSet.size();
186     }
187     public boolean isEmpty() {
188       return this.decSet.isEmpty();
189     }
190     public boolean contains(Object o) {
191       return this.decSet.contains(o);
192     }
193 
194     public boolean remove(Object o) {
195       boolean b = this.decSet.remove(o);
196       PublishedSortedMap.this.fireRemoved(o);
197       return b;
198     }
199 
200     public Iterator iterator() {
201       Iterator decIterator = this.decSet.iterator();
202       return new SetIterator(decIterator);
203     } // iterator()
204 
205     private class SetIterator implements Iterator
206     {
207       private final Iterator decIterator;
208       private Object lastRead = null;
209 
210       SetIterator(Iterator decoratedIterator) {
211   this.decIterator = decoratedIterator;
212       }
213 
214       public boolean hasNext() {
215   return decIterator.hasNext();
216       }
217 
218       public Object next() {
219   return lastRead = decIterator.next();
220       }
221 
222       public void remove() {
223   decIterator.remove();
224   PublishedSortedMap.this.fireRemoved(lastRead);
225       }
226 
227     } // SetIterator
228 
229 
230   } // class KeySet */
231 
232 } // class PublishedSortedMap