001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.preferences.validator; 003 004import static org.openstreetmap.josm.tools.I18n.marktr; 005import static org.openstreetmap.josm.tools.I18n.tr; 006 007import java.util.ArrayList; 008import java.util.Collection; 009import java.util.Collections; 010import java.util.HashMap; 011import java.util.List; 012import java.util.Map; 013 014import org.openstreetmap.josm.Main; 015import org.openstreetmap.josm.data.validation.OsmValidator; 016import org.openstreetmap.josm.data.validation.tests.MapCSSTagChecker; 017import org.openstreetmap.josm.gui.preferences.PreferenceSetting; 018import org.openstreetmap.josm.gui.preferences.PreferenceSettingFactory; 019import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane; 020import org.openstreetmap.josm.gui.preferences.SourceEditor; 021import org.openstreetmap.josm.gui.preferences.SourceEditor.ExtendedSourceEntry; 022import org.openstreetmap.josm.gui.preferences.SourceEntry; 023import org.openstreetmap.josm.gui.preferences.SourceProvider; 024import org.openstreetmap.josm.gui.preferences.SourceType; 025import org.openstreetmap.josm.gui.preferences.SubPreferenceSetting; 026import org.openstreetmap.josm.gui.preferences.TabPreferenceSetting; 027 028/** 029 * The general validator preferences, allowing to enable/disable tests. 030 * @since 6669 031 */ 032public class ValidatorTagCheckerRulesPreference implements SubPreferenceSetting { 033 034 /** 035 * Factory used to create a new {@code ValidatorTagCheckerRulesPreference}. 036 */ 037 public static class Factory implements PreferenceSettingFactory { 038 @Override 039 public PreferenceSetting createPreferenceSetting() { 040 return new ValidatorTagCheckerRulesPreference(); 041 } 042 } 043 044 private static final List<SourceProvider> ruleSourceProviders = new ArrayList<>(); 045 046 /** 047 * Registers a new additional rule source provider. 048 * @param provider The rule source provider 049 * @return {@code true}, if the provider has been added, {@code false} otherwise 050 */ 051 public static final boolean registerSourceProvider(SourceProvider provider) { 052 if (provider != null) 053 return ruleSourceProviders.add(provider); 054 return false; 055 } 056 057 static class TagCheckerRulesSourceEditor extends SourceEditor { 058 059 public TagCheckerRulesSourceEditor() { 060 super(SourceType.TAGCHECKER_RULE, Main.getJOSMWebsite()+"/rules", ruleSourceProviders, false); 061 } 062 063 @Override 064 public Collection<? extends SourceEntry> getInitialSourcesList() { 065 return RulePrefHelper.INSTANCE.get(); 066 } 067 068 @Override 069 public boolean finish() { 070 return RulePrefHelper.INSTANCE.put(activeSourcesModel.getSources()); 071 } 072 073 @Override 074 public Collection<ExtendedSourceEntry> getDefault() { 075 return RulePrefHelper.INSTANCE.getDefault(); 076 } 077 078 @Override 079 public Collection<String> getInitialIconPathsList() { 080 return null; 081 } 082 083 @Override 084 public String getStr(I18nString ident) { 085 switch (ident) { 086 case AVAILABLE_SOURCES: 087 return tr("Available rules:"); 088 case ACTIVE_SOURCES: 089 return tr("Active rules:"); 090 case NEW_SOURCE_ENTRY_TOOLTIP: 091 return tr("Add a new rule by entering filename or URL"); 092 case NEW_SOURCE_ENTRY: 093 return tr("New rule entry:"); 094 case REMOVE_SOURCE_TOOLTIP: 095 return tr("Remove the selected rules from the list of active rules"); 096 case EDIT_SOURCE_TOOLTIP: 097 return tr("Edit the filename or URL for the selected active rule"); 098 case ACTIVATE_TOOLTIP: 099 return tr("Add the selected available rules to the list of active rules"); 100 case RELOAD_ALL_AVAILABLE: 101 return marktr("Reloads the list of available rules from ''{0}''"); 102 case LOADING_SOURCES_FROM: 103 return marktr("Loading rule sources from ''{0}''"); 104 case FAILED_TO_LOAD_SOURCES_FROM: 105 return marktr("<html>Failed to load the list of rule sources from<br>" 106 + "''{0}''.<br>" 107 + "<br>" 108 + "Details (untranslated):<br>{1}</html>"); 109 case FAILED_TO_LOAD_SOURCES_FROM_HELP_TOPIC: 110 return "/Preferences/Rules#FailedToLoadRuleSources"; 111 case ILLEGAL_FORMAT_OF_ENTRY: 112 return marktr("Warning: illegal format of entry in rule list ''{0}''. Got ''{1}''"); 113 default: throw new AssertionError(); 114 } 115 } 116 } 117 118 /** 119 * Helper class for validator tag checker rules preferences. 120 */ 121 public static class RulePrefHelper extends SourceEditor.SourcePrefHelper { 122 123 /** 124 * The unique instance. 125 */ 126 public static final RulePrefHelper INSTANCE = new RulePrefHelper(); 127 128 /** 129 * Constructs a new {@code PresetPrefHelper}. 130 */ 131 public RulePrefHelper() { 132 super(MapCSSTagChecker.ENTRIES_PREF_KEY); 133 } 134 135 @Override 136 public Collection<ExtendedSourceEntry> getDefault() { 137 List<ExtendedSourceEntry> def = new ArrayList<>(); 138 139 addDefault(def, "addresses", tr("Addresses"), tr("Checks for errors on addresses")); 140 addDefault(def, "combinations", tr("Tag combinations"), tr("Checks for missing tag or suspicious combinations")); 141 addDefault(def, "deprecated", tr("Deprecated features"), tr("Checks for deprecated features")); 142 addDefault(def, "geometry", tr("Geometry"), tr("Checks for geometry errors")); 143 addDefault(def, "highway", tr("Highways"), tr("Checks for errors on highways")); 144 addDefault(def, "multiple", tr("Multiple values"), tr("Checks for wrong multiple values")); 145 addDefault(def, "numeric", tr("Numeric values"), tr("Checks for wrong numeric values")); 146 addDefault(def, "power", tr("Power"), tr("Checks for errors on power infrastructures")); 147 addDefault(def, "religion", tr("Religion"), tr("Checks for errors on religious objects")); 148 addDefault(def, "relation", tr("Relations"), tr("Checks for errors on relations")); 149 addDefault(def, "unnecessary", tr("Unnecessary tags"), tr("Checks for unnecessary tags")); 150 addDefault(def, "wikipedia", tr("Wikipedia"), tr("Checks for wrong wikipedia tags")); 151 152 return def; 153 } 154 155 private void addDefault(List<ExtendedSourceEntry> defaults, String filename, String title, String description) { 156 ExtendedSourceEntry i = new ExtendedSourceEntry(filename+".mapcss", "resource://data/validator/"+filename+".mapcss"); 157 i.title = title; 158 i.description = description; 159 defaults.add(i); 160 } 161 162 @Override 163 public Map<String, String> serialize(SourceEntry entry) { 164 Map<String, String> res = new HashMap<>(); 165 res.put("url", entry.url); 166 res.put("title", entry.title == null ? "" : entry.title); 167 res.put("active", Boolean.toString(entry.active)); 168 return res; 169 } 170 171 @Override 172 public SourceEntry deserialize(Map<String, String> s) { 173 return new SourceEntry(s.get("url"), null, s.get("title"), Boolean.parseBoolean(s.get("active"))); 174 } 175 } 176 177 private SourceEditor sources; 178 179 @Override 180 public void addGui(PreferenceTabbedPane gui) { 181 final ValidatorPreference valPref = gui.getValidatorPreference(); 182 sources = new TagCheckerRulesSourceEditor(); 183 184 valPref.addSubTab(this, tr("Tag checker rules"), 185 sources, tr("Choose Tag checker rules to enable")); 186 sources.deferLoading(valPref, sources); 187 } 188 189 @Override 190 public boolean ok() { 191 if (sources.finish()) { 192 // Reload sources 193 MapCSSTagChecker tagChecker = OsmValidator.getTest(MapCSSTagChecker.class); 194 if (tagChecker != null) { 195 OsmValidator.initializeTests(Collections.singleton(tagChecker)); 196 } 197 } 198 199 return false; 200 } 201 202 @Override 203 public boolean isExpert() { 204 return false; 205 } 206 207 @Override 208 public TabPreferenceSetting getTabPreferenceSetting(PreferenceTabbedPane gui) { 209 return gui.getValidatorPreference(); 210 } 211}