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

Last change on this file since 8836 was 8510, checked in by Don-vip, 9 years ago

checkstyle: enable relevant whitespace checks and fix them

  • Property svn:eol-style set to native
File size: 6.7 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.tr;
5
6import java.net.IDN;
7import java.util.regex.Pattern;
8
9import org.openstreetmap.josm.command.ChangePropertyCommand;
10import org.openstreetmap.josm.data.osm.Node;
11import org.openstreetmap.josm.data.osm.OsmPrimitive;
12import org.openstreetmap.josm.data.osm.Relation;
13import org.openstreetmap.josm.data.osm.Way;
14import org.openstreetmap.josm.data.validation.FixableTestError;
15import org.openstreetmap.josm.data.validation.Severity;
16import org.openstreetmap.josm.data.validation.Test;
17import org.openstreetmap.josm.data.validation.TestError;
18import org.openstreetmap.josm.data.validation.routines.AbstractValidator;
19import org.openstreetmap.josm.data.validation.routines.EmailValidator;
20import org.openstreetmap.josm.data.validation.routines.UrlValidator;
21
22/**
23 * Performs validation tests on internet-related tags (websites, e-mail addresses, etc.).
24 * @since 7489
25 */
26public class InternetTags extends Test {
27
28 /** Error code for an invalid URL */
29 public static final int INVALID_URL = 3301;
30 /** Error code for an invalid e-mail */
31 public static final int INVALID_EMAIL = 3302;
32
33 private static final Pattern ASCII_PATTERN = Pattern.compile("^\\p{ASCII}+$");
34
35 /**
36 * List of keys subject to URL validation.
37 */
38 private static String[] URL_KEYS = new String[] {
39 "url", "source:url",
40 "website", "contact:website", "heritage:website", "source:website"
41 };
42
43 /**
44 * List of keys subject to email validation.
45 */
46 private static String[] EMAIL_KEYS = new String[] {
47 "email", "contact:email"
48 };
49
50 /**
51 * Constructs a new {@code InternetTags} test.
52 */
53 public InternetTags() {
54 super(tr("Internet tags"), tr("Checks for errors in internet-related tags."));
55 }
56
57 /**
58 * Potentially validates a given primitive key against a given validator.
59 * @param p The OSM primitive to test
60 * @param k The key to validate
61 * @param keys The list of keys to check. If {@code k} is not inside this collection, do nothing
62 * @param validator The validator to run if {@code k} is inside {@code keys}
63 * @param code The error code to set if the validation fails
64 * @return {@code true} if the validation fails. In this case, a new error has been created.
65 */
66 private boolean doTest(OsmPrimitive p, String k, String[] keys, AbstractValidator validator, int code) {
67 for (String i : keys) {
68 if (i.equals(k)) {
69 TestError error = validateTag(p, k, validator, code);
70 if (error != null) {
71 errors.add(error);
72 }
73 break;
74 }
75 }
76 return false;
77 }
78
79 /**
80 * Validates a given primitive tag against a given validator.
81 * @param p The OSM primitive to test
82 * @param k The key to validate
83 * @param validator The validator to run
84 * @param code The error code to set if the validation fails
85 * @return The error if the validation fails, {@code null} otherwise
86 * @since 7824
87 */
88 public TestError validateTag(OsmPrimitive p, String k, AbstractValidator validator, int code) {
89 TestError error = doValidateTag(p, k, null, validator, code);
90 if (error != null) {
91 // Workaround to https://issues.apache.org/jira/browse/VALIDATOR-290
92 // Apache Commons Validator 1.4.1-SNAPSHOT does not support yet IDN URLs
93 // To remove if it gets fixed on Apache side
94 String v = p.get(k);
95 if (!ASCII_PATTERN.matcher(v).matches()) {
96 try {
97 String protocol = "";
98 if (v.contains("://")) {
99 protocol = v.substring(0, v.indexOf("://")+3);
100 }
101 String domain = !protocol.isEmpty() ? v.substring(protocol.length(), v.length()) : v;
102 String ending = "";
103 if (domain.contains("/")) {
104 int idx = domain.indexOf("/");
105 ending = domain.substring(idx, domain.length());
106 domain = domain.substring(0, idx);
107 }
108 // Try to apply ToASCII algorithm
109 error = doValidateTag(p, k, protocol+IDN.toASCII(domain)+ending, validator, code);
110 } catch (IllegalArgumentException e) {
111 error.setMessage(error.getMessage() +
112 tr(" URL cannot be converted to ASCII: {0}", e.getMessage()));
113 }
114 }
115 }
116 return error;
117 }
118
119 /**
120 * Validates a given primitive tag against a given validator.
121 * @param p The OSM primitive to test
122 * @param k The key to validate
123 * @param v The value to validate. May be {@code null} to use {@code p.get(k)}
124 * @param validator The validator to run
125 * @param code The error code to set if the validation fails
126 * @return The error if the validation fails, {@code null} otherwise
127 */
128 private TestError doValidateTag(OsmPrimitive p, String k, String v, AbstractValidator validator, int code) {
129 TestError error = null;
130 String value = v != null ? v : p.get(k);
131 if (!validator.isValid(value)) {
132 String errMsg = validator.getErrorMessage();
133 // Special treatment to allow URLs without protocol. See UrlValidator#isValid
134 if (tr("URL contains an invalid protocol: {0}", (String) null).equals(errMsg)) {
135 String proto = validator instanceof EmailValidator ? "mailto://" : "http://";
136 return doValidateTag(p, k, proto+value, validator, code);
137 }
138 String msg = tr("''{0}'': {1}", k, errMsg);
139 String fix = validator.getFix();
140 if (fix != null) {
141 error = new FixableTestError(this, Severity.WARNING, msg, code, p,
142 new ChangePropertyCommand(p, k, fix));
143 } else {
144 error = new TestError(this, Severity.WARNING, msg, code, p);
145 }
146 }
147 return error;
148 }
149
150 private void test(OsmPrimitive p) {
151 for (String k : p.keySet()) {
152 // Test key against URL validator
153 if (!doTest(p, k, URL_KEYS, UrlValidator.getInstance(), INVALID_URL)) {
154 // Test key against e-mail validator only if the URL validator did not fail
155 doTest(p, k, EMAIL_KEYS, EmailValidator.getInstance(), INVALID_EMAIL);
156 }
157 }
158 }
159
160 @Override
161 public void visit(Node n) {
162 test(n);
163 }
164
165 @Override
166 public void visit(Way w) {
167 test(w);
168 }
169
170 @Override
171 public void visit(Relation r) {
172 test(r);
173 }
174}
Note: See TracBrowser for help on using the repository browser.