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