Changeset 14469 in josm for trunk/src/org
- Timestamp:
- 2018-11-30T10:43:39+01:00 (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java
r14421 r14469 17 17 import java.util.HashMap; 18 18 import java.util.HashSet; 19 import java.util.Iterator; 19 20 import java.util.LinkedHashMap; 20 21 import java.util.LinkedHashSet; … … 36 37 import org.openstreetmap.josm.command.SequenceCommand; 37 38 import org.openstreetmap.josm.data.osm.DataSet; 39 import org.openstreetmap.josm.data.osm.INode; 40 import org.openstreetmap.josm.data.osm.IRelation; 41 import org.openstreetmap.josm.data.osm.IWay; 38 42 import org.openstreetmap.josm.data.osm.OsmPrimitive; 39 43 import org.openstreetmap.josm.data.osm.OsmUtils; … … 55 59 import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSRule.Declaration; 56 60 import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSStyleSource; 61 import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSStyleSource.MapCSSRuleIndex; 57 62 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector; 58 63 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.AbstractSelector; 59 64 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.GeneralSelector; 65 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.OptimizedGeneralSelector; 60 66 import org.openstreetmap.josm.gui.mappaint.mapcss.parsergen.MapCSSParser; 61 67 import org.openstreetmap.josm.gui.mappaint.mapcss.parsergen.ParseException; 62 68 import org.openstreetmap.josm.gui.mappaint.mapcss.parsergen.TokenMgrError; 69 import org.openstreetmap.josm.gui.progress.ProgressMonitor; 63 70 import org.openstreetmap.josm.io.CachedFile; 64 71 import org.openstreetmap.josm.io.FileWatcher; … … 68 75 import org.openstreetmap.josm.tools.CheckParameterUtil; 69 76 import org.openstreetmap.josm.tools.I18n; 77 import org.openstreetmap.josm.tools.JosmRuntimeException; 70 78 import org.openstreetmap.josm.tools.Logging; 71 79 import org.openstreetmap.josm.tools.MultiMap; … … 77 85 */ 78 86 public class MapCSSTagChecker extends Test.TagTest { 79 80 /** 81 * A grouped MapCSSRule with multiple selectors for a single declaration. 82 * @see MapCSSRule 87 IndexData indexData; 88 89 /** 90 * Helper class to store indexes of rules. 91 * @author Gerd 92 * 83 93 */ 94 private static class IndexData { 95 final Map<MapCSSRule, TagCheck> ruleToCheckMap = new HashMap<>(); 96 97 /** 98 * Rules for nodes 99 */ 100 final MapCSSRuleIndex nodeRules = new MapCSSRuleIndex(); 101 /** 102 * Rules for ways without tag area=no 103 */ 104 final MapCSSRuleIndex wayRules = new MapCSSRuleIndex(); 105 /** 106 * Rules for ways with tag area=no 107 */ 108 final MapCSSRuleIndex wayNoAreaRules = new MapCSSRuleIndex(); 109 /** 110 * Rules for relations that are not multipolygon relations 111 */ 112 final MapCSSRuleIndex relationRules = new MapCSSRuleIndex(); 113 /** 114 * Rules for multipolygon relations 115 */ 116 final MapCSSRuleIndex multipolygonRules = new MapCSSRuleIndex(); 117 118 IndexData(MultiMap<String, TagCheck> checks) { 119 buildIndex(checks); 120 } 121 122 private void buildIndex(MultiMap<String, TagCheck> checks) { 123 List<TagCheck> allChecks = new ArrayList<>(); 124 for (Set<TagCheck> cs : checks.values()) { 125 allChecks.addAll(cs); 126 } 127 128 ruleToCheckMap.clear(); 129 nodeRules.clear(); 130 wayRules.clear(); 131 wayNoAreaRules.clear(); 132 relationRules.clear(); 133 multipolygonRules.clear(); 134 135 // optimization: filter rules for different primitive types 136 for (TagCheck c : allChecks) { 137 for (Selector s : c.rule.selectors) { 138 // find the rightmost selector, this must be a GeneralSelector 139 Selector selRightmost = s; 140 while (selRightmost instanceof Selector.ChildOrParentSelector) { 141 selRightmost = ((Selector.ChildOrParentSelector) selRightmost).right; 142 } 143 MapCSSRule optRule = new MapCSSRule(s.optimizedBaseCheck(), c.rule.declaration); 144 145 ruleToCheckMap.put(optRule, c); 146 final String base = ((GeneralSelector) selRightmost).getBase(); 147 switch (base) { 148 case Selector.BASE_NODE: 149 nodeRules.add(optRule); 150 break; 151 case Selector.BASE_WAY: 152 wayNoAreaRules.add(optRule); 153 wayRules.add(optRule); 154 break; 155 case Selector.BASE_AREA: 156 wayRules.add(optRule); 157 multipolygonRules.add(optRule); 158 break; 159 case Selector.BASE_RELATION: 160 relationRules.add(optRule); 161 multipolygonRules.add(optRule); 162 break; 163 case Selector.BASE_ANY: 164 nodeRules.add(optRule); 165 wayRules.add(optRule); 166 wayNoAreaRules.add(optRule); 167 relationRules.add(optRule); 168 multipolygonRules.add(optRule); 169 break; 170 case Selector.BASE_CANVAS: 171 case Selector.BASE_META: 172 case Selector.BASE_SETTING: 173 break; 174 default: 175 final RuntimeException e = new JosmRuntimeException(MessageFormat.format("Unknown MapCSS base selector {0}", base)); 176 Logging.warn(tr("Failed to index validator rules. Error was: {0}", e.getMessage())); 177 Logging.error(e); 178 } 179 } 180 } 181 nodeRules.initIndex(); 182 wayRules.initIndex(); 183 wayNoAreaRules.initIndex(); 184 relationRules.initIndex(); 185 multipolygonRules.initIndex(); 186 } 187 188 /** 189 * Get the index of rules for the given primitive. 190 * @param p the primitve 191 * @return index of rules for the given primitive 192 */ 193 public MapCSSRuleIndex get(OsmPrimitive p) { 194 if (p instanceof INode) { 195 return nodeRules; 196 } else if (p instanceof IWay) { 197 if (OsmUtils.isFalse(p.get("area"))) { 198 return wayNoAreaRules; 199 } else { 200 return wayRules; 201 } 202 } else if (p instanceof IRelation) { 203 if (((IRelation<?>) p).isMultipolygon()) { 204 return multipolygonRules; 205 } else { 206 return relationRules; 207 } 208 } else { 209 throw new IllegalArgumentException("Unsupported type: " + p); 210 } 211 } 212 213 /** 214 * return the TagCheck for which the given indexed rule was created. 215 * @param rule an indexed rule 216 * @return the original TagCheck 217 */ 218 public TagCheck getCheck(MapCSSRule rule) { 219 return ruleToCheckMap.get(rule); 220 } 221 } 222 223 /** 224 * A grouped MapCSSRule with multiple selectors for a single declaration. 225 * @see MapCSSRule 226 */ 84 227 public static class GroupedMapCSSRule { 85 228 /** MapCSS selectors **/ … … 430 573 * @return argument value, can be {@code null} 431 574 */ 432 static String determineArgument( Selector.GeneralSelector matchingSelector, int index, String type, OsmPrimitive p) {575 static String determineArgument(OptimizedGeneralSelector matchingSelector, int index, String type, OsmPrimitive p) { 433 576 try { 434 577 final Condition c = matchingSelector.getConditions().get(index); … … 462 605 if (s != null && matchingSelector instanceof Selector.ChildOrParentSelector) { 463 606 return insertArguments(((Selector.ChildOrParentSelector) matchingSelector).right, s, p); 464 } else if (s == null || !(matchingSelector instanceof GeneralSelector)) {607 } else if (s == null || !(matchingSelector instanceof Selector.OptimizedGeneralSelector)) { 465 608 return s; 466 609 } … … 468 611 final StringBuffer sb = new StringBuffer(); 469 612 while (m.find()) { 470 final String argument = determineArgument((Selector. GeneralSelector) matchingSelector,613 final String argument = determineArgument((Selector.OptimizedGeneralSelector) matchingSelector, 471 614 Integer.parseInt(m.group(1)), m.group(2), p); 472 615 try { … … 678 821 */ 679 822 public synchronized Collection<TestError> getErrorsForPrimitive(OsmPrimitive p, boolean includeOtherSeverity) { 680 return getErrorsForPrimitive(p, includeOtherSeverity, checks.values()); 823 final List<TestError> res = new ArrayList<>(); 824 if (indexData == null) 825 indexData = new IndexData(checks); 826 827 MapCSSRuleIndex matchingRuleIndex = indexData.get(p); 828 829 Environment env = new Environment(p, new MultiCascade(), Environment.DEFAULT_LAYER, null); 830 // the declaration indices are sorted, so it suffices to save the last used index 831 Declaration lastDeclUsed = null; 832 833 Iterator<MapCSSRule> candidates = matchingRuleIndex.getRuleCandidates(p); 834 while (candidates.hasNext()) { 835 MapCSSRule r = candidates.next(); 836 env.clearSelectorMatchingInformation(); 837 if (r.selector.matches(env)) { // as side effect env.parent will be set (if s is a child selector) 838 TagCheck check = indexData.getCheck(r); 839 if (check != null) { 840 boolean ignoreError = Severity.OTHER == check.getSeverity() && !includeOtherSeverity; 841 // Do not run "information" level checks if not wanted, unless they also set a MapCSS class 842 if (ignoreError && check.setClassExpressions.isEmpty()) { 843 continue; 844 } 845 if (r.declaration == lastDeclUsed) 846 continue; // don't apply one declaration more than once 847 lastDeclUsed = r.declaration; 848 849 r.declaration.execute(env); 850 if (!ignoreError && !check.errors.isEmpty()) { 851 final TestError error = check.getErrorForPrimitive(p, r.selector, env, new MapCSSTagCheckerAndRule(check.rule)); 852 if (error != null) { 853 res.add(error); 854 } 855 } 856 857 } 858 } 859 } 860 return res; 681 861 } 682 862 … … 737 917 checks.remove(url); 738 918 checks.putAll(url, result.parseChecks); 919 indexData = null; 739 920 // Check assertions, useful for development of local files 740 921 if (Config.getPref().getBoolean("validator.check_assert_local_rules", false) && Utils.isLocalUrl(url)) { … … 750 931 public synchronized void initialize() throws Exception { 751 932 checks.clear(); 933 indexData = null; 752 934 for (SourceEntry source : new ValidatorPrefHelper().get()) { 753 935 if (!source.active) { … … 842 1024 } 843 1025 } 1026 1027 @Override 1028 public void startTest(ProgressMonitor progressMonitor) { 1029 super.startTest(progressMonitor); 1030 if (indexData == null) { 1031 indexData = new IndexData(checks); 1032 } 1033 } 1034 1035 @Override 1036 public void endTest() { 1037 super.endTest(); 1038 // no need to keep the index, it is quickly build and doubles the memory needs 1039 indexData = null; 1040 } 1041 844 1042 }
Note:
See TracChangeset
for help on using the changeset viewer.