source: josm/trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletionCache.java@ 2621

Last change on this file since 2621 was 2621, checked in by Gubaer, 14 years ago

Moved layer listener management from Layer to MapView
Made sure that listeners also unregister when they register for layer change events.

This will certainly break plugins. Plugin updates will follow later.

File size: 6.9 KB
Line 
1package org.openstreetmap.josm.gui.tagging.ac;
2
3import java.util.ArrayList;
4import java.util.Collection;
5import java.util.HashMap;
6import java.util.HashSet;
7import java.util.List;
8import java.util.Set;
9import java.util.logging.Logger;
10
11import org.openstreetmap.josm.data.osm.OsmPrimitive;
12import org.openstreetmap.josm.data.osm.Relation;
13import org.openstreetmap.josm.data.osm.RelationMember;
14import org.openstreetmap.josm.gui.MapView;
15import org.openstreetmap.josm.gui.layer.Layer;
16import org.openstreetmap.josm.gui.layer.OsmDataLayer;
17
18/**
19 * AutoCompletionCache temporarily holds a cache of keys with a list of
20 * possible auto completion values for each key.
21 *
22 * The cache can initialize itself from the current JOSM data set such that
23 * <ol>
24 * <li>any key used in a tag in the data set is part of the key list in the cache</li>
25 * <li>any value used in a tag for a specific key is part of the autocompletion list of
26 * this key</li>
27 * </ol>
28 *
29 * Building up auto completion lists should not
30 * slow down tabbing from input field to input field. Looping through the complete
31 * data set in order to build up the auto completion list for a specific input
32 * field is not efficient enough, hence this cache.
33 *
34 */
35public class AutoCompletionCache {
36 static private final Logger logger = Logger.getLogger(AutoCompletionCache.class.getName());
37
38 private static HashMap<OsmDataLayer, AutoCompletionCache> caches;
39
40 static {
41 caches = new HashMap<OsmDataLayer, AutoCompletionCache>();
42 MapView.addLayerChangeListener(new MapView.LayerChangeListener() {
43 public void activeLayerChange(Layer oldLayer, Layer newLayer) {
44 // do nothing
45 }
46
47 public void layerAdded(Layer newLayer) {
48 // do noting
49 }
50
51 public void layerRemoved(Layer oldLayer) {
52 if (oldLayer instanceof OsmDataLayer) {
53 caches.remove(oldLayer);
54 }
55 }
56 }
57 );
58 }
59
60 static public AutoCompletionCache getCacheForLayer(OsmDataLayer layer) {
61 AutoCompletionCache cache = caches.get(layer);
62 if (cache == null) {
63 cache = new AutoCompletionCache(layer);
64 caches.put(layer, cache);
65 }
66 return cache;
67 }
68
69 /** the cached tags give by a tag key and a list of values for this tag*/
70 private HashMap<String, Set<String>> tagCache;
71 /** the cached list of member roles */
72 private Set<String> roleCache;
73 /** the layer this cache is built for */
74 private OsmDataLayer layer;
75
76 /**
77 * constructor
78 */
79 public AutoCompletionCache(OsmDataLayer layer) {
80 tagCache = new HashMap<String, Set<String>>();
81 roleCache = new HashSet<String>();
82 this.layer = layer;
83 }
84
85 public AutoCompletionCache() {
86 this(null);
87 }
88
89 /**
90 * make sure, <code>key</code> is in the cache
91 *
92 * @param key the key
93 */
94 protected void cacheKey(String key) {
95 if (tagCache.containsKey(key))
96 return;
97 tagCache.put(key, new HashSet<String>());
98 }
99
100 /**
101 * make sure, value is one of the auto completion values allowed for key
102 *
103 * @param key the key
104 * @param value the value
105 */
106 protected void cacheValue(String key, String value) {
107 cacheKey(key);
108 tagCache.get(key).add(value);
109 }
110
111 /**
112 * make sure, the keys and values of all tags held by primitive are
113 * in the auto completion cache
114 *
115 * @param primitive an OSM primitive
116 */
117 protected void cachePrimitive(OsmPrimitive primitive) {
118 for (String key: primitive.keySet()) {
119 String value = primitive.get(key);
120 cacheValue(key, value);
121 }
122 }
123
124 /**
125 * Caches all member roles of the relation <code>relation</code>
126 *
127 * @param relation the relation
128 */
129 protected void cacheRelationMemberRoles(Relation relation){
130 for (RelationMember m: relation.getMembers()) {
131 if (m.hasRole() && !roleCache.contains(m.getRole())) {
132 roleCache.add(m.getRole());
133 }
134 }
135 }
136
137 /**
138 * initializes the cache from the primitives in the dataset of
139 * {@see #layer}
140 *
141 */
142 public void initFromDataSet() {
143 tagCache = new HashMap<String, Set<String>>();
144 if (layer == null)
145 return;
146 Collection<OsmPrimitive> ds = layer.data.allNonDeletedPrimitives();
147 for (OsmPrimitive primitive : ds) {
148 cachePrimitive(primitive);
149 }
150 for (Relation relation : layer.data.getRelations()) {
151 if (relation.isIncomplete() || relation.isDeleted()) {
152 continue;
153 }
154 cacheRelationMemberRoles(relation);
155 }
156 }
157
158 /**
159 * replies the keys held by the cache
160 *
161 * @return the list of keys held by the cache
162 */
163 public List<String> getKeys() {
164 return new ArrayList<String>(tagCache.keySet());
165 }
166
167 /**
168 * replies the auto completion values allowed for a specific key. Replies
169 * an empty list if key is null or if key is not in {@link #getKeys()}.
170 *
171 * @param key
172 * @return the list of auto completion values
173 */
174 public List<String> getValues(String key) {
175 if (!tagCache.containsKey(key))
176 return new ArrayList<String>();
177 return new ArrayList<String>(tagCache.get(key));
178 }
179
180 /**
181 * Replies the list of member roles
182 *
183 * @return the list of member roles
184 */
185 public List<String> getMemberRoles() {
186 return new ArrayList<String>(roleCache);
187 }
188
189 /**
190 * Populates the an {@see AutoCompletionList} with the currently cached
191 * member roles.
192 *
193 * @param list the list to populate
194 */
195 public void populateWithMemberRoles(AutoCompletionList list) {
196 list.clear();
197 list.add(roleCache, AutoCompletionItemPritority.IS_IN_DATASET);
198 }
199
200 /**
201 * Populates the an {@see AutoCompletionList} with the currently cached
202 * values for a tag
203 *
204 * @param list the list to populate
205 * @param key the tag key
206 * @param append true to add the values to the list; false, to replace the values
207 * in the list by the tag values
208 */
209 public void populateWithTagValues(AutoCompletionList list, String key, boolean append) {
210 if (!append) {
211 list.clear();
212 }
213 list.add(getValues(key), AutoCompletionItemPritority.IS_IN_DATASET);
214 }
215
216 /**
217 * Populates the an {@see AutoCompletionList} with the currently cached
218 * tag keys
219 *
220 * @param list the list to populate
221 * @param append true to add the keys to the list; false, to replace the keys
222 * in the list by the keys in the cache
223 */
224 public void populateWithKeys(AutoCompletionList list, boolean append) {
225 if (!append) {
226 list.clear();
227 }
228 list.add(tagCache.keySet(), AutoCompletionItemPritority.IS_IN_DATASET);
229 }
230}
Note: See TracBrowser for help on using the repository browser.