1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.settings.validation;
20
21 import javax.inject.Named;
22 import javax.inject.Singleton;
23
24 import java.util.HashSet;
25 import java.util.List;
26 import java.util.Set;
27 import java.util.regex.Pattern;
28
29 import org.apache.maven.settings.Mirror;
30 import org.apache.maven.settings.Profile;
31 import org.apache.maven.settings.Proxy;
32 import org.apache.maven.settings.Repository;
33 import org.apache.maven.settings.Server;
34 import org.apache.maven.settings.Settings;
35 import org.apache.maven.settings.building.SettingsProblem.Severity;
36 import org.apache.maven.settings.building.SettingsProblemCollector;
37 import org.codehaus.plexus.util.StringUtils;
38
39
40
41
42 @Named
43 @Singleton
44 public class DefaultSettingsValidator implements SettingsValidator {
45
46 private static final String ID = "[\\w.-]+";
47 private static final Pattern ID_REGEX = Pattern.compile(ID);
48
49 private static final String ILLEGAL_REPO_ID_CHARS = "\\/:\"<>|?*";
50
51 @Override
52 public void validate(Settings settings, SettingsProblemCollector problems) {
53 if (settings.isUsePluginRegistry()) {
54 addViolation(problems, Severity.WARNING, "usePluginRegistry", null, "is deprecated and has no effect.");
55 }
56
57 List<String> pluginGroups = settings.getPluginGroups();
58
59 if (pluginGroups != null) {
60 for (int i = 0; i < pluginGroups.size(); i++) {
61 String pluginGroup = pluginGroups.get(i).trim();
62
63 if (StringUtils.isBlank(pluginGroup)) {
64 addViolation(
65 problems, Severity.ERROR, "pluginGroups.pluginGroup[" + i + "]", null, "must not be empty");
66 } else if (!ID_REGEX.matcher(pluginGroup).matches()) {
67 addViolation(
68 problems,
69 Severity.ERROR,
70 "pluginGroups.pluginGroup[" + i + "]",
71 null,
72 "must denote a valid group id and match the pattern " + ID);
73 }
74 }
75 }
76
77 List<Server> servers = settings.getServers();
78
79 if (servers != null) {
80 Set<String> serverIds = new HashSet<>();
81
82 for (int i = 0; i < servers.size(); i++) {
83 Server server = servers.get(i);
84
85 validateStringNotEmpty(problems, "servers.server[" + i + "].id", server.getId(), null);
86
87 if (!serverIds.add(server.getId())) {
88 addViolation(
89 problems,
90 Severity.WARNING,
91 "servers.server.id",
92 null,
93 "must be unique but found duplicate server with id " + server.getId());
94 }
95 }
96 }
97
98 List<Mirror> mirrors = settings.getMirrors();
99
100 if (mirrors != null) {
101 for (Mirror mirror : mirrors) {
102 validateStringNotEmpty(problems, "mirrors.mirror.id", mirror.getId(), mirror.getUrl());
103
104 validateBannedCharacters(
105 problems, "mirrors.mirror.id", Severity.WARNING, mirror.getId(), null, ILLEGAL_REPO_ID_CHARS);
106
107 if ("local".equals(mirror.getId())) {
108 addViolation(
109 problems,
110 Severity.WARNING,
111 "mirrors.mirror.id",
112 null,
113 "must not be 'local'"
114 + ", this identifier is reserved for the local repository"
115 + ", using it for other repositories will corrupt your repository metadata.");
116 }
117
118 validateStringNotEmpty(problems, "mirrors.mirror.url", mirror.getUrl(), mirror.getId());
119
120 validateStringNotEmpty(problems, "mirrors.mirror.mirrorOf", mirror.getMirrorOf(), mirror.getId());
121 }
122 }
123
124 List<Profile> profiles = settings.getProfiles();
125
126 if (profiles != null) {
127 Set<String> profileIds = new HashSet<>();
128
129 for (Profile profile : profiles) {
130 if (!profileIds.add(profile.getId())) {
131 addViolation(
132 problems,
133 Severity.WARNING,
134 "profiles.profile.id",
135 null,
136 "must be unique but found duplicate profile with id " + profile.getId());
137 }
138
139 String prefix = "profiles.profile[" + profile.getId() + "].";
140
141 validateRepositories(problems, profile.getRepositories(), prefix + "repositories.repository");
142 validateRepositories(
143 problems, profile.getPluginRepositories(), prefix + "pluginRepositories.pluginRepository");
144 }
145 }
146
147 List<Proxy> proxies = settings.getProxies();
148
149 if (proxies != null) {
150 Set<String> proxyIds = new HashSet<>();
151
152 for (Proxy proxy : proxies) {
153 if (!proxyIds.add(proxy.getId())) {
154 addViolation(
155 problems,
156 Severity.WARNING,
157 "proxies.proxy.id",
158 null,
159 "must be unique but found duplicate proxy with id " + proxy.getId());
160 }
161 validateStringNotEmpty(problems, "proxies.proxy.host", proxy.getHost(), proxy.getId());
162 }
163 }
164 }
165
166 private void validateRepositories(SettingsProblemCollector problems, List<Repository> repositories, String prefix) {
167 Set<String> repoIds = new HashSet<>();
168
169 for (Repository repository : repositories) {
170 validateStringNotEmpty(problems, prefix + ".id", repository.getId(), repository.getUrl());
171
172 validateBannedCharacters(
173 problems, prefix + ".id", Severity.WARNING, repository.getId(), null, ILLEGAL_REPO_ID_CHARS);
174
175 if ("local".equals(repository.getId())) {
176 addViolation(
177 problems,
178 Severity.WARNING,
179 prefix + ".id",
180 null,
181 "must not be 'local'"
182 + ", this identifier is reserved for the local repository"
183 + ", using it for other repositories will corrupt your repository metadata.");
184 }
185
186 if (!repoIds.add(repository.getId())) {
187 addViolation(
188 problems,
189 Severity.WARNING,
190 prefix + ".id",
191 null,
192 "must be unique but found duplicate repository with id " + repository.getId());
193 }
194
195 validateStringNotEmpty(problems, prefix + ".url", repository.getUrl(), repository.getId());
196
197 if ("legacy".equals(repository.getLayout())) {
198 addViolation(
199 problems,
200 Severity.WARNING,
201 prefix + ".layout",
202 repository.getId(),
203 "uses the unsupported value 'legacy', artifact resolution might fail.");
204 }
205 }
206 }
207
208
209
210
211
212
213
214
215
216
217
218
219
220 private static boolean validateStringNotEmpty(
221 SettingsProblemCollector problems, String fieldName, String string, String sourceHint) {
222 if (!validateNotNull(problems, fieldName, string, sourceHint)) {
223 return false;
224 }
225
226 if (string.length() > 0) {
227 return true;
228 }
229
230 addViolation(problems, Severity.ERROR, fieldName, sourceHint, "is missing");
231
232 return false;
233 }
234
235
236
237
238
239
240
241
242 private static boolean validateNotNull(
243 SettingsProblemCollector problems, String fieldName, Object object, String sourceHint) {
244 if (object != null) {
245 return true;
246 }
247
248 addViolation(problems, Severity.ERROR, fieldName, sourceHint, "is missing");
249
250 return false;
251 }
252
253 private static boolean validateBannedCharacters(
254 SettingsProblemCollector problems,
255 String fieldName,
256 Severity severity,
257 String string,
258 String sourceHint,
259 String banned) {
260 if (string != null) {
261 for (int i = string.length() - 1; i >= 0; i--) {
262 if (banned.indexOf(string.charAt(i)) >= 0) {
263 addViolation(
264 problems,
265 severity,
266 fieldName,
267 sourceHint,
268 "must not contain any of these characters " + banned + " but found " + string.charAt(i));
269 return false;
270 }
271 }
272 }
273
274 return true;
275 }
276
277 private static void addViolation(
278 SettingsProblemCollector problems, Severity severity, String fieldName, String sourceHint, String message) {
279 StringBuilder buffer = new StringBuilder(256);
280 buffer.append('\'').append(fieldName).append('\'');
281
282 if (sourceHint != null) {
283 buffer.append(" for ").append(sourceHint);
284 }
285
286 buffer.append(' ').append(message);
287
288 problems.add(severity, buffer.toString(), -1, -1, null);
289 }
290 }