Changeset 9269 in osm for applications/editors/josm/plugins
- Timestamp:
- 2008-07-24T08:57:07+02:00 (16 years ago)
- Location:
- applications/editors/josm/plugins/validator
- Files:
-
- 1 added
- 1 deleted
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/ErrorTreePanel.java
r4023 r9269 160 160 } 161 161 162 /** 163 * Clears the current error list and adds thiese errors to it 164 * @param errors The validation errors 165 */ 166 public void setErrors(List<TestError> errors) 167 { 168 this.errors.clear(); 169 this.errors.addAll(errors); 170 if( isVisible() ) 171 buildTree(); 172 } 173 174 /** 175 * Returns the errors of the tree 176 * @return the errors of the tree 177 */ 178 public List<TestError> getErrors() 179 { 180 return errors != null ? errors : Collections.<TestError>emptyList(); 181 } 162 /** 163 * Clears the current error list and adds these errors to it 164 * @param errors The validation errors 165 */ 166 public void setErrors(List<TestError> newerrors) 167 { 168 errors.clear(); 169 for(TestError error : newerrors) 170 { 171 if(!error.getIgnored()) 172 errors.add(error); 173 } 174 if( isVisible() ) 175 buildTree(); 176 } 177 178 /** 179 * Returns the errors of the tree 180 * @return the errors of the tree 181 */ 182 public List<TestError> getErrors() 183 { 184 return errors != null ? errors : Collections.<TestError>emptyList(); 185 } 186 187 /** 188 * Updates the current errors list 189 * @param errors The validation errors 190 */ 191 public void resetErrors() 192 { 193 List<TestError> e = new ArrayList<TestError>(errors); 194 setErrors(e); 195 } 182 196 183 197 /** -
applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/OSMValidatorPlugin.java
r9111 r9269 50 50 UntaggedWay.class, 51 51 SelfIntersectingWay.class, 52 SpellCheck.class,53 52 DuplicatedWayNodes.class, 54 53 CrossingWays.class, -
applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/PreferenceEditor.java
r6389 r9269 35 35 public static final String PREF_TESTS = PREFIX + ".tests"; 36 36 37 /** The preferences key for enabled tests */ 38 public static final String PREF_USE_IGNORE = PREFIX + ".ignore"; 39 37 40 /** The preferences key for enabled tests before upload*/ 38 41 public static final String PREF_TESTS_BEFORE_UPLOAD = PREFIX + ".testsBeforeUpload"; 42 43 private JCheckBox prefUseIgnore; 39 44 40 45 /** The list of all tests */ … … 45 50 } 46 51 47 48 52 public void addGui(PreferenceDialog gui) 53 { 49 54 JPanel testPanel = new JPanel(new GridBagLayout()); 50 55 testPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 51 52 testPanel.add( new JLabel(), GBC.std() ); 53 testPanel.add( new JLabel("On upload"), GBC.eop() ); 56 57 prefUseIgnore = new JCheckBox(tr("Use ignore list."), Main.pref.getBoolean(PREF_USE_IGNORE, true)); 58 prefUseIgnore.setToolTipText(tr("Use the use ignore list to suppress warnings.")); 59 testPanel.add(prefUseIgnore, GBC.eol()); 60 61 GBC a = GBC.eol().insets(-5,0,0,0); 62 a.anchor = GBC.EAST; 63 testPanel.add( new JLabel(tr("On demand")), GBC.std() ); 64 testPanel.add( new JLabel(tr("On upload")), a ); 54 65 55 66 allTests = OSMValidatorPlugin.getTests(); 56 for(Test test: allTests) 67 for(Test test: allTests) 57 68 { 58 69 test.addGui(testPanel); 59 70 } 60 71 61 72 JScrollPane testPane = new JScrollPane(testPanel, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 62 73 testPane.setBorder(null); … … 66 77 if( ver != null ) 67 78 description += "<br><br>" + tr("Version: {0}<br>Last change at {1}", ver.revision, ver.time); 68 79 JPanel tab = gui.createPreferenceTab("validator", tr("Data validator"), description); 69 80 tab.add(testPane, GBC.eol().fill(GBC.BOTH)); 70 tab.add(GBC.glue(0,10), GBC.eol());71 81 tab.add(GBC.glue(0,10), a); 82 } 72 83 73 public void ok() 84 public void ok() 74 85 { 75 86 StringBuilder tests = new StringBuilder(); 76 87 StringBuilder testsBeforeUpload = new StringBuilder(); 77 88 78 89 for (Test test : allTests) 79 90 { … … 83 94 testsBeforeUpload.append( ',' ).append( name ).append( '=' ).append( test.testBeforeUpload ); 84 95 } 85 96 86 97 if (tests.length() > 0 ) tests = tests.deleteCharAt(0); 87 98 if (testsBeforeUpload.length() > 0 ) testsBeforeUpload = testsBeforeUpload.deleteCharAt(0); 88 99 89 100 plugin.initializeTests( allTests ); 90 101 91 102 Main.pref.put( PREF_TESTS, tests.toString()); 92 103 Main.pref.put( PREF_TESTS_BEFORE_UPLOAD, testsBeforeUpload.toString()); 104 Main.pref.put( PREF_USE_IGNORE, prefUseIgnore.isSelected()); 93 105 } 94 106 -
applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/Severity.java
r7404 r9269 1 1 package org.openstreetmap.josm.plugins.validator; 2 3 import static org.openstreetmap.josm.tools.I18n.tr; 2 4 3 5 import java.awt.Color; … … 8 10 public enum Severity { 9 11 /** Error messages */ 10 ERROR( "Errors", "error.gif", Preferences.getPreferencesColor("validation error", Color.RED)),12 ERROR(tr("Errors"), "error.gif", Preferences.getPreferencesColor("validation error", Color.RED)), 11 13 /** Warning messages */ 12 WARNING( "Warnings", "warning.gif", Preferences.getPreferencesColor("validation warning", Color.YELLOW)),14 WARNING(tr("Warnings"), "warning.gif", Preferences.getPreferencesColor("validation warning", Color.YELLOW)), 13 15 /** Other messages */ 14 OTHER( "Other", "other.gif", Preferences.getPreferencesColor("validation other", Color.CYAN));16 OTHER(tr("Other"), "other.gif", Preferences.getPreferencesColor("validation other", Color.CYAN)); 15 17 16 18 /** Description of the severity code */ -
applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/Test.java
r6388 r9269 142 142 checkEnabled = new JCheckBox(name, enabled); 143 143 checkEnabled.setToolTipText(description); 144 testPanel.add(checkEnabled, GBC.std().insets(20,0,0,0)); 145 146 checkBeforeUpload = new JCheckBox(); 147 checkBeforeUpload.setSelected(testBeforeUpload); 148 testPanel.add(checkBeforeUpload, GBC.eop().insets(20,0,0,0)); 144 testPanel.add(checkEnabled, GBC.std()); 145 146 GBC a = GBC.eol(); 147 a.anchor = GBC.EAST; 148 checkBeforeUpload = new JCheckBox(); 149 checkBeforeUpload.setSelected(testBeforeUpload); 150 testPanel.add(checkBeforeUpload, a); 149 151 } 150 152 -
applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/TestError.java
r9111 r9269 2 2 3 3 import java.awt.*; 4 import java.util.Collection; 4 5 import java.util.Collections; 5 6 import java.util.List; 7 import java.util.TreeSet; 6 8 7 9 import org.openstreetmap.josm.command.Command; … … 16 18 public class TestError 17 19 { 20 /** is this error on the ignore list */ 21 private Boolean ignored = false; 18 22 /** Severity */ 19 23 private Severity severity; … … 28 32 /** Internal code used by testers to classify errors */ 29 33 private int internalCode = -1; 30 31 34 /** If this error is selected */ 35 private boolean selected; 32 36 33 37 public TestError(Test tester, Severity severity, String message, … … 136 140 * Sets the ignore state for this error 137 141 */ 138 public void getIgnoreState() 139 { 140 System.out.println("Ignore " + message); 142 public String getIgnoreState() 143 { 144 Collection<String> strings = new TreeSet<String>(); 145 String ignorestring = message; 141 146 for (OsmPrimitive o : primitives) 142 147 { 143 System.out.println(o.id + " - " + o.getClass()); 144 } 145 } 146 147 /** 148 * Gets the tester that raised this error 148 String type = "u"; 149 if (o instanceof Way) type = "w"; 150 else if (o instanceof Relation) type = "r"; 151 else if (o instanceof Node) type = "n"; 152 strings.add(type + "_" + o.id); 153 } 154 for (String o : strings) 155 { 156 ignorestring += ":" + o; 157 } 158 return ignorestring; 159 } 160 161 public void setIgnored(boolean state) 162 { 163 ignored = state; 164 } 165 166 public Boolean getIgnored() 167 { 168 return ignored; 169 } 170 171 /** 172 * Gets the tester that raised this error 149 173 * @return the tester that raised this error 150 174 */ 151 public Test getTester() 175 public Test getTester() 152 176 { 153 177 return tester; … … 158 182 * @return the internal code 159 183 */ 160 public int getInternalCode() 184 public int getInternalCode() 161 185 { 162 186 return internalCode; 163 187 } 164 188 165 166 189 /** 167 190 * Sets the internal code … … 175 198 /** 176 199 * Returns true if the error can be fixed automatically 177 * 200 * 178 201 * @return true if the error can be fixed 179 202 */ … … 182 205 return tester != null && tester.isFixable(this); 183 206 } 184 207 185 208 /** 186 209 * Fixes the error with the appropiate command 187 * 210 * 188 211 * @return The command to fix the error 189 212 */ … … 192 215 if( tester == null ) 193 216 return null; 194 217 195 218 return tester.fixError(this); 196 219 } 197 220 198 /** 199 * Paints the error on affected primitives 200 * 201 * @param g The graphics 202 * @param mv The MapView 203 */ 204 public void paint(Graphics g, MapView mv) 205 { 206 PaintVisitor v = new PaintVisitor(g, mv); 207 for (Object o : highlighted) { 208 if (o instanceof OsmPrimitive) { 209 v.visit((OsmPrimitive) o); 210 } else if (o instanceof WaySegment) { 211 v.visit((WaySegment) o); 221 /** 222 * Paints the error on affected primitives 223 * 224 * @param g The graphics 225 * @param mv The MapView 226 */ 227 public void paint(Graphics g, MapView mv) 228 { 229 if(!ignored) 230 { 231 PaintVisitor v = new PaintVisitor(g, mv); 232 for (Object o : highlighted) { 233 if (o instanceof OsmPrimitive) 234 v.visit((OsmPrimitive) o); 235 else if (o instanceof WaySegment) 236 v.visit((WaySegment) o); 212 237 } 213 214 } 215 238 } 239 } 240 216 241 /** 217 242 * Visitor that highlights the primitives affected by this error -
applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/ValidateAction.java
r6389 r9269 1 1 package org.openstreetmap.josm.plugins.validator; 2 3 import static org.openstreetmap.josm.tools.I18n.tr; 2 4 3 5 import java.awt.event.ActionEvent; … … 35 37 */ 36 38 public ValidateAction(OSMValidatorPlugin plugin) { 37 super( "Validation", "validator", "Performs the data validation", KeyEvent.VK_V, KeyEvent.CTRL_DOWN_MASK + KeyEvent.ALT_MASK, true);39 super(tr("Validation"), "validator", tr("Performs the data validation"), KeyEvent.VK_V, KeyEvent.CTRL_DOWN_MASK + KeyEvent.ALT_MASK, true); 38 40 this.plugin = plugin; 39 41 } … … 88 90 89 91 List<TestError> errors = new ArrayList<TestError>(); 90 for(Test test : tests) 91 92 for(Test test : tests) 93 { 92 94 test.setPartialSelection(lastSelection != null); 93 94 95 test.startTest(); 96 test.visit(selection); 95 97 test.endTest(); 96 98 errors.addAll( test.getErrors() ); 97 99 } 98 100 tests = null; 99 101 if(Main.pref.getBoolean(PreferenceEditor.PREF_USE_IGNORE, true)) 102 { 103 for(TestError error : errors) 104 { 105 if(plugin.validationDialog.ignoredErrors.contains(error.getIgnoreState())) 106 { 107 error.setIgnored(true); 108 } 109 } 110 } 111 100 112 plugin.validationDialog.tree.setErrors(errors); 101 102 113 plugin.validationDialog.setVisible(true); 114 DataSet.fireSelectionChanged(Main.ds.getSelected()); 103 115 } 104 116 } -
applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/ValidatorDialog.java
r9111 r9269 6 6 import java.awt.GridLayout; 7 7 import java.awt.event.*; 8 import java.io.BufferedReader; 9 import java.io.FileNotFoundException; 10 import java.io.FileReader; 11 import java.io.FileWriter; 12 import java.io.IOException; 13 import java.io.PrintWriter; 8 14 import java.util.*; 9 15 import java.util.Map.Entry; … … 40 46 protected ErrorTreePanel tree; 41 47 48 public Collection<String> ignoredErrors = new TreeSet<String>(); 49 42 50 /** The fix button */ 43 51 private JButton fixButton; … … 76 84 fixButton.setEnabled(false); 77 85 buttonPanel.add(fixButton); 78 ignoreButton = Util.createButton(tr("Ignore"), "ignore", "dialogs/delete", tr("Ignore the selected errors next time."), this); 79 ignoreButton.setEnabled(false); 80 buttonPanel.add(ignoreButton); 86 if(Main.pref.getBoolean(PreferenceEditor.PREF_USE_IGNORE, true)) 87 { 88 ignoreButton = Util.createButton(tr("Ignore"), "ignore", "dialogs/delete", tr("Ignore the selected errors next time."), this); 89 ignoreButton.setEnabled(false); 90 buttonPanel.add(ignoreButton); 91 } 92 else 93 { 94 ignoreButton = null; 95 } 81 96 add(buttonPanel, BorderLayout.SOUTH); 82 } 83 84 @Override 85 public void setVisible(boolean v) 86 { 87 if( tree != null ) 88 tree.setVisible(v); 97 loadIgnoredErrors(); 98 } 99 100 private void loadIgnoredErrors() { 101 ignoredErrors.clear(); 102 if(Main.pref.getBoolean(PreferenceEditor.PREF_USE_IGNORE, true)) 103 { 104 try { 105 final BufferedReader in = new BufferedReader(new FileReader(Util.getPluginDir() + "ignorederrors")); 106 for (String line = in.readLine(); line != null; line = in.readLine()) { 107 ignoredErrors.add(line); 108 } 109 } 110 catch (final FileNotFoundException e) {} 111 catch (final IOException e) { 112 e.printStackTrace(); 113 } 114 } 115 } 116 117 private void saveIgnoredErrors() { 118 try { 119 final PrintWriter out = new PrintWriter(new FileWriter(Util.getPluginDir() + "ignorederrors"), false); 120 for (String e : ignoredErrors) 121 out.println(e); 122 out.close(); 123 } catch (final IOException e) { 124 e.printStackTrace(); 125 } 126 } 127 128 @Override 129 public void setVisible(boolean v) 130 { 131 if( tree != null ) 132 tree.setVisible(v); 89 133 if( action != null && action.button != null ) 90 134 action.button.setSelected(v); … … 92 136 Main.map.repaint(); 93 137 } 94 95 138 139 96 140 /** 97 141 * Fix selected errors 98 * @param e 142 * @param e 99 143 */ 100 144 @SuppressWarnings("unchecked") 101 private void fixErrors(ActionEvent e) 102 { 103 TreePath[] selectionPaths = tree.getSelectionPaths(); 104 if( selectionPaths == null ) 105 return; 106 107 Set<DefaultMutableTreeNode> processedNodes = new HashSet<DefaultMutableTreeNode>(); 108 for( TreePath path : selectionPaths ) 109 { 110 DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); 111 if( node == null ) 112 continue; 113 114 Enumeration<DefaultMutableTreeNode> children = node.breadthFirstEnumeration(); 115 while( children.hasMoreElements() ) 116 { 117 DefaultMutableTreeNode childNode = children.nextElement(); 118 if( processedNodes.contains(childNode) ) 119 continue; 120 121 processedNodes.add(childNode); 122 Object nodeInfo = childNode.getUserObject(); 123 if( nodeInfo instanceof TestError) 124 { 125 TestError error = (TestError)nodeInfo; 126 Command fixCommand = error.getFix(); 127 if( fixCommand != null ) 128 { 129 Main.main.undoRedo.add(fixCommand); 130 } 131 } 132 } 133 } 134 135 Main.map.repaint(); 136 DataSet.fireSelectionChanged(Main.ds.getSelected()); 137 138 plugin.validateAction.doValidate(e, false); 139 } 140 141 /** 142 * Set selected errors to ignore state 143 * @param e 144 */ 145 @SuppressWarnings("unchecked") 146 private void ignoreErrors(ActionEvent e) 145 private void fixErrors(ActionEvent e) 147 146 { 148 147 TreePath[] selectionPaths = tree.getSelectionPaths(); … … 169 168 { 170 169 TestError error = (TestError)nodeInfo; 171 String error.getIgnoreState(); 172 /* ignore */ 170 Command fixCommand = error.getFix(); 171 if( fixCommand != null ) 172 { 173 Main.main.undoRedo.add(fixCommand); 174 error.setIgnored(true); 175 } 173 176 } 174 177 } … … 176 179 177 180 Main.map.repaint(); 181 tree.resetErrors(); 178 182 DataSet.fireSelectionChanged(Main.ds.getSelected()); 179 180 plugin.validateAction.doValidate(e, false); 183 } 184 185 /** 186 * Set selected errors to ignore state 187 * @param e 188 */ 189 @SuppressWarnings("unchecked") 190 private void ignoreErrors(ActionEvent e) 191 { 192 boolean changed = false; 193 TreePath[] selectionPaths = tree.getSelectionPaths(); 194 if( selectionPaths == null ) 195 return; 196 197 Set<DefaultMutableTreeNode> processedNodes = new HashSet<DefaultMutableTreeNode>(); 198 for( TreePath path : selectionPaths ) 199 { 200 DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); 201 if( node == null ) 202 continue; 203 204 Enumeration<DefaultMutableTreeNode> children = node.breadthFirstEnumeration(); 205 while( children.hasMoreElements() ) 206 { 207 DefaultMutableTreeNode childNode = children.nextElement(); 208 if( processedNodes.contains(childNode) ) 209 continue; 210 211 processedNodes.add(childNode); 212 Object nodeInfo = childNode.getUserObject(); 213 if( nodeInfo instanceof TestError) 214 { 215 TestError error = (TestError)nodeInfo; 216 String state = error.getIgnoreState(); 217 ignoredErrors.add(state); 218 changed = true; 219 error.setIgnored(true); 220 } 221 } 222 } 223 if(changed) 224 { 225 tree.resetErrors(); 226 saveIgnoredErrors(); 227 Main.map.repaint(); 228 } 181 229 } 182 230 … … 277 325 } 278 326 selectButton.setEnabled(true); 279 ignoreButton.setEnabled(true); 327 if(ignoreButton != null) 328 ignoreButton.setEnabled(true); 280 329 281 330 return hasFixes; … … 291 340 { 292 341 fixButton.setEnabled(false); 293 ignoreButton.setEnabled(false); 342 if(ignoreButton != null) 343 ignoreButton.setEnabled(false); 294 344 selectButton.setEnabled(false); 295 345 … … 316 366 { 317 367 fixButton.setEnabled(false); 318 ignoreButton.setEnabled(false); 368 if(ignoreButton != null) 369 ignoreButton.setEnabled(false); 319 370 selectButton.setEnabled(false); 320 371 -
applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/TagChecker.java
r9111 r9269 3 3 import static org.openstreetmap.josm.tools.I18n.tr; 4 4 5 import java.awt.GridBagLayout; 6 import java.awt.event.ActionEvent; 7 import java.awt.event.ActionListener; 8 import java.io.*; 9 import java.net.URL; 5 10 import java.util.*; 6 7 import org.openstreetmap.josm.data.osm.OsmPrimitive; 8 import org.openstreetmap.josm.data.osm.Way; 9 import org.openstreetmap.josm.data.osm.Node; 10 import org.openstreetmap.josm.plugins.validator.Severity; 11 import org.openstreetmap.josm.plugins.validator.Test; 12 import org.openstreetmap.josm.plugins.validator.TestError; 11 import java.util.Map.Entry; 12 13 import javax.swing.*; 14 15 import org.openstreetmap.josm.Main; 16 import org.openstreetmap.josm.command.*; 17 import org.openstreetmap.josm.data.osm.*; 18 import org.openstreetmap.josm.gui.tagging.TaggingPreset; 19 import org.openstreetmap.josm.gui.tagging.TaggingPreset.*; 20 import org.openstreetmap.josm.gui.preferences.TaggingPresetPreference; 21 import org.openstreetmap.josm.plugins.validator.*; 13 22 import org.openstreetmap.josm.plugins.validator.util.Bag; 23 import org.openstreetmap.josm.plugins.validator.util.Util; 24 import org.openstreetmap.josm.tools.GBC; 25 import org.openstreetmap.josm.tools.XmlObjectParser; 26 import org.xml.sax.SAXException; 14 27 15 28 /** 16 * Check area type ways for errors29 * Check for mispelled or wrong properties 17 30 * 18 * @author stoecker31 * @author frsantos 19 32 */ 20 public class TagChecker extends Test { 21 /** The already detected errors */ 22 Bag<Way, Way> _errorWays; 33 public class TagChecker extends Test 34 { 35 /** The default data files */ 36 public static final String DATA_FILE = "http://svn.openstreetmap.org/applications/editors/josm/plugins/validator/tagchecker.cfg"; 37 public static final String SPELL_FILE = "http://svn.openstreetmap.org/applications/utils/planet.osm/java/speller/words.cfg"; 38 39 /** The spell check key substitutions: the key should be substituted by the value */ 40 protected static Map<String, String> spellCheckKeyData; 41 /** The spell check preset values */ 42 protected static Bag<String, String> presetsValueData; 43 44 /** The preferences prefix */ 45 protected static final String PREFIX = PreferenceEditor.PREFIX + "." + TagChecker.class.getSimpleName(); 46 47 /** Preference name for checking values */ 48 public static final String PREF_CHECK_VALUES = PREFIX + ".checkValues"; 49 /** Preference name for checking values */ 50 public static final String PREF_CHECK_KEYS = PREFIX + ".checkKeys"; 51 /** Preference name for checking FIXMES */ 52 public static final String PREF_CHECK_FIXMES = PREFIX + ".checkFixmes"; 53 /** Preference name for sources */ 54 public static final String PREF_SOURCES = PREFIX + ".sources"; 55 /** Preference name for sources */ 56 public static final String PREF_USE_DATA_FILE = PREFIX + ".usedatafile"; 57 /** Preference name for sources */ 58 public static final String PREF_USE_SPELL_FILE = PREFIX + ".usespellfile"; 59 /** Preference name for keys upload check */ 60 public static final String PREF_CHECK_KEYS_BEFORE_UPLOAD = PREFIX + ".checkKeysBeforeUpload"; 61 /** Preference name for values upload check */ 62 public static final String PREF_CHECK_VALUES_BEFORE_UPLOAD = PREFIX + ".checkValuesBeforeUpload"; 63 /** Preference name for fixmes upload check */ 64 public static final String PREF_CHECK_FIXMES_BEFORE_UPLOAD = PREFIX + ".checkFixmesBeforeUpload"; 65 66 /** Whether to check keys */ 67 protected boolean checkKeys = false; 68 /** Whether to check values */ 69 protected boolean checkValues = false; 70 /** Whether to check for fixmes in values */ 71 protected boolean checkFixmes = false; 72 73 /** Preferences checkbox for keys */ 74 protected JCheckBox prefCheckKeys; 75 /** Preferences checkbox for values */ 76 protected JCheckBox prefCheckValues; 77 /** Preferences checkbox for FIXMES */ 78 protected JCheckBox prefCheckFixmes; 79 /** The preferences checkbox for validation of keys on upload */ 80 protected JCheckBox prefCheckKeysBeforeUpload; 81 /** The preferences checkbox for validation of values on upload */ 82 protected JCheckBox prefCheckValuesBeforeUpload; 83 /** The preferences checkbox for validation of fixmes on upload */ 84 protected JCheckBox prefCheckFixmesBeforeUpload; 85 /** The add button */ 86 protected JButton addSrcButton; 87 /** The edit button */ 88 protected JButton editSrcButton; 89 /** The delete button */ 90 protected JButton deleteSrcButton; 91 92 /** Empty values error */ 93 protected static int EMPTY_VALUES = 0; 94 /** Invalid key error */ 95 protected static int INVALID_KEY = 1; 96 /** Invalid value error */ 97 protected static int INVALID_VALUE = 2; 98 /** fixme error */ 99 protected static int FIXME = 3; 100 101 /** List of sources for spellcheck data */ 102 protected JList Sources; 103 104 /** Whether this test must check the keys before upload. Used by peferences */ 105 protected boolean testKeysBeforeUpload; 106 /** Whether this test must check the values before upload. Used by peferences */ 107 protected boolean testValuesBeforeUpload; 108 /** Whether this test must check form fixmes in values before upload. Used by peferences */ 109 protected boolean testFixmesBeforeUpload; 23 110 24 111 /** … … 27 114 public TagChecker() 28 115 { 29 super(tr("Tag Checker."), 30 tr("This tests if major tags are used as expected.")); 116 super(tr("Properties checker :"), 117 tr("This plugin checks for errors in property keys and values.")); 118 } 119 120 public static void initialize(OSMValidatorPlugin plugin) throws Exception 121 { 122 initializeData(); 123 initializePresets(); 124 } 125 126 /** 127 * Reads the spellcheck file into a HashMap. 128 * <p> 129 * The data file is a list of words, beginning with +/-. If it starts with +, 130 * the word is valid, but if it starts with -, the word should be replaced 131 * by the nearest + word before this. 132 * 133 * @throws FileNotFoundException 134 * @throws IOException 135 */ 136 private static void initializeData() throws FileNotFoundException, IOException 137 { 138 spellCheckKeyData = new HashMap<String, String>(); 139 String sources = Main.pref.get( PREF_SOURCES ); 140 // if(Main.pref.getBoolean(PREF_USE_DATA_FILE)) 141 // { 142 // if( sources == null || sources.length() == 0) 143 // sources = DATA_FILE; 144 // else 145 // sources = DATA_FILE + ";" + sources; 146 // } 147 if(Main.pref.getBoolean(PREF_USE_SPELL_FILE)) 148 { 149 if( sources == null || sources.length() == 0) 150 sources = SPELL_FILE; 151 else 152 sources = SPELL_FILE + ";" + sources; 153 } 154 155 StringTokenizer st = new StringTokenizer(sources, ";"); 156 StringBuilder errorSources = new StringBuilder(); 157 while (st.hasMoreTokens()) 158 { 159 String source = st.nextToken(); 160 File sourceFile = Util.mirror(new URL(source), Util.getPluginDir(), -1); 161 if( sourceFile == null || !sourceFile.exists() ) 162 { 163 errorSources.append(source).append("\n"); 164 continue; 165 } 166 167 BufferedReader reader = new BufferedReader(new FileReader(sourceFile)); 168 169 String okValue = null; 170 do 171 { 172 String line = reader.readLine(); 173 if( line == null || line.length() == 0 ) 174 break; 175 if( line.startsWith("#") ) 176 continue; 177 178 if( line.charAt(0) == '+' ) 179 { 180 okValue = line.substring(1); 181 } 182 else if( line.charAt(0) == '-' && okValue != null ) 183 { 184 spellCheckKeyData.put(line.substring(1), okValue); 185 } 186 else 187 { 188 System.err.println("Invalid spellcheck line:" + line); 189 } 190 } 191 while( true ); 192 } 193 194 if( errorSources.length() > 0 ) 195 throw new IOException( tr("Could not download data file(s):\n{0}", errorSources) ); 196 } 197 198 /** 199 * Reads the presets data. 200 * 201 * @throws Exception 202 */ 203 public static void initializePresets() throws Exception 204 { 205 if( !Main.pref.getBoolean(PREF_CHECK_VALUES) ) 206 return; 207 208 Collection<TaggingPreset> presets = TaggingPresetPreference.taggingPresets; 209 if( presets == null || presets.isEmpty() ) 210 { 211 // Skip re-reading presets if there are none available 212 return; 213 } 214 215 presetsValueData = new Bag<String, String>(); 216 readPresetFromPreferences(); 217 } 218 219 220 @Override 221 public void visit(Node n) 222 { 223 checkPrimitive(n); 224 } 225 226 227 @Override 228 public void visit(Way w) 229 { 230 checkPrimitive(w); 231 } 232 233 /** 234 * Checks the primitive properties 235 * @param p The primitive to check 236 */ 237 private void checkPrimitive(OsmPrimitive p) 238 { 239 // Just a collection to know if a primitive has been already marked with error 240 Bag<OsmPrimitive, String> withErrors = new Bag<OsmPrimitive, String>(); 241 242 Map<String, String> props = (p.keys == null) ? Collections.<String, String>emptyMap() : p.keys; 243 for(Entry<String, String> prop: props.entrySet() ) 244 { 245 String key = prop.getKey(); 246 String value = prop.getValue(); 247 if( checkValues && (value==null || value.trim().length() == 0) && !withErrors.contains(p, "EV")) 248 { 249 errors.add( new TestError(this, Severity.WARNING, tr("Tags with empty values"), p, EMPTY_VALUES) ); 250 withErrors.add(p, "EV"); 251 } 252 if( checkKeys && spellCheckKeyData.containsKey(key) && !withErrors.contains(p, "IPK")) 253 { 254 errors.add( new TestError(this, Severity.WARNING, tr("Invalid property key ''{0}''", key), p, INVALID_KEY) ); 255 withErrors.add(p, "IPK"); 256 } 257 if( checkKeys && key.indexOf(" ") >= 0 && !withErrors.contains(p, "IPK")) 258 { 259 errors.add( new TestError(this, Severity.WARNING, tr("Invalid white space in property key ''{0}''", key), p, INVALID_KEY) ); 260 withErrors.add(p, "IPK"); 261 } 262 if( checkValues && value != null && (value.startsWith(" ") || value.endsWith(" ")) && !withErrors.contains(p, "SPACE")) 263 { 264 errors.add( new TestError(this, Severity.OTHER, tr("Property values start or end with white space"), p, INVALID_VALUE) ); 265 withErrors.add(p, "SPACE"); 266 } 267 if( checkValues && value != null && value.length() > 0 && presetsValueData != null) 268 { 269 List<String> values = presetsValueData.get(key); 270 if( values != null && !values.contains(prop.getValue()) && !withErrors.contains(p, "UPV")) 271 { 272 errors.add( new TestError(this, Severity.OTHER, tr("Unknown property values"), p, INVALID_VALUE) ); 273 withErrors.add(p, "UPV"); 274 } 275 } 276 if( checkFixmes && value != null && value.length() > 0 ) 277 { 278 if( (value.contains("FIXME") || value.contains("check and delete") || key.contains("todo") || key.contains("fixme")) 279 && !withErrors.contains(p, "FIXME")) 280 { 281 errors.add( new TestError(this, Severity.OTHER, tr("FIXMES"), p, FIXME) ); 282 withErrors.add(p, "FIXME"); 283 } 284 } 285 } 286 } 287 288 /** 289 * Parse an anotation preset from a stream 290 * 291 * @param inStream The stream of the anotstion preset 292 * @throws SAXException 293 */ 294 public static void readPresets(InputStream inStream) throws SAXException 295 { 296 BufferedReader in = null; 297 try 298 { 299 in = new BufferedReader(new InputStreamReader(inStream, "UTF-8")); 300 } 301 catch (UnsupportedEncodingException e) 302 { 303 e.printStackTrace(); 304 in = new BufferedReader(new InputStreamReader(inStream)); 305 } 306 307 XmlObjectParser parser = new XmlObjectParser(); 308 parser.mapOnStart("item", TaggingPreset.class); 309 parser.map("text", Text.class); 310 parser.map("check", Check.class); 311 parser.map("combo", Combo.class); 312 parser.map("label", Label.class); 313 parser.map("key", Key.class); 314 parser.start(in); 315 316 while(parser.hasNext()) 317 { 318 Object obj = parser.next(); 319 if (obj instanceof Combo) { 320 Combo combo = (Combo)obj; 321 for(String value : combo.values.split(",") ) 322 presetsValueData.add(combo.key, value); 323 } 324 } 325 } 326 327 /** 328 * Reads the tagging presets 329 */ 330 public static void readPresetFromPreferences() 331 { 332 String allAnnotations = Main.pref.get("taggingpreset.sources"); 333 StringTokenizer st = new StringTokenizer(allAnnotations, ";"); 334 while (st.hasMoreTokens()) 335 { 336 InputStream in = null; 337 String source = st.nextToken(); 338 try 339 { 340 if (source.startsWith("http") || source.startsWith("ftp") || source.startsWith("file")) 341 in = new URL(source).openStream(); 342 else if (source.startsWith("resource://")) 343 in = Main.class.getResourceAsStream(source.substring("resource:/".length())); 344 else 345 in = new FileInputStream(source); 346 readPresets(in); 347 in.close(); 348 } 349 catch (IOException e) 350 { 351 // Error already reported by JOSM 352 } 353 catch (SAXException e) 354 { 355 // Error already reported by JOSM 356 } 357 } 31 358 } 32 359 … … 34 361 public void startTest() 35 362 { 36 _errorWays = new Bag<Way, Way>(); 37 } 38 39 @Override 40 public void endTest() 41 { 42 _errorWays = null; 363 checkKeys = Main.pref.getBoolean(PREF_CHECK_KEYS); 364 if( isBeforeUpload ) 365 checkKeys = checkKeys && Main.pref.getBoolean(PREF_CHECK_KEYS_BEFORE_UPLOAD, true); 366 367 checkValues = Main.pref.getBoolean(PREF_CHECK_VALUES); 368 if( isBeforeUpload ) 369 checkValues = checkValues && Main.pref.getBoolean(PREF_CHECK_VALUES_BEFORE_UPLOAD, true); 370 371 checkFixmes = Main.pref.getBoolean(PREF_CHECK_FIXMES); 372 if( isBeforeUpload ) 373 checkFixmes = checkFixmes && Main.pref.getBoolean(PREF_CHECK_FIXMES_BEFORE_UPLOAD, true); 374 } 375 376 @Override 377 public void visit(Collection<OsmPrimitive> selection) 378 { 379 if( checkKeys || checkValues) 380 super.visit(selection); 43 381 } 44 382 45 383 @Override 46 public void visit(Node n) 47 { 48 /* ... */ 49 } 50 51 @Override 52 public void visit(Way w) 53 { 54 /* ... */ 384 public void addGui(JPanel testPanel) 385 { 386 GBC a = GBC.eol(); 387 a.anchor = GBC.EAST; 388 389 testPanel.add( new JLabel(name), GBC.eol().insets(3,0,0,0) ); 390 391 boolean checkKeys = Main.pref.getBoolean(PREF_CHECK_KEYS, true); 392 prefCheckKeys = new JCheckBox(tr("Check property keys."), checkKeys); 393 prefCheckKeys.setToolTipText(tr("Validate that property keys are valid checking against list of words.")); 394 testPanel.add(prefCheckKeys, GBC.std().insets(20,0,0,0)); 395 396 prefCheckKeysBeforeUpload = new JCheckBox(); 397 prefCheckKeysBeforeUpload.setSelected(Main.pref.getBoolean(PREF_CHECK_KEYS_BEFORE_UPLOAD, true)); 398 testPanel.add(prefCheckKeysBeforeUpload, a); 399 400 Sources = new JList(new DefaultListModel()); 401 402 String sources = Main.pref.get( PREF_SOURCES ); 403 StringTokenizer st = new StringTokenizer(sources, ";"); 404 while (st.hasMoreTokens()) 405 ((DefaultListModel)Sources.getModel()).addElement(st.nextToken()); 406 407 addSrcButton = new JButton(tr("Add")); 408 addSrcButton.addActionListener(new ActionListener(){ 409 public void actionPerformed(ActionEvent e) { 410 String source = JOptionPane.showInputDialog(Main.parent, tr("TagChecker source")); 411 if (source != null) 412 ((DefaultListModel)Sources.getModel()).addElement(source); 413 Sources.clearSelection(); 414 } 415 }); 416 417 editSrcButton = new JButton(tr("Edit")); 418 editSrcButton.addActionListener(new ActionListener(){ 419 public void actionPerformed(ActionEvent e) { 420 int row = Sources.getSelectedIndex(); 421 if(row == -1 && Sources.getModel().getSize() == 1) 422 { 423 Sources.setSelectedIndex(0); 424 row = 0; 425 } 426 if (row == -1) 427 { 428 if(Sources.getModel().getSize() == 0) 429 { 430 String source = JOptionPane.showInputDialog(Main.parent, tr("TagChecker source")); 431 if (source != null) 432 ((DefaultListModel)Sources.getModel()).addElement(source); 433 } 434 else 435 { 436 JOptionPane.showMessageDialog(Main.parent, tr("Please select the row to edit.")); 437 } 438 } 439 else { 440 String source = JOptionPane.showInputDialog(Main.parent, tr("TagChecker source"), Sources.getSelectedValue()); 441 if (source != null) 442 ((DefaultListModel)Sources.getModel()).setElementAt(source, row); 443 } 444 Sources.clearSelection(); 445 } 446 }); 447 448 deleteSrcButton = new JButton(tr("Delete")); 449 deleteSrcButton.addActionListener(new ActionListener(){ 450 public void actionPerformed(ActionEvent e) { 451 if (Sources.getSelectedIndex() == -1) 452 JOptionPane.showMessageDialog(Main.parent, tr("Please select the row to delete.")); 453 else { 454 ((DefaultListModel)Sources.getModel()).remove(Sources.getSelectedIndex()); 455 } 456 } 457 }); 458 Sources.setVisibleRowCount(3); 459 460 Sources.setToolTipText(tr("The sources (url or filename) of spell check (see http://wiki.openstreetmap.org/index.php/User:JLS/speller) or tag checking data files.")); 461 addSrcButton.setToolTipText(tr("Add a new source to the list.")); 462 editSrcButton.setToolTipText(tr("Edit the selected source.")); 463 deleteSrcButton.setToolTipText(tr("Delete the selected source from the list.")); 464 465 testPanel.add(new JLabel(tr("Data sources")), GBC.eol().insets(23,0,0,0)); 466 testPanel.add(new JScrollPane(Sources), GBC.eol().insets(23,0,0,0).fill(GBC.HORIZONTAL)); 467 final JPanel buttonPanel = new JPanel(new GridBagLayout()); 468 testPanel.add(buttonPanel, GBC.eol().fill(GBC.HORIZONTAL)); 469 buttonPanel.add(addSrcButton, GBC.std().insets(0,5,0,0)); 470 buttonPanel.add(editSrcButton, GBC.std().insets(5,5,5,0)); 471 buttonPanel.add(deleteSrcButton, GBC.std().insets(0,5,0,0)); 472 473 ActionListener disableCheckKeysActionListener = new ActionListener(){ 474 public void actionPerformed(ActionEvent e) { 475 boolean selected = prefCheckKeys.isSelected() || prefCheckKeysBeforeUpload.isSelected(); 476 Sources.setEnabled( selected ); 477 addSrcButton.setEnabled(selected); 478 editSrcButton.setEnabled(selected); 479 deleteSrcButton.setEnabled(selected); 480 } 481 }; 482 prefCheckKeys.addActionListener(disableCheckKeysActionListener); 483 prefCheckKeysBeforeUpload.addActionListener(disableCheckKeysActionListener); 484 485 Sources.setEnabled( checkKeys ); 486 buttonPanel.setEnabled( checkKeys ); 487 488 boolean checkValues = Main.pref.getBoolean(PREF_CHECK_VALUES, true); 489 prefCheckValues = new JCheckBox(tr("Check property values."), checkValues); 490 prefCheckValues.setToolTipText(tr("Validate that property values are valid checking against presets.")); 491 testPanel.add(prefCheckValues, GBC.std().insets(20,0,0,0)); 492 493 prefCheckValuesBeforeUpload = new JCheckBox(); 494 prefCheckValuesBeforeUpload.setSelected(Main.pref.getBoolean(PREF_CHECK_VALUES_BEFORE_UPLOAD, true)); 495 testPanel.add(prefCheckValuesBeforeUpload, a); 496 497 boolean checkFixmes = Main.pref.getBoolean(PREF_CHECK_FIXMES, true); 498 prefCheckFixmes = new JCheckBox(tr("Check for FIXMES."), checkFixmes); 499 prefCheckFixmes.setToolTipText(tr("Looks for nodes or ways with FIXME in any property value.")); 500 testPanel.add(prefCheckFixmes, GBC.std().insets(20,0,0,0)); 501 502 prefCheckFixmesBeforeUpload = new JCheckBox(); 503 prefCheckFixmesBeforeUpload.setSelected(Main.pref.getBoolean(PREF_CHECK_FIXMES_BEFORE_UPLOAD, true)); 504 testPanel.add(prefCheckFixmesBeforeUpload, a); 505 506 boolean useDataFile = Main.pref.getBoolean(PREF_USE_DATA_FILE, true); 507 JCheckBox prefUseDataFile = new JCheckBox(tr("Use default data file."), checkValues); 508 prefUseDataFile.setToolTipText(tr("Use the default data file (recommended).")); 509 testPanel.add(prefUseDataFile, GBC.eol().insets(20,0,0,0)); 510 511 boolean useSpellFile = Main.pref.getBoolean(PREF_USE_DATA_FILE, true); 512 JCheckBox prefUseSpellFile = new JCheckBox(tr("Use default spellcheck file."), checkValues); 513 prefUseSpellFile.setToolTipText(tr("Use the default spellcheck file (recommended).")); 514 testPanel.add(prefUseSpellFile, GBC.eol().insets(20,0,0,0)); 515 } 516 517 @Override 518 public void ok() 519 { 520 enabled = prefCheckKeys.isSelected() || prefCheckValues.isSelected() || prefCheckFixmes.isSelected(); 521 testBeforeUpload = prefCheckKeysBeforeUpload.isSelected() || prefCheckValuesBeforeUpload.isSelected() || prefCheckFixmesBeforeUpload.isSelected(); 522 523 Main.pref.put(PREF_CHECK_VALUES, prefCheckValues.isSelected()); 524 Main.pref.put(PREF_CHECK_KEYS, prefCheckKeys.isSelected()); 525 Main.pref.put(PREF_CHECK_FIXMES, prefCheckFixmes.isSelected()); 526 Main.pref.put(PREF_CHECK_VALUES_BEFORE_UPLOAD, prefCheckValuesBeforeUpload.isSelected()); 527 Main.pref.put(PREF_CHECK_KEYS_BEFORE_UPLOAD, prefCheckKeysBeforeUpload.isSelected()); 528 Main.pref.put(PREF_CHECK_FIXMES_BEFORE_UPLOAD, prefCheckFixmesBeforeUpload.isSelected()); 529 String sources = ""; 530 if( Sources.getModel().getSize() > 0 ) 531 { 532 StringBuilder sb = new StringBuilder(); 533 for (int i = 0; i < Sources.getModel().getSize(); ++i) 534 sb.append(";"+Sources.getModel().getElementAt(i)); 535 sources = sb.substring(1); 536 } 537 Main.pref.put(PREF_SOURCES, sources ); 538 } 539 540 @Override 541 public Command fixError(TestError testError) 542 { 543 List<Command> commands = new ArrayList<Command>(50); 544 545 int i = -1; 546 List<? extends OsmPrimitive> primitives = testError.getPrimitives(); 547 for(OsmPrimitive p : primitives ) 548 { 549 i++; 550 Map<String, String> tags = p.keys; 551 if( tags == null || tags.size() == 0 ) 552 continue; 553 554 for(Entry<String, String> prop: tags.entrySet() ) 555 { 556 String key = prop.getKey(); 557 String value = prop.getValue(); 558 if( value == null || value.trim().length() == 0 ) 559 commands.add( new ChangePropertyCommand(Collections.singleton(primitives.get(i)), key, null) ); 560 else 561 { 562 String replacementKey = spellCheckKeyData.get(key); 563 if( replacementKey != null ) 564 commands.add( new ChangePropertyKeyCommand(Collections.singleton(primitives.get(i)), key, replacementKey) ); 565 } 566 } 567 } 568 569 if( commands.size() == 0 ) 570 return null; 571 else if( commands.size() == 1 ) 572 return commands.get(0); 573 else 574 return new SequenceCommand(tr("Fix properties"), commands); 575 } 576 577 @Override 578 public boolean isFixable(TestError testError) 579 { 580 if( testError.getTester() instanceof TagChecker) 581 { 582 int code = testError.getInternalCode(); 583 return code == INVALID_KEY || code == EMPTY_VALUES; 584 } 585 586 return false; 55 587 } 56 588 }
Note:
See TracChangeset
for help on using the changeset viewer.