source: josm/trunk/src/org/openstreetmap/josm/data/validation/tests/InternetTags.java@ 16643

Last change on this file since 16643 was 16643, checked in by simon04, 4 years ago

see #19334 - https://errorprone.info/bugpattern/StringSplitter

  • Property svn:eol-style set to native
File size: 5.5 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.validation.tests;
3
4import static org.openstreetmap.josm.tools.I18n.marktr;
5import static org.openstreetmap.josm.tools.I18n.tr;
6
7import java.util.ArrayList;
8import java.util.List;
9import java.util.function.Supplier;
10
11import org.openstreetmap.josm.command.ChangePropertyCommand;
12import org.openstreetmap.josm.command.Command;
13import org.openstreetmap.josm.data.osm.OsmPrimitive;
14import org.openstreetmap.josm.data.validation.Severity;
15import org.openstreetmap.josm.data.validation.Test;
16import org.openstreetmap.josm.data.validation.TestError;
17import org.openstreetmap.josm.data.validation.routines.AbstractValidator;
18import org.openstreetmap.josm.data.validation.routines.EmailValidator;
19import org.openstreetmap.josm.data.validation.routines.UrlValidator;
20
21/**
22 * Performs validation tests on internet-related tags (websites, e-mail addresses, etc.).
23 * @since 7489
24 */
25public class InternetTags extends Test.TagTest {
26
27 /** Error code for an invalid URL */
28 public static final int INVALID_URL = 3301;
29 /** Error code for an invalid e-mail */
30 public static final int INVALID_EMAIL = 3302;
31
32 /**
33 * List of keys subject to URL validation.
34 */
35 private static final String[] URL_KEYS = {
36 "url", "source:url",
37 "website", "contact:website", "heritage:website", "source:website"
38 };
39
40 /**
41 * List of keys subject to email validation.
42 */
43 private static final String[] EMAIL_KEYS = {
44 "email", "contact:email"
45 };
46
47 /**
48 * Constructs a new {@code InternetTags} test.
49 */
50 public InternetTags() {
51 super(tr("Internet tags"), tr("Checks for errors in internet-related tags."));
52 }
53
54 /**
55 * Potentially validates a given primitive key against a given validator.
56 * @param p The OSM primitive to test
57 * @param k The key to validate
58 * @param keys The list of keys to check. If {@code k} is not inside this collection, do nothing
59 * @param validator The validator to run if {@code k} is inside {@code keys}
60 * @param code The error code to set if the validation fails
61 * @return {@code true} if the validation fails. In this case, a new error has been created.
62 */
63 private boolean doTest(OsmPrimitive p, String k, String[] keys, AbstractValidator validator, int code) {
64 for (String i : keys) {
65 if (i.equals(k)) {
66 return errors.addAll(validateTag(p, k, validator, code));
67 }
68 }
69 return false;
70 }
71
72 /**
73 * Validates a given primitive tag against a given validator.
74 * @param p The OSM primitive to test
75 * @param k The key to validate
76 * @param validator The validator to run
77 * @param code The error code to set if the validation fails
78 * @return The error if the validation fails, {@code null} otherwise
79 * @since 7824
80 * @since 14803 (return type)
81 */
82 public List<TestError> validateTag(OsmPrimitive p, String k, AbstractValidator validator, int code) {
83 return doValidateTag(p, k, null, validator, code);
84 }
85
86 /**
87 * Validates a given primitive tag against a given validator.
88 * @param p The OSM primitive to test
89 * @param k The key to validate
90 * @param v The value to validate. May be {@code null} to use {@code p.get(k)}
91 * @param validator The validator to run
92 * @param code The error code to set if the validation fails
93 * @return The error if the validation fails, {@code null} otherwise
94 */
95 private List<TestError> doValidateTag(OsmPrimitive p, String k, String v, AbstractValidator validator, int code) {
96 List<TestError> errors = new ArrayList<>();
97 String values = v != null ? v : p.get(k);
98 for (String value : values.split(";", -1)) {
99 if (!validator.isValid(value)) {
100 Supplier<Command> fix = null;
101 String errMsg = validator.getErrorMessage();
102 if (tr("URL contains an invalid protocol: {0}", (String) null).equals(errMsg)) {
103 // Special treatment to allow URLs without protocol. See UrlValidator#isValid
104 String proto = validator instanceof EmailValidator ? "mailto://" : "http://";
105 return doValidateTag(p, k, proto+value, validator, code);
106 } else if (tr("URL contains an invalid authority: {0}", (String) null).equals(errMsg)
107 && value.contains("\\") && validator.isValid(value.replaceAll("\\\\", "/"))) {
108 // Special treatment to autofix URLs with backslashes. See UrlValidator#isValid
109 errMsg = tr("URL contains backslashes instead of slashes");
110 fix = () -> new ChangePropertyCommand(p, k, value.replaceAll("\\\\", "/"));
111 }
112 errors.add(TestError.builder(this, Severity.WARNING, code)
113 .message(validator.getValidatorName(), marktr("''{0}'': {1}"), k, errMsg)
114 .primitives(p)
115 .fix(fix)
116 .build());
117 }
118 }
119 return errors;
120 }
121
122 @Override
123 public void check(OsmPrimitive p) {
124 for (String k : p.keySet()) {
125 // Test key against URL validator
126 if (!doTest(p, k, URL_KEYS, UrlValidator.getInstance(), INVALID_URL)) {
127 // Test key against e-mail validator only if the URL validator did not fail
128 doTest(p, k, EMAIL_KEYS, EmailValidator.getInstance(), INVALID_EMAIL);
129 }
130 }
131 }
132}
Note: See TracBrowser for help on using the repository browser.