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 | */
|
---|
17 | package org.openstreetmap.josm.data.validation.routines;
|
---|
18 |
|
---|
19 | import java.util.regex.Matcher;
|
---|
20 | import 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 | */
|
---|
56 | public 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 | @Override
|
---|
126 | public boolean isValid(String value) {
|
---|
127 | if (value == null) {
|
---|
128 | return false;
|
---|
129 | }
|
---|
130 | for (int i = 0; i < patterns.length; i++) {
|
---|
131 | if (patterns[i].matcher(value).matches()) {
|
---|
132 | return true;
|
---|
133 | }
|
---|
134 | }
|
---|
135 | return false;
|
---|
136 | }
|
---|
137 |
|
---|
138 | /**
|
---|
139 | * Validate a value against the set of regular expressions
|
---|
140 | * returning the array of matched groups.
|
---|
141 | *
|
---|
142 | * @param value The value to validate.
|
---|
143 | * @return String array of the <i>groups</i> matched if
|
---|
144 | * valid or <code>null</code> if invalid
|
---|
145 | */
|
---|
146 | public String[] match(String value) {
|
---|
147 | if (value == null) {
|
---|
148 | return null;
|
---|
149 | }
|
---|
150 | for (int i = 0; i < patterns.length; i++) {
|
---|
151 | Matcher matcher = patterns[i].matcher(value);
|
---|
152 | if (matcher.matches()) {
|
---|
153 | int count = matcher.groupCount();
|
---|
154 | String[] groups = new String[count];
|
---|
155 | for (int j = 0; j < count; j++) {
|
---|
156 | groups[j] = matcher.group(j+1);
|
---|
157 | }
|
---|
158 | return groups;
|
---|
159 | }
|
---|
160 | }
|
---|
161 | return null;
|
---|
162 | }
|
---|
163 |
|
---|
164 |
|
---|
165 | /**
|
---|
166 | * Validate a value against the set of regular expressions
|
---|
167 | * returning a String value of the aggregated groups.
|
---|
168 | *
|
---|
169 | * @param value The value to validate.
|
---|
170 | * @return Aggregated String value comprised of the
|
---|
171 | * <i>groups</i> matched if valid or <code>null</code> if invalid
|
---|
172 | */
|
---|
173 | public String validate(String value) {
|
---|
174 | if (value == null) {
|
---|
175 | return null;
|
---|
176 | }
|
---|
177 | for (int i = 0; i < patterns.length; i++) {
|
---|
178 | Matcher matcher = patterns[i].matcher(value);
|
---|
179 | if (matcher.matches()) {
|
---|
180 | int count = matcher.groupCount();
|
---|
181 | if (count == 1) {
|
---|
182 | return matcher.group(1);
|
---|
183 | }
|
---|
184 | StringBuilder buffer = new StringBuilder();
|
---|
185 | for (int j = 0; j < count; j++) {
|
---|
186 | String component = matcher.group(j+1);
|
---|
187 | if (component != null) {
|
---|
188 | buffer.append(component);
|
---|
189 | }
|
---|
190 | }
|
---|
191 | return buffer.toString();
|
---|
192 | }
|
---|
193 | }
|
---|
194 | return null;
|
---|
195 | }
|
---|
196 |
|
---|
197 | /**
|
---|
198 | * Provide a String representation of this validator.
|
---|
199 | * @return A String representation of this validator
|
---|
200 | */
|
---|
201 | @Override
|
---|
202 | public String toString() {
|
---|
203 | StringBuilder buffer = new StringBuilder();
|
---|
204 | buffer.append("RegexValidator{");
|
---|
205 | for (int i = 0; i < patterns.length; i++) {
|
---|
206 | if (i > 0) {
|
---|
207 | buffer.append(',');
|
---|
208 | }
|
---|
209 | buffer.append(patterns[i].pattern());
|
---|
210 | }
|
---|
211 | buffer.append('}');
|
---|
212 | return buffer.toString();
|
---|
213 | }
|
---|
214 | }
|
---|