source: josm/trunk/src/org/openstreetmap/josm/data/osm/ChangesetCache.java@ 3083

Last change on this file since 3083 was 3083, checked in by bastiK, 14 years ago

added svn:eol-style=native to source files

  • Property svn:eol-style set to native
File size: 6.4 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.osm;
3
4import java.util.ArrayList;
5import java.util.Collection;
6import java.util.HashMap;
7import java.util.HashSet;
8import java.util.List;
9import java.util.Map;
10import java.util.Set;
11import java.util.concurrent.CopyOnWriteArrayList;
12import java.util.logging.Logger;
13
14import javax.swing.SwingUtilities;
15
16import org.openstreetmap.josm.Main;
17import org.openstreetmap.josm.data.Preferences.PreferenceChangeEvent;
18import org.openstreetmap.josm.data.Preferences.PreferenceChangedListener;
19
20/**
21 * ChangesetCache is global in-memory cache for changesets downloaded from
22 * an OSM API server. The unique instance is available as singleton, see
23 * {@see #getInstance()}.
24 *
25 * Clients interested in cache updates can register for {@see ChangesetCacheEvent}s
26 * using {@see #addChangesetCacheListener(ChangesetCacheListener)}. They can use
27 * {@see #removeChangesetCacheListener(ChangesetCacheListener)} to unregister as
28 * cache event listener.
29 *
30 * The cache itself listens to {@see java.util.prefs.PreferenceChangeEvent}s. It
31 * clears itself if the OSM API URL is changed in the preferences.
32 *
33 * {@see ChangesetCacheEvent}s are delivered on the EDT.
34 *
35 */
36public class ChangesetCache implements PreferenceChangedListener{
37 @SuppressWarnings("unused")
38 static private final Logger logger = Logger.getLogger(ChangesetCache.class.getName());
39
40 /** the unique instance */
41 static private final ChangesetCache instance = new ChangesetCache();
42
43 /**
44 * Replies the unique instance of the cache
45 *
46 * @return the unique instance of the cache
47 */
48 public static ChangesetCache getInstance() {
49 return instance;
50 }
51
52 /** the cached changesets */
53 private final Map<Integer, Changeset> cache = new HashMap<Integer, Changeset>();
54
55 private final CopyOnWriteArrayList<ChangesetCacheListener> listeners =
56 new CopyOnWriteArrayList<ChangesetCacheListener>();
57
58 private ChangesetCache() {
59 Main.pref.addPreferenceChangeListener(this);
60 }
61
62 public void addChangesetCacheListener(ChangesetCacheListener listener) {
63 listeners.addIfAbsent(listener);
64 }
65
66 public void removeChangesetCacheListener(ChangesetCacheListener listener) {
67 listeners.remove(listener);
68 }
69
70 protected void fireChangesetCacheEvent(final ChangesetCacheEvent e) {
71 Runnable r = new Runnable() {
72 public void run() {
73 for(ChangesetCacheListener l: listeners) {
74 l.changesetCacheUpdated(e);
75 }
76 }
77 };
78 if (SwingUtilities.isEventDispatchThread()) {
79 r.run();
80 } else {
81 SwingUtilities.invokeLater(r);
82 }
83 }
84
85 protected void update(Changeset cs, DefaultChangesetCacheEvent e) {
86 if (cs == null) return;
87 if (cs.isNew()) return;
88 Changeset inCache = cache.get(cs.getId());
89 if (inCache != null) {
90 inCache.mergeFrom(cs);
91 e.rememberUpdatedChangeset(inCache);
92 } else {
93 e.rememberAddedChangeset(cs);
94 cache.put(cs.getId(), cs);
95 }
96 }
97
98 public void update(Changeset cs) {
99 DefaultChangesetCacheEvent e = new DefaultChangesetCacheEvent(this);
100 update(cs, e);
101 fireChangesetCacheEvent(e);
102 }
103
104 public void update(Collection<Changeset> changesets) {
105 if (changesets == null || changesets.isEmpty()) return;
106 DefaultChangesetCacheEvent e = new DefaultChangesetCacheEvent(this);
107 for (Changeset cs: changesets) {
108 update(cs, e);
109 }
110 fireChangesetCacheEvent(e);
111 }
112
113 public boolean contains(int id) {
114 if (id <=0) return false;
115 return cache.get(id) != null;
116 }
117
118 public boolean contains(Changeset cs) {
119 if (cs == null) return false;
120 if (cs.isNew()) return false;
121 return contains(cs.getId());
122 }
123
124 public Changeset get(int id) {
125 return cache.get(id);
126 }
127
128 public Set<Changeset> getChangesets() {
129 return new HashSet<Changeset>(cache.values());
130 }
131
132 protected void remove(int id, DefaultChangesetCacheEvent e) {
133 if (id <= 0) return;
134 Changeset cs = cache.get(id);
135 if (cs == null) return;
136 cache.remove(id);
137 e.rememberRemovedChangeset(cs);
138 }
139
140 public void remove(int id) {
141 DefaultChangesetCacheEvent e = new DefaultChangesetCacheEvent(this);
142 remove(id, e);
143 if (! e.isEmpty()) {
144 fireChangesetCacheEvent(e);
145 }
146 }
147
148 public void remove(Changeset cs) {
149 if (cs == null) return;
150 if (cs.isNew()) return;
151 remove(cs.getId());
152 }
153
154 /**
155 * Removes the changesets in <code>changesets</code> from the cache. A
156 * {@see ChangesetCacheEvent} is fired.
157 *
158 * @param changesets the changesets to remove. Ignored if null.
159 */
160 public void remove(Collection<Changeset> changesets) {
161 if (changesets == null) return;
162 DefaultChangesetCacheEvent evt = new DefaultChangesetCacheEvent(this);
163 for (Changeset cs : changesets) {
164 if (cs == null || cs.isNew()) {
165 continue;
166 }
167 remove(cs.getId(), evt);
168 }
169 if (! evt.isEmpty()) {
170 fireChangesetCacheEvent(evt);
171 }
172 }
173
174 public int size() {
175 return cache.size();
176 }
177
178 public void clear() {
179 DefaultChangesetCacheEvent e = new DefaultChangesetCacheEvent(this);
180 for (Changeset cs: cache.values()) {
181 e.rememberRemovedChangeset(cs);
182 }
183 cache.clear();
184 fireChangesetCacheEvent(e);
185 }
186
187 public List<Changeset> getOpenChangesets() {
188 List<Changeset> ret = new ArrayList<Changeset>();
189 for (Changeset cs: cache.values()) {
190 if (cs.isOpen()) {
191 ret.add(cs);
192 }
193 }
194 return ret;
195 }
196
197 /* ------------------------------------------------------------------------- */
198 /* interface PreferenceChangedListener */
199 /* ------------------------------------------------------------------------- */
200 public void preferenceChanged(PreferenceChangeEvent e) {
201 if (e.getKey() == null || ! e.getKey().equals("osm-server.url"))
202 return;
203
204 // clear the cache when the API url changes
205 if (e.getOldValue() == null || e.getNewValue() == null || !e.getOldValue().equals(e.getNewValue())) {
206 clear();
207 }
208 }
209}
Note: See TracBrowser for help on using the repository browser.