source: josm/trunk/src/org/openstreetmap/josm/data/validation/routines/RegexValidator.java@ 7489

Last change on this file since 7489 was 7489, checked in by Don-vip, 10 years ago

fix #10393 - Validation of URLs and e-mails in relevant tags, using modified subset of Apache Commons Validator 1.4

File size: 7.3 KB
Line 
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17package org.openstreetmap.josm.data.validation.routines;
18
19import java.util.regex.Matcher;
20import java.util.regex.Pattern;
21
22/**
23 * <b>Regular Expression</b> validation (using JDK 1.4+ regex support).
24 * <p>
25 * Construct the validator either for a single regular expression or a set (array) of
26 * regular expressions. By default validation is <i>case sensitive</i> but constructors
27 * are provided to allow <i>case in-sensitive</i> validation. For example to create
28 * a validator which does <i>case in-sensitive</i> validation for a set of regular
29 * expressions:
30 * <pre>
31 * String[] regexs = new String[] {...};
32 * RegexValidator validator = new RegexValidator(regexs, false);
33 * </pre>
34 * <p>
35 * <ul>
36 * <li>Validate <code>true</code> or <code>false</code>:</li>
37 * <ul>
38 * <li><code>boolean valid = validator.isValid(value);</code></li>
39 * </ul>
40 * <li>Validate returning an aggregated String of the matched groups:</li>
41 * <ul>
42 * <li><code>String result = validator.validate(value);</code></li>
43 * </ul>
44 * <li>Validate returning the matched groups:</li>
45 * <ul>
46 * <li><code>String[] result = validator.match(value);</code></li>
47 * </ul>
48 * </ul>
49 * <p>
50 * Cached instances pre-compile and re-use {@link Pattern}(s) - which according
51 * to the {@link Pattern} API are safe to use in a multi-threaded environment.
52 *
53 * @version $Revision: 1227719 $ $Date: 2012-01-05 18:45:51 +0100 (Thu, 05 Jan 2012) $
54 * @since Validator 1.4
55 */
56public class RegexValidator extends AbstractValidator {
57
58 private final Pattern[] patterns;
59
60 /**
61 * Construct a <i>case sensitive</i> validator for a single
62 * regular expression.
63 *
64 * @param regex The regular expression this validator will
65 * validate against
66 */
67 public RegexValidator(String regex) {
68 this(regex, true);
69 }
70
71 /**
72 * Construct a validator for a single regular expression
73 * with the specified case sensitivity.
74 *
75 * @param regex The regular expression this validator will
76 * validate against
77 * @param caseSensitive when <code>true</code> matching is <i>case
78 * sensitive</i>, otherwise matching is <i>case in-sensitive</i>
79 */
80 public RegexValidator(String regex, boolean caseSensitive) {
81 this(new String[] {regex}, caseSensitive);
82 }
83
84 /**
85 * Construct a <i>case sensitive</i> validator that matches any one
86 * of the set of regular expressions.
87 *
88 * @param regexs The set of regular expressions this validator will
89 * validate against
90 */
91 public RegexValidator(String[] regexs) {
92 this(regexs, true);
93 }
94
95 /**
96 * Construct a validator that matches any one of the set of regular
97 * expressions with the specified case sensitivity.
98 *
99 * @param regexs The set of regular expressions this validator will
100 * validate against
101 * @param caseSensitive when <code>true</code> matching is <i>case
102 * sensitive</i>, otherwise matching is <i>case in-sensitive</i>
103 */
104 public RegexValidator(String[] regexs, boolean caseSensitive) {
105 if (regexs == null || regexs.length == 0) {
106 throw new IllegalArgumentException("Regular expressions are missing");
107 }
108 patterns = new Pattern[regexs.length];
109 int flags = (caseSensitive ? 0: Pattern.CASE_INSENSITIVE);
110 for (int i = 0; i < regexs.length; i++) {
111 if (regexs[i] == null || regexs[i].length() == 0) {
112 throw new IllegalArgumentException("Regular expression[" + i + "] is missing");
113 }
114 patterns[i] = Pattern.compile(regexs[i], flags);
115 }
116 }
117
118 /**
119 * Validate a value against the set of regular expressions.
120 *
121 * @param value The value to validate.
122 * @return <code>true</code> if the value is valid
123 * otherwise <code>false</code>.
124 */
125 public boolean isValid(String value) {
126 if (value == null) {
127 return false;
128 }
129 for (int i = 0; i < patterns.length; i++) {
130 if (patterns[i].matcher(value).matches()) {
131 return true;
132 }
133 }
134 return false;
135 }
136
137 /**
138 * Validate a value against the set of regular expressions
139 * returning the array of matched groups.
140 *
141 * @param value The value to validate.
142 * @return String array of the <i>groups</i> matched if
143 * valid or <code>null</code> if invalid
144 */
145 public String[] match(String value) {
146 if (value == null) {
147 return null;
148 }
149 for (int i = 0; i < patterns.length; i++) {
150 Matcher matcher = patterns[i].matcher(value);
151 if (matcher.matches()) {
152 int count = matcher.groupCount();
153 String[] groups = new String[count];
154 for (int j = 0; j < count; j++) {
155 groups[j] = matcher.group(j+1);
156 }
157 return groups;
158 }
159 }
160 return null;
161 }
162
163
164 /**
165 * Validate a value against the set of regular expressions
166 * returning a String value of the aggregated groups.
167 *
168 * @param value The value to validate.
169 * @return Aggregated String value comprised of the
170 * <i>groups</i> matched if valid or <code>null</code> if invalid
171 */
172 public String validate(String value) {
173 if (value == null) {
174 return null;
175 }
176 for (int i = 0; i < patterns.length; i++) {
177 Matcher matcher = patterns[i].matcher(value);
178 if (matcher.matches()) {
179 int count = matcher.groupCount();
180 if (count == 1) {
181 return matcher.group(1);
182 }
183 StringBuffer buffer = new StringBuffer();
184 for (int j = 0; j < count; j++) {
185 String component = matcher.group(j+1);
186 if (component != null) {
187 buffer.append(component);
188 }
189 }
190 return buffer.toString();
191 }
192 }
193 return null;
194 }
195
196 /**
197 * Provide a String representation of this validator.
198 * @return A String representation of this validator
199 */
200 @Override
201 public String toString() {
202 StringBuffer buffer = new StringBuffer();
203 buffer.append("RegexValidator{");
204 for (int i = 0; i < patterns.length; i++) {
205 if (i > 0) {
206 buffer.append(",");
207 }
208 buffer.append(patterns[i].pattern());
209 }
210 buffer.append("}");
211 return buffer.toString();
212 }
213
214}
Note: See TracBrowser for help on using the repository browser.