source: josm/trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleIndex.java@ 17765

Last change on this file since 17765 was 16784, checked in by GerdP, 4 years ago

see #19180: false positives from tagchecker with single letter differences

  • avoid to produce "Value 'y' for key 'x' is unknown, maybe 'z' is meant?" when x=z produces a deprecated message. It uses all *.mapcss rules which are stored in files ending with deprecated.mapcss, so this will fail if user changed the name to something else, but it should work with e.g. my_deprecated.mapcss
File size: 6.4 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.mappaint.mapcss;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.text.MessageFormat;
7import java.util.Collections;
8import java.util.Iterator;
9import java.util.Map;
10import java.util.Set;
11import java.util.stream.Collectors;
12import java.util.stream.Stream;
13
14import org.openstreetmap.josm.data.osm.INode;
15import org.openstreetmap.josm.data.osm.IPrimitive;
16import org.openstreetmap.josm.data.osm.IRelation;
17import org.openstreetmap.josm.data.osm.IWay;
18import org.openstreetmap.josm.data.osm.OsmUtils;
19import org.openstreetmap.josm.tools.JosmRuntimeException;
20import org.openstreetmap.josm.tools.Logging;
21
22/**
23 * Store indexes of {@link MapCSSRule}s using {@link MapCSSRuleIndex} differentiated by {@linkplain Selector#getBase() base}
24 */
25public final class MapCSSStyleIndex {
26
27 /**
28 * Rules for nodes
29 */
30 final MapCSSRuleIndex nodeRules = new MapCSSRuleIndex();
31 /**
32 * Rules for ways without tag area=no
33 */
34 final MapCSSRuleIndex wayRules = new MapCSSRuleIndex();
35 /**
36 * Rules for ways with tag area=no
37 */
38 final MapCSSRuleIndex wayNoAreaRules = new MapCSSRuleIndex();
39 /**
40 * Rules for relations that are not multipolygon relations
41 */
42 final MapCSSRuleIndex relationRules = new MapCSSRuleIndex();
43 /**
44 * Rules for multipolygon relations
45 */
46 final MapCSSRuleIndex multipolygonRules = new MapCSSRuleIndex();
47 /**
48 * rules to apply canvas properties
49 */
50 final MapCSSRuleIndex canvasRules = new MapCSSRuleIndex();
51
52 /**
53 * Clear the index.
54 * <p>
55 * You must own the write lock STYLE_SOURCE_LOCK when calling this method.
56 */
57 public void clear() {
58 nodeRules.clear();
59 wayRules.clear();
60 wayNoAreaRules.clear();
61 relationRules.clear();
62 multipolygonRules.clear();
63 canvasRules.clear();
64 }
65
66 /**
67 * Builds and initializes the index.
68 * <p>
69 * You must own the write lock of STYLE_SOURCE_LOCK when calling this method.
70 * @param ruleStream the rules to index
71 */
72 public void buildIndex(Stream<MapCSSRule> ruleStream) {
73 clear();
74 // optimization: filter rules for different primitive types
75 ruleStream.forEach(rule -> {
76 final Map<String, MapCSSRule> selectorsByBase;
77 final Set<String> bases = rule.selectors.stream().map(Selector::getBase).collect(Collectors.toSet());
78 if (bases.size() == 1) {
79 // reuse rule
80 selectorsByBase = Collections.singletonMap(bases.iterator().next(), rule);
81 } else {
82 selectorsByBase = rule.selectors.stream()
83 .collect(Collectors.groupingBy(Selector::getBase,
84 Collectors.collectingAndThen(Collectors.toList(), selectors -> new MapCSSRule(selectors, rule.declaration))));
85 }
86 selectorsByBase.forEach((base, optRule) -> {
87 switch (base) {
88 case Selector.BASE_NODE:
89 nodeRules.add(optRule);
90 break;
91 case Selector.BASE_WAY:
92 wayNoAreaRules.add(optRule);
93 wayRules.add(optRule);
94 break;
95 case Selector.BASE_AREA:
96 wayRules.add(optRule);
97 multipolygonRules.add(optRule);
98 break;
99 case Selector.BASE_RELATION:
100 relationRules.add(optRule);
101 multipolygonRules.add(optRule);
102 break;
103 case Selector.BASE_ANY:
104 nodeRules.add(optRule);
105 wayRules.add(optRule);
106 wayNoAreaRules.add(optRule);
107 relationRules.add(optRule);
108 multipolygonRules.add(optRule);
109 break;
110 case Selector.BASE_CANVAS:
111 canvasRules.add(optRule);
112 break;
113 case Selector.BASE_META:
114 case Selector.BASE_SETTING:
115 case Selector.BASE_SETTINGS:
116 break;
117 default:
118 final RuntimeException e = new JosmRuntimeException(MessageFormat.format("Unknown MapCSS base selector {0}", base));
119 Logging.warn(tr("Failed to index validator rules. Error was: {0}", e.getMessage()));
120 Logging.error(e);
121 }
122 });
123 });
124 initIndex();
125 }
126
127 private void initIndex() {
128 nodeRules.initIndex();
129 wayRules.initIndex();
130 wayNoAreaRules.initIndex();
131 relationRules.initIndex();
132 multipolygonRules.initIndex();
133 canvasRules.initIndex();
134 }
135
136 /**
137 * Get the index of rules for the given primitive.
138 * @param p the primitive
139 * @return index of rules for the given primitive
140 */
141 public MapCSSRuleIndex get(IPrimitive p) {
142 if (p instanceof INode) {
143 return nodeRules;
144 } else if (p instanceof IWay) {
145 if (OsmUtils.isFalse(p.get("area"))) {
146 return wayNoAreaRules;
147 } else {
148 return wayRules;
149 }
150 } else if (p instanceof IRelation) {
151 if (((IRelation<?>) p).isMultipolygon()) {
152 return multipolygonRules;
153 } else if (p.hasKey("#canvas")) {
154 return canvasRules;
155 } else {
156 return relationRules;
157 }
158 } else {
159 throw new IllegalArgumentException("Unsupported type: " + p);
160 }
161 }
162
163 /**
164 * Get a subset of all rules that might match the primitive. Rules not included in the result are guaranteed to
165 * not match this primitive.
166 * <p>
167 * You must have a read lock of STYLE_SOURCE_LOCK when calling this method.
168 *
169 * @param osm the primitive to match
170 * @return An iterator over possible rules in the right order.
171 */
172 public Iterator<MapCSSRule> getRuleCandidates(IPrimitive osm) {
173 return get(osm).getRuleCandidates(osm);
174 }
175
176 /**
177 * Check if this index is empty.
178 * @return true if this index is empty.
179 * @since 16784
180 */
181 public boolean isEmpty() {
182 return nodeRules.isEmpty() && wayRules.isEmpty() && wayNoAreaRules.isEmpty() && relationRules.isEmpty()
183 && multipolygonRules.isEmpty() && canvasRules.isEmpty();
184 }
185}
Note: See TracBrowser for help on using the repository browser.