source: josm/trunk/src/org/openstreetmap/josm/gui/dialogs/properties/RecentTagCollection.java@ 13992

Last change on this file since 13992 was 13992, checked in by Don-vip, 6 years ago

fix #16443 - add robustness to invalid preferences when loading recent tag collection

File size: 3.4 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.dialogs.properties;
3
4import java.util.ArrayList;
5import java.util.Iterator;
6import java.util.LinkedHashMap;
7import java.util.List;
8import java.util.Map;
9
10import org.openstreetmap.josm.data.osm.Tag;
11import org.openstreetmap.josm.data.osm.search.SearchCompiler;
12import org.openstreetmap.josm.data.osm.search.SearchParseError;
13import org.openstreetmap.josm.data.osm.search.SearchSetting;
14import org.openstreetmap.josm.data.preferences.ListProperty;
15import org.openstreetmap.josm.tools.Logging;
16
17/**
18 * Manages list of recently used tags that will be displayed in the {@link PropertiesDialog}.
19 */
20class RecentTagCollection {
21
22 /**
23 * LRU cache for recently added tags (http://java-planet.blogspot.com/2005/08/how-to-set-up-simple-lru-cache-using.html)
24 */
25 static final class LruCache extends LinkedHashMap<Tag, Void> {
26 private static final long serialVersionUID = 1L;
27 private final int capacity;
28
29 LruCache(int capacity) {
30 super(capacity + 1, 1.1f, true);
31 this.capacity = capacity;
32 }
33
34 @Override
35 protected boolean removeEldestEntry(Map.Entry<Tag, Void> eldest) {
36 return size() > capacity;
37 }
38 }
39
40 private final Map<Tag, Void> recentTags;
41 private SearchCompiler.Match tagsToIgnore;
42
43 RecentTagCollection(final int capacity) {
44 recentTags = new LruCache(capacity);
45 tagsToIgnore = SearchCompiler.Never.INSTANCE;
46 }
47
48 public void loadFromPreference(ListProperty property) {
49 recentTags.clear();
50 List<String> list = property.get();
51 Iterator<String> it = list.iterator();
52 while (it.hasNext()) {
53 String key = it.next();
54 if (it.hasNext()) {
55 String value = it.next();
56 add(new Tag(key, value));
57 } else {
58 Logging.error("Invalid or incomplete list property: " + list);
59 break;
60 }
61 }
62 }
63
64 public void saveToPreference(ListProperty property) {
65 List<String> c = new ArrayList<>(recentTags.size() * 2);
66 for (Tag t : recentTags.keySet()) {
67 c.add(t.getKey());
68 c.add(t.getValue());
69 }
70 property.put(c);
71 }
72
73 public void add(Tag tag) {
74 if (!tagsToIgnore.match(tag)) {
75 recentTags.put(tag, null);
76 }
77 }
78
79 public boolean isEmpty() {
80 return recentTags.isEmpty();
81 }
82
83 public List<Tag> toList() {
84 return new ArrayList<>(recentTags.keySet());
85 }
86
87 public void setTagsToIgnore(SearchCompiler.Match tagsToIgnore) {
88 this.tagsToIgnore = tagsToIgnore;
89 recentTags.keySet().removeIf(tagsToIgnore::match);
90 }
91
92 public void setTagsToIgnore(SearchSetting tagsToIgnore) throws SearchParseError {
93 setTagsToIgnore(tagsToIgnore.text.isEmpty() ? SearchCompiler.Never.INSTANCE : SearchCompiler.compile(tagsToIgnore));
94 }
95
96 public SearchSetting ignoreTag(Tag tagToIgnore, SearchSetting settingToUpdate) throws SearchParseError {
97 final String forTag = SearchCompiler.buildSearchStringForTag(tagToIgnore.getKey(), tagToIgnore.getValue());
98 settingToUpdate.text = settingToUpdate.text.isEmpty()
99 ? forTag
100 : settingToUpdate.text + " OR " + forTag;
101 setTagsToIgnore(settingToUpdate);
102 return settingToUpdate;
103 }
104}
Note: See TracBrowser for help on using the repository browser.